From 20fc994cacf166cd2f65f3ceeeceb0e23ee0eb61 Mon Sep 17 00:00:00 2001 From: junjie Date: Tue, 10 Aug 2021 11:00:38 +0800 Subject: [PATCH 01/30] =?UTF-8?q?feat:=20=E7=9F=A9=E5=BD=A2=E6=A0=91?= =?UTF-8?q?=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/lang/en.js | 5 ++++- frontend/src/lang/tw.js | 5 ++++- frontend/src/lang/zh.js | 5 ++++- frontend/src/views/chart/chart/chart.js | 4 +++- frontend/src/views/chart/chart/treemap/treemap.js | 9 +++++---- .../chart/components/shape-attr/SizeSelector.vue | 11 +++++++++++ frontend/src/views/chart/view/ChartEdit.vue | 2 +- 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 8cf635faf5..2e66018e6b 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -837,7 +837,10 @@ export default { drill: 'Drill', drag_block_treemap_label: 'Color Label', drag_block_treemap_size: 'Color Size', - bubble_symbol: 'Shape' + bubble_symbol: 'Shape', + gap_width: 'Gap Width', + width: 'Width', + height: 'Height' }, dataset: { sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index b0a38fd1b0..12c3625fee 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -837,7 +837,10 @@ export default { drill: '鉆取', drag_block_treemap_label: '色塊標簽', drag_block_treemap_size: '色塊大小', - bubble_symbol: '圖形' + bubble_symbol: '圖形', + gap_width: '間隔', + width: '寬度', + height: '高度' }, dataset: { sheet_warn: '有多個sheet頁面,默認抽取第一個', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index ba630a4bd8..503a0c9c6c 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -837,7 +837,10 @@ export default { drill: '钻取', drag_block_treemap_label: '色块标签', drag_block_treemap_size: '色块大小', - bubble_symbol: '图形' + bubble_symbol: '图形', + gap_width: '间隔', + width: '宽度', + height: '高度' }, dataset: { sheet_warn: '有多个 Sheet 页,默认抽取第一个', diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index 90e7c5134f..cdce29e33d 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -39,7 +39,9 @@ export const DEFAULT_SIZE = { dimensionShow: true, quotaShow: true, scatterSymbol: 'circle', - scatterSymbolSize: 20 + scatterSymbolSize: 20, + treemapWidth: 80, + treemapHeight: 80 } export const DEFAULT_LABEL = { show: false, diff --git a/frontend/src/views/chart/chart/treemap/treemap.js b/frontend/src/views/chart/chart/treemap/treemap.js index 5ecca3ca82..de7c07eb49 100644 --- a/frontend/src/views/chart/chart/treemap/treemap.js +++ b/frontend/src/views/chart/chart/treemap/treemap.js @@ -24,12 +24,13 @@ export function baseTreemapOption(chart_option, chart) { // chart_option.series[0].name = chart.data.series[0].name // size if (customAttr.size) { - // chart_option.series[0].radius = [customAttr.size.pieInnerRadius + '%', customAttr.size.pieOuterRadius + '%'] + chart_option.series[0].width = (customAttr.size.treemapWidth ? customAttr.size.treemapWidth : 80) + '%' + chart_option.series[0].height = (customAttr.size.treemapHeight ? customAttr.size.treemapHeight : 80) + '%' } // label - if (customAttr.label) { - // chart_option.series[0].label = customAttr.label - } + // if (customAttr.label) { + // chart_option.series[0].label = customAttr.label + // } const valueArr = chart.data.series[0].data for (let i = 0; i < valueArr.length; i++) { // const y = { diff --git a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue index 906a1eb79f..0295369719 100644 --- a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue +++ b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue @@ -151,6 +151,15 @@ + + + + + + + + + @@ -353,6 +362,8 @@ export default { } if (customAttr.size) { this.sizeForm = customAttr.size + this.sizeForm.treemapWidth = this.sizeForm.treemapWidth ? this.sizeForm.treemapWidth : 80 + this.sizeForm.treemapHeight = this.sizeForm.treemapHeight ? this.sizeForm.treemapHeight : 80 } } }, diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index 6d48edba2e..d4d89818d5 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -427,7 +427,7 @@ - + From 3ea7da10cab0bdf676ff968e1c8b56964d0a6c6e Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Tue, 10 Aug 2021 14:24:13 +0800 Subject: [PATCH 02/30] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8ak=EF=BC=8Csk?= =?UTF-8?q?=E8=AE=BF=E9=97=AEapi=E6=8E=A5=E5=8F=A3=E4=BB=A5=E5=8F=8Aswagge?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/dataease/auth/config/F2CRealm.java | 54 ++++++++++-- .../io/dataease/auth/entity/ASKToken.java | 25 ++++++ .../io/dataease/auth/filter/JWTFilter.java | 19 +++- .../dataease/auth/handler/ApiKeyHandler.java | 88 +++++++++++++++++++ .../io/dataease/commons/utils/CodingUtil.java | 12 +++ .../dataease/config/Knife4jConfiguration.java | 19 +++- .../src/main/resources/application.properties | 2 +- 7 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 backend/src/main/java/io/dataease/auth/entity/ASKToken.java create mode 100644 backend/src/main/java/io/dataease/auth/handler/ApiKeyHandler.java diff --git a/backend/src/main/java/io/dataease/auth/config/F2CRealm.java b/backend/src/main/java/io/dataease/auth/config/F2CRealm.java index 1f0ee7e60d..c7a46650b6 100644 --- a/backend/src/main/java/io/dataease/auth/config/F2CRealm.java +++ b/backend/src/main/java/io/dataease/auth/config/F2CRealm.java @@ -2,18 +2,17 @@ package io.dataease.auth.config; import io.dataease.auth.api.dto.CurrentRoleDto; import io.dataease.auth.api.dto.CurrentUserDto; +import io.dataease.auth.entity.ASKToken; import io.dataease.auth.entity.JWTToken; import io.dataease.auth.entity.SysUserEntity; import io.dataease.auth.entity.TokenInfo; +import io.dataease.auth.handler.ApiKeyHandler; import io.dataease.auth.service.AuthUserService; import io.dataease.auth.util.JWTUtils; import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.LogUtil; import io.dataease.listener.util.CacheUtils; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; @@ -37,7 +36,7 @@ public class F2CRealm extends AuthorizingRealm { @Override public boolean supports(AuthenticationToken token) { - return token instanceof JWTToken; + return token instanceof JWTToken || token instanceof ASKToken; } //验证资源权限 @@ -56,12 +55,27 @@ public class F2CRealm extends AuthorizingRealm { @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { + + if (auth instanceof ASKToken) { + + Object accessKey = auth.getPrincipal(); + Object signature = auth.getCredentials(); + Long userId = ApiKeyHandler.getUser(accessKey.toString(), signature.toString()); + + SysUserEntity userEntity = userWithId(userId); + CurrentUserDto currentUserDto = queryCacheUserDto(userEntity); + return new SimpleAuthenticationInfo(currentUserDto, signature, "f2cReam"); + } + + + try { CacheUtils.get("lic_info", "lic"); }catch (Exception e) { LogUtil.error(e); throw new AuthenticationException("lic error"); } + TokenInfo tokenInfo = null; String token = null; try { @@ -78,13 +92,14 @@ public class F2CRealm extends AuthorizingRealm { throw new AuthenticationException("token invalid"); } // 使用缓存 - SysUserEntity user = authUserService.getUserById(userId); + /*SysUserEntity user = authUserService.getUserById(userId); if (user == null) { throw new AuthenticationException("User didn't existed!"); } if (user.getEnabled()==0) { throw new AuthenticationException("User is valid!"); - } + }*/ + SysUserEntity user = userWithId(userId); String pass = null; try { pass = user.getPassword(); @@ -94,6 +109,29 @@ public class F2CRealm extends AuthorizingRealm { if (! JWTUtils.verify(token, tokenInfo, pass)) { throw new AuthenticationException("Username or password error"); } + /*// 使用缓存 + List currentRoleDtos = authUserService.roleInfos(user.getUserId()); + // 使用缓存 + List permissions = authUserService.permissions(user.getUserId()); + CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user); + currentUserDto.setRoles(currentRoleDtos); + currentUserDto.setPermissions(permissions);*/ + CurrentUserDto currentUserDto = queryCacheUserDto(user); + return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam"); + } + + public SysUserEntity userWithId(Long userId) { + SysUserEntity user = authUserService.getUserById(userId); + if (user == null) { + throw new AuthenticationException("User didn't existed!"); + } + if (user.getEnabled()==0) { + throw new AuthenticationException("User is valid!"); + } + return user; + } + + public CurrentUserDto queryCacheUserDto(SysUserEntity user) { // 使用缓存 List currentRoleDtos = authUserService.roleInfos(user.getUserId()); // 使用缓存 @@ -101,6 +139,6 @@ public class F2CRealm extends AuthorizingRealm { CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user); currentUserDto.setRoles(currentRoleDtos); currentUserDto.setPermissions(permissions); - return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam"); + return currentUserDto; } } diff --git a/backend/src/main/java/io/dataease/auth/entity/ASKToken.java b/backend/src/main/java/io/dataease/auth/entity/ASKToken.java new file mode 100644 index 0000000000..4112fe197e --- /dev/null +++ b/backend/src/main/java/io/dataease/auth/entity/ASKToken.java @@ -0,0 +1,25 @@ +package io.dataease.auth.entity; + +import org.apache.shiro.authc.AuthenticationToken; + +public class ASKToken implements AuthenticationToken { + + private String accessKey; + + private String signature; + + public ASKToken(String accessKey, String signature) { + this.accessKey = accessKey; + this.signature = signature; + } + + @Override + public Object getPrincipal() { + return accessKey; + } + + @Override + public Object getCredentials() { + return signature; + } +} diff --git a/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java b/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java index ba23292a7a..3077a338a5 100644 --- a/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java +++ b/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java @@ -1,8 +1,10 @@ package io.dataease.auth.filter; +import io.dataease.auth.entity.ASKToken; import io.dataease.auth.entity.JWTToken; import io.dataease.auth.entity.SysUserEntity; import io.dataease.auth.entity.TokenInfo; +import io.dataease.auth.handler.ApiKeyHandler; import io.dataease.auth.service.AuthUserService; import io.dataease.auth.util.JWTUtils; import io.dataease.commons.utils.CommonBeanFactory; @@ -48,6 +50,18 @@ public class JWTFilter extends BasicHttpAuthenticationFilter { @Override protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest) request; + + + if (ApiKeyHandler.isApiKeyCall(httpServletRequest)) { + // Long userId = ApiKeyHandler.getUser(httpServletRequest); + + ASKToken askToken = ApiKeyHandler.buildToken(httpServletRequest); + + // UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userId.toString(), ApiKeyHandler.random); + getSubject(request, response).login(askToken); + return true; + } + String authorization = httpServletRequest.getHeader("Authorization"); if (StringUtils.startsWith(authorization, "Basic")) { return false; @@ -72,7 +86,10 @@ public class JWTFilter extends BasicHttpAuthenticationFilter { */ @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { - if (isLoginAttempt(request, response)) { + // 先判断是不是api调用 + HttpServletRequest hRequest = (HttpServletRequest) request; + + if (isLoginAttempt(request, response) || ApiKeyHandler.isApiKeyCall(hRequest)) { try { boolean loginSuccess = executeLogin(request, response); return loginSuccess; diff --git a/backend/src/main/java/io/dataease/auth/handler/ApiKeyHandler.java b/backend/src/main/java/io/dataease/auth/handler/ApiKeyHandler.java new file mode 100644 index 0000000000..bd0a0e35a4 --- /dev/null +++ b/backend/src/main/java/io/dataease/auth/handler/ApiKeyHandler.java @@ -0,0 +1,88 @@ +package io.dataease.auth.handler; + +import io.dataease.auth.entity.ASKToken; +import io.dataease.commons.utils.CodingUtil; +import io.dataease.plugins.config.SpringContextUtil; +import io.dataease.plugins.xpack.ukey.dto.request.XpackUkeyDto; +import io.dataease.plugins.xpack.ukey.service.UkeyXpackService; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.UUID; + +public class ApiKeyHandler { + + public static final String API_ACCESS_KEY = "accessKey"; + + public static final String API_SIGNATURE = "signature"; + + + public static String random = UUID.randomUUID().toString() + UUID.randomUUID().toString(); + + public static Long getUser(HttpServletRequest request) { + if (request == null) { + return null; + } + return getUser(request.getHeader(API_ACCESS_KEY), request.getHeader(API_SIGNATURE)); + } + + public static ASKToken buildToken(HttpServletRequest request) { + if (request == null) { + return null; + } + String accessKey = request.getHeader(API_ACCESS_KEY); + String signature = request.getHeader(API_SIGNATURE); + ASKToken askToken = new ASKToken(accessKey, signature); + return askToken; + } + + public static Boolean isApiKeyCall(HttpServletRequest request) { + if (request == null) { + return false; + } + if (StringUtils.isBlank(request.getHeader(API_ACCESS_KEY)) || StringUtils.isBlank(request.getHeader(API_SIGNATURE))) { + return false; + } + return true; + } + + public static XpackUkeyDto ukey(String accessKey) { + UkeyXpackService ukeyXpackService = SpringContextUtil.getBean(UkeyXpackService.class); + XpackUkeyDto userKey = ukeyXpackService.getUserKey(accessKey); + return userKey; + } + + public static Long getUser(String accessKey, String signature) { + if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(signature)) { + return null; + } + XpackUkeyDto userKey = ukey(accessKey); + if (userKey == null) { + throw new RuntimeException("invalid accessKey"); + } + String signatureDecrypt; + try { + signatureDecrypt = CodingUtil.aesDecrypt(signature, userKey.getSecretKey(), accessKey); + } catch (Throwable t) { + throw new RuntimeException("invalid signature"); + } + String[] signatureArray = StringUtils.split(StringUtils.trimToNull(signatureDecrypt), "|"); + if (signatureArray.length < 2) { + throw new RuntimeException("invalid signature"); + } + if (!StringUtils.equals(accessKey, signatureArray[0])) { + throw new RuntimeException("invalid signature"); + } + long signatureTime = 0l; + try { + signatureTime = Long.valueOf(signatureArray[signatureArray.length - 1]).longValue(); + } catch (Exception e) { + throw new RuntimeException(e); + } + if (Math.abs(System.currentTimeMillis() - signatureTime) > 1800000) { + //签名30分钟超时 + throw new RuntimeException("expired signature"); + } + return userKey.getUserId(); + } +} diff --git a/backend/src/main/java/io/dataease/commons/utils/CodingUtil.java b/backend/src/main/java/io/dataease/commons/utils/CodingUtil.java index d377fafcfd..4bdea0e469 100644 --- a/backend/src/main/java/io/dataease/commons/utils/CodingUtil.java +++ b/backend/src/main/java/io/dataease/commons/utils/CodingUtil.java @@ -7,6 +7,7 @@ import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.MessageDigest; +import java.util.UUID; /** * 加密解密工具 @@ -153,6 +154,17 @@ public class CodingUtil { } } + /*public static String getSignature(String accessKey, String secretKey) throws Exception { + return aesEncrypt(accessKey + "|" + UUID.randomUUID().toString() + "|" + System.currentTimeMillis(), secretKey, accessKey); + } + + public static void main(String[] args) throws Exception{ + String accessKey = "gnPFmtAsdLhUEWPA"; + String secretKey = "TfK5FGUle0KRfJJJ"; + String signature = getSignature(accessKey, secretKey); + System.out.println(signature); + }*/ + public static String secretKey() { try { KeyGenerator keyGen = KeyGenerator.getInstance("AES"); diff --git a/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java b/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java index c8174f6e31..7a58bb54ee 100644 --- a/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java +++ b/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java @@ -77,7 +77,9 @@ public class Knife4jConfiguration { private Docket defaultApi(String groupName, String packageName) { List securitySchemes=new ArrayList<>(); - securitySchemes.add(apiKey()); + securitySchemes.add(accessKey()); + securitySchemes.add(signature()); + List securityContexts = new ArrayList<>(); securityContexts.add(securityContext()); @@ -100,8 +102,12 @@ public class Knife4jConfiguration { .build(); } - private ApiKey apiKey() { - return new ApiKey("Authorization", "Authorization", "header"); + private ApiKey accessKey() { + return new ApiKey("accessKey", "accessKey", "header"); + } + + private ApiKey signature() { + return new ApiKey("signature", "signature", "header"); } @@ -109,7 +115,12 @@ public class Knife4jConfiguration { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; - return CollectionUtil.newArrayList(new SecurityReference("Authorization", authorizationScopes)); + + List results = new ArrayList<>(); + results.add(new SecurityReference("accessKey", authorizationScopes)); + results.add(new SecurityReference("signature", authorizationScopes)); + + return results; } } diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 14368c84d1..d4f4111a23 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -28,7 +28,7 @@ knife4j.enable=true knife4j.setting.enableFooter=false knife4j.setting.enableFooterCustom=false knife4j.setting.footerCustomContent=fit2cloud 1.0-b9 -knife4j.setting.enableSwaggerModels=false +#knife4j.setting.enableSwaggerModels=false knife4j.setting.enableDocumentManage=false knife4j.setting.enableSearch=false knife4j.setting.enableOpenApi=false From b3c7aa5d167fc44240ce65181aa7eccfbd331615 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Tue, 10 Aug 2021 15:50:00 +0800 Subject: [PATCH 03/30] =?UTF-8?q?refactor:=E4=BB=AA=E8=A1=A8=E7=89=88?= =?UTF-8?q?=E5=A4=9A=E7=BB=84=E4=BB=B6=E9=97=B4=E8=81=94=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/ext/ExtPanelViewLinkageMapper.java | 4 ++ .../mapper/ext/ExtPanelViewLinkageMapper.xml | 20 +++++++ .../panel/PanelViewLinkageController.java | 6 +++ .../request/chart/ChartExtRequest.java | 3 ++ .../java/io/dataease/dto/LinkageInfoDTO.java | 31 +++++++++++ .../service/chart/ChartViewService.java | 21 +++++++- .../panel/PanelViewLinkageService.java | 16 ++---- frontend/src/api/panel/linkage.js | 6 +++ .../components/Editor/ComponentWrapper.vue | 1 - .../canvas/components/Editor/Preview.vue | 1 - .../canvas/custom-component/UserView.vue | 15 ++++++ frontend/src/components/canvas/store/copy.js | 1 - frontend/src/store/index.js | 53 ++++++++++++++++++- frontend/src/utils/conditionUtil.js | 6 +++ .../views/chart/components/ChartComponent.vue | 12 +++++ frontend/src/views/panel/edit/index.vue | 9 ++++ .../src/views/panel/list/EditPanel/index.vue | 1 - frontend/src/views/panel/list/PanelList.vue | 13 ++++- 18 files changed, 200 insertions(+), 19 deletions(-) create mode 100644 backend/src/main/java/io/dataease/dto/LinkageInfoDTO.java diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.java index 82cea4163a..96ac3fe6a6 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.java @@ -1,15 +1,19 @@ package io.dataease.base.mapper.ext; import io.dataease.base.domain.DatasetTableField; +import io.dataease.dto.LinkageInfoDTO; import io.dataease.dto.PanelViewLinkageDTO; import org.apache.ibatis.annotations.Param; import java.util.List; +import java.util.Map; public interface ExtPanelViewLinkageMapper { List getViewLinkageGather(@Param("panelId") String panelId,@Param("sourceViewId") String sourceViewId,@Param("targetViewIds") List targetViewIds); + List getPanelAllLinkageInfo(@Param("panelId") String panelId); + List queryTableField(@Param("table_id") String tableId); void deleteViewLinkage(@Param("panelId") String panelId,@Param("sourceViewId") String sourceViewId); diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.xml index f81e6c76ea..fb47e5fe23 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelViewLinkageMapper.xml @@ -24,6 +24,14 @@ + + + + + + + + + SELECT + distinct + CONCAT( panel_view_linkage.source_view_id, '#', panel_view_linkage_field.source_field ) AS 'sourceInfo', + CONCAT( panel_view_linkage.target_view_id, '#', panel_view_linkage_field.target_field ) AS 'targetInfo' + FROM + panel_view_linkage + LEFT JOIN panel_view_linkage_field ON panel_view_linkage.id = panel_view_linkage_field.linkage_id + WHERE + panel_view_linkage.panel_id = #{panelId} + diff --git a/backend/src/main/java/io/dataease/controller/panel/PanelViewLinkageController.java b/backend/src/main/java/io/dataease/controller/panel/PanelViewLinkageController.java index b74b33a97f..c994a835f7 100644 --- a/backend/src/main/java/io/dataease/controller/panel/PanelViewLinkageController.java +++ b/backend/src/main/java/io/dataease/controller/panel/PanelViewLinkageController.java @@ -9,6 +9,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.util.List; import java.util.Map; /** @@ -39,5 +40,10 @@ public class PanelViewLinkageController { } + @ApiOperation("获取当前仪表板所有联动信息") + @GetMapping("/getPanelAllLinkageInfo/{panelId}") + public Map> getPanelAllLinkageInfo(@PathVariable String panelId){ + return panelViewLinkageService.getPanelAllLinkageInfo(panelId); + } } diff --git a/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java index 3806316bd6..35e310d379 100644 --- a/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java +++ b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java @@ -13,4 +13,7 @@ import java.util.List; @Setter public class ChartExtRequest { private List filter; + + //联动过滤条件 + private List linkageFilters; } diff --git a/backend/src/main/java/io/dataease/dto/LinkageInfoDTO.java b/backend/src/main/java/io/dataease/dto/LinkageInfoDTO.java new file mode 100644 index 0000000000..d1f915b042 --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/LinkageInfoDTO.java @@ -0,0 +1,31 @@ +package io.dataease.dto; + +import java.util.List; + +/** + * Author: wangjiahao + * Date: 8/10/21 + * Description: + */ +public class LinkageInfoDTO { + + private String sourceInfo; + + private List targetInfoList; + + public String getSourceInfo() { + return sourceInfo; + } + + public void setSourceInfo(String sourceInfo) { + this.sourceInfo = sourceInfo; + } + + public List getTargetInfoList() { + return targetInfoList; + } + + public void setTargetInfoList(List targetInfoList) { + this.targetInfoList = targetInfoList; + } +} diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 68fa644ab0..709dce5e34 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -225,6 +225,8 @@ public class ChartViewService { // 过滤来自仪表板的条件 List extFilterList = new ArrayList<>(); + + //组件过滤条件 if (ObjectUtils.isNotEmpty(requestList.getFilter())) { for (ChartExtFilterRequest request : requestList.getFilter()) { DatasetTableField datasetTableField = dataSetTableFieldsService.get(request.getFieldId()); @@ -241,6 +243,23 @@ public class ChartViewService { } } + //联动过滤条件联动条件全部加上 + if (ObjectUtils.isNotEmpty(requestList.getLinkageFilters())) { + for (ChartExtFilterRequest request : requestList.getLinkageFilters()) { + DatasetTableField datasetTableField = dataSetTableFieldsService.get(request.getFieldId()); + request.setDatasetTableField(datasetTableField); + if (StringUtils.equalsIgnoreCase(datasetTableField.getTableId(), view.getTableId())) { + if (CollectionUtils.isNotEmpty(request.getViewIds())) { + if (request.getViewIds().contains(view.getId())) { + extFilterList.add(request); + } + } else { + extFilterList.add(request); + } + } + } + } + // 获取数据集,需校验权限 DatasetTable table = dataSetTableService.get(view.getTableId()); if (ObjectUtils.isEmpty(table)) { @@ -339,7 +358,7 @@ public class ChartViewService { data = (List) cache; }*/ // 仪表板有参数不实用缓存 - if (CollectionUtils.isNotEmpty(requestList.getFilter())) { + if (CollectionUtils.isNotEmpty(requestList.getFilter()) || CollectionUtils.isNotEmpty(requestList.getLinkageFilters())) { data = datasourceProvider.getData(datasourceRequest); } else { try { diff --git a/backend/src/main/java/io/dataease/service/panel/PanelViewLinkageService.java b/backend/src/main/java/io/dataease/service/panel/PanelViewLinkageService.java index 792ada85de..20447092a0 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelViewLinkageService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelViewLinkageService.java @@ -8,6 +8,7 @@ import io.dataease.base.mapper.PanelViewLinkageMapper; import io.dataease.base.mapper.ext.ExtPanelViewLinkageMapper; import io.dataease.commons.utils.AuthUtils; import io.dataease.controller.request.panel.PanelLinkageRequest; +import io.dataease.dto.LinkageInfoDTO; import io.dataease.dto.PanelViewLinkageDTO; import io.dataease.dto.PanelViewLinkageFieldDTO; import org.apache.commons.collections4.CollectionUtils; @@ -89,19 +90,12 @@ public class PanelViewLinkageService { }); } - - - - } + } - - - - - - - + public Map> getPanelAllLinkageInfo(String panelId) { + List info = extPanelViewLinkageMapper.getPanelAllLinkageInfo(panelId); + return Optional.ofNullable(info).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(LinkageInfoDTO::getSourceInfo,LinkageInfoDTO::getTargetInfoList)); } } diff --git a/frontend/src/api/panel/linkage.js b/frontend/src/api/panel/linkage.js index 4a0f0ecc4a..6b0bd72fa6 100644 --- a/frontend/src/api/panel/linkage.js +++ b/frontend/src/api/panel/linkage.js @@ -18,3 +18,9 @@ export function saveLinkage(requestInfo) { }) } +export function getPanelAllLinkageInfo(panelId) { + return request({ + url: '/linkage/getPanelAllLinkageInfo/' + panelId, + method: 'get' + }) +} diff --git a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue index 4b6da3a6ea..88216e9e1a 100644 --- a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue +++ b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue @@ -102,7 +102,6 @@ export default { }) }, elementMouseDown(e) { - debugger // private 设置当前组件数据及状态 this.$store.commit('setClickComponentStatus', true) if (this.config.component !== 'v-text' && this.config.component !== 'rect-shape' && this.config.component !== 'de-input-search' && this.config.component !== 'de-number-range') { diff --git a/frontend/src/components/canvas/components/Editor/Preview.vue b/frontend/src/components/canvas/components/Editor/Preview.vue index 1fbc589005..9eda38c7c8 100644 --- a/frontend/src/components/canvas/components/Editor/Preview.vue +++ b/frontend/src/components/canvas/components/Editor/Preview.vue @@ -209,7 +209,6 @@ export default { this.$refs['userViewDialog'].exportExcel() }, deselectCurComponent(e) { - debugger if (!this.isClickComponent) { this.$store.commit('setCurComponent', { component: null, index: null }) } diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index 00cf67d92c..1d61d5893e 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -84,6 +84,7 @@ export default { filter() { const filter = {} filter.filter = this.element.filters + filter.linkageFilters = this.element.linkageFilters return filter }, filters() { @@ -91,6 +92,13 @@ export default { if (!this.element.filters) return [] return JSON.parse(JSON.stringify(this.element.filters)) }, + + linkageFilters() { + // 必要 勿删勿该 watch数组,哪怕发生变化 oldValue等于newValue ,深拷贝解决 + if (!this.element.linkageFilters) return [] + console.log('linkageFilters:' + JSON.stringify(this.element.linkageFilters)) + return JSON.parse(JSON.stringify(this.element.linkageFilters)) + }, ...mapState([ 'canvasStyleData' ]) @@ -101,6 +109,13 @@ export default { // this.getData(this.element.propValue.viewId) isChange(val1, val2) && this.getData(this.element.propValue.viewId) }, + linkageFilters: { + handler(newVal, oldVal) { + debugger + isChange(newVal, oldVal) && this.getData(this.element.propValue.viewId) + }, + deep: true + }, // deep监听panel 如果改变 提交到 store canvasStyleData: { handler(newVal, oldVla) { diff --git a/frontend/src/components/canvas/store/copy.js b/frontend/src/components/canvas/store/copy.js index ef4eb98351..e7daeb98cd 100644 --- a/frontend/src/components/canvas/store/copy.js +++ b/frontend/src/components/canvas/store/copy.js @@ -41,7 +41,6 @@ export default { data.id = generateID() // 如果是用户视图 测先进行底层复制 - debugger if (data.type === 'view') { chartCopy(data.propValue.viewId).then(res => { const newView = deepCopy(data) diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 3f299683e8..7114ce2c23 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -21,7 +21,9 @@ import event from '@/components/canvas/store/event' import layer from '@/components/canvas/store/layer' import snapshot from '@/components/canvas/store/snapshot' import lock from '@/components/canvas/store/lock' -import { valueValid, formatCondition } from '@/utils/conditionUtil' +import { valueValid, formatCondition, formatLinkageCondition } from '@/utils/conditionUtil' +import { Condition } from '@/components/widget/bean/Condition' + import { DEFAULT_COMMON_CANVAS_STYLE_STRING } from '@/views/panel/panel' @@ -54,7 +56,9 @@ const data = { // 当前设置联动的组件 curLinkageView: null, // 和当前组件联动的目标组件 - targetLinkageInfo: [] + targetLinkageInfo: [], + // 当前仪表板联动 下钻 上卷等信息 + nowPanelTrackInfo: {} }, mutations: { ...animation.mutations, @@ -154,6 +158,48 @@ const data = { state.componentData[index] = element } }, + + // 添加联动 下钻 等过滤组件 + addViewTrackFilter(state, data) { + console.log('联动信息', JSON.stringify(data)) + debugger + const viewId = data.viewId + const trackInfo = state.nowPanelTrackInfo + for (let index = 0; index < state.componentData.length; index++) { + const element = state.componentData[index] + if (!element.type || element.type !== 'view') continue + const currentFilters = element.linkageFilters || [] // 当前联动filter + + data.dimensionList.forEach(dimension => { + const sourceInfo = viewId + '#' + dimension.id + // 获取所有目标联动信息 + const targetInfoList = trackInfo[sourceInfo] || [] + targetInfoList.forEach(targetInfo => { + const targetInfoArray = targetInfo.split('#') + const targetViewId = targetInfoArray[0] // 目标视图 + if (element.propValue.viewId === targetViewId) { // 如果目标视图 和 当前循环组件id相等 则进行条件增减 + const targetFieldId = targetInfoArray[1] // 目标视图列ID + const condition = new Condition('', targetFieldId, 'eq', [dimension.value], [targetViewId]) + + let j = currentFilters.length + while (j--) { + const filter = currentFilters[j] + // 兼容性准备 viewIds 只会存放一个值 + if (targetFieldId === filter.fieldId && filter.viewIds.includes(targetViewId)) { + currentFilters.splice(j, 1) + } + } + // 不存在该条件 且 条件有效 直接保存该条件 + // !filterExist && vValid && currentFilters.push(condition) + currentFilters.push(condition) + } + }) + }) + + element.linkageFilters = currentFilters + state.componentData[index] = element + } + }, setComponentWithId(state, component) { for (let index = 0; index < state.componentData.length; index++) { const element = state.componentData[index] @@ -189,6 +235,9 @@ const data = { state.linkageSettingStatus = false state.curLinkageView = null state.targetLinkageInfo = [] + }, + setNowPanelTrackInfo(state, trackInfo) { + state.nowPanelTrackInfo = trackInfo } }, modules: { diff --git a/frontend/src/utils/conditionUtil.js b/frontend/src/utils/conditionUtil.js index 0e010b8665..7cfee37f9f 100644 --- a/frontend/src/utils/conditionUtil.js +++ b/frontend/src/utils/conditionUtil.js @@ -30,3 +30,9 @@ export const formatCondition = obj => { const condition = new Condition(component.id, fieldId, operator, value, viewIds) return condition } + +export const formatLinkageCondition = obj => { + const { viewIds, fieldId, value, operator } = obj + const condition = new Condition(null, fieldId, operator, value, viewIds) + return condition +} diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 1cea6ea399..4c2573fcb3 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -60,6 +60,8 @@ export default { }, methods: { preDraw() { + const viewId = this.chart.id + const _store = this.$store // 基于准备好的dom,初始化echarts实例 // 渲染echart等待dom加载完毕,渲染之前先尝试销毁具有相同id的echart 放置多次切换仪表板有重复id情况 new Promise((resolve) => { resolve() }).then(() => { @@ -69,6 +71,16 @@ export default { this.myChart = this.$echarts.init(document.getElementById(this.chartId)) } this.drawEcharts() + this.myChart.on('click', function(param) { + debugger + console.log(JSON.stringify(param.data)) + const trackFilter = { + viewId: viewId, + dimensionList: param.data.dimensionList, + quotaList: param.data.quotaList + } + _store.commit('addViewTrackFilter', trackFilter) + }) }) }, drawEcharts() { diff --git a/frontend/src/views/panel/edit/index.vue b/frontend/src/views/panel/edit/index.vue index 070886ad4d..5149e7ab18 100644 --- a/frontend/src/views/panel/edit/index.vue +++ b/frontend/src/views/panel/edit/index.vue @@ -192,6 +192,7 @@ import { mapState } from 'vuex' import { uuid } from 'vue-uuid' import Toolbar from '@/components/canvas/components/Toolbar' import { findOne } from '@/api/panel/panel' +import { getPanelAllLinkageInfo } from '@/api/panel/linkage' import PreviewFullScreen from '@/components/canvas/components/Editor/PreviewFullScreen' import Preview from '@/components/canvas/components/Editor/Preview' import AttrList from '@/components/canvas/components/AttrList' @@ -363,6 +364,7 @@ export default { const componentDatas = JSON.parse(componentDataTemp) componentDatas.forEach(item => { item.filters = (item.filters || []) + item.linkageFilters = (item.linkageFilters || []) }) this.$store.commit('setComponentData', this.resetID(componentDatas)) // this.$store.commit('setComponentData', this.resetID(JSON.parse(componentDataTemp))) @@ -375,12 +377,17 @@ export default { const componentDatas = JSON.parse(response.data.panelData) componentDatas.forEach(item => { item.filters = (item.filters || []) + item.linkageFilters = (item.linkageFilters || []) }) this.$store.commit('setComponentData', this.resetID(componentDatas)) // this.$store.commit('setComponentData', this.resetID(JSON.parse(response.data.panelData))) const panelStyle = JSON.parse(response.data.panelStyle) this.$store.commit('setCanvasStyle', panelStyle) this.$store.commit('recordSnapshot')// 记录快照 + // 刷新联动信息 + getPanelAllLinkageInfo(panelId).then(rsp => { + this.$store.commit('setNowPanelTrackInfo', rsp.data) + }) }) } }, @@ -463,6 +470,7 @@ export default { } component.propValue = propValue component.filters = [] + component.linkageFilters = [] } }) } else { @@ -660,6 +668,7 @@ export default { } component.propValue = propValue component.filters = [] + component.linkageFilters = [] } }) diff --git a/frontend/src/views/panel/list/EditPanel/index.vue b/frontend/src/views/panel/list/EditPanel/index.vue index 0aca7f717e..368b7c2e3c 100644 --- a/frontend/src/views/panel/list/EditPanel/index.vue +++ b/frontend/src/views/panel/list/EditPanel/index.vue @@ -134,7 +134,6 @@ export default { return false } - debugger if (this.editPanel.panelInfo.name.length > 50) { this.$warning(this.$t('commons.char_can_not_more_50')) return false diff --git a/frontend/src/views/panel/list/PanelList.vue b/frontend/src/views/panel/list/PanelList.vue index d7b5c99bda..6f69d67cde 100644 --- a/frontend/src/views/panel/list/PanelList.vue +++ b/frontend/src/views/panel/list/PanelList.vue @@ -177,6 +177,8 @@ import { uuid } from 'vue-uuid' import bus from '@/utils/bus' import EditPanel from './EditPanel' import { addGroup, delGroup, groupTree, defaultTree, findOne } from '@/api/panel/panel' +import { getPanelAllLinkageInfo } from '@/api/panel/linkage' +import { mapState } from 'vuex' import { DEFAULT_COMMON_CANVAS_STYLE_STRING } from '@/views/panel/panel' @@ -274,7 +276,10 @@ export default { computed: { panelDialogTitle() { return this.editPanel.titlePre + this.editPanel.titleSuf - } + }, + ...mapState([ + 'nowPanelTrackInfo' + ]) }, watch: { // 切换展示页面后 重新点击一下当前节点 @@ -517,12 +522,18 @@ export default { const componentDatas = JSON.parse(response.data.panelData) componentDatas.forEach(item => { item.filters = (item.filters || []) + item.linkageFilters = (item.linkageFilters || []) }) this.$store.commit('setComponentData', this.resetID(componentDatas)) // this.$store.commit('setComponentData', sourceInfo.type === 'custom' ? sourceInfo : this.resetID(sourceInfo)) const temp = JSON.parse(response.data.panelStyle) this.$store.commit('setCanvasStyle', temp) this.$store.dispatch('panel/setPanelInfo', data) + + // 刷新联动信息 + getPanelAllLinkageInfo(data.id).then(rsp => { + this.$store.commit('setNowPanelTrackInfo', rsp.data) + }) }) } if (node.expanded) { From 18b68616ac5aa463739b6727027a9fde3406a632 Mon Sep 17 00:00:00 2001 From: junjie Date: Tue, 10 Aug 2021 16:13:22 +0800 Subject: [PATCH 04/30] Merge branch 'dev' of /Users/gin/dataease/dataease with conflicts. --- .../request/chart/ChartDrillRequest.java | 15 ++++++ .../request/chart/ChartExtRequest.java | 1 + .../io/dataease/dto/chart/ChartViewDTO.java | 4 ++ .../service/chart/ChartViewService.java | 48 +++++++++++++++---- .../views/chart/components/ChartComponent.vue | 6 +++ frontend/src/views/chart/view/ChartEdit.vue | 21 ++++++-- 6 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 backend/src/main/java/io/dataease/controller/request/chart/ChartDrillRequest.java diff --git a/backend/src/main/java/io/dataease/controller/request/chart/ChartDrillRequest.java b/backend/src/main/java/io/dataease/controller/request/chart/ChartDrillRequest.java new file mode 100644 index 0000000000..c5537b9d4a --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/request/chart/ChartDrillRequest.java @@ -0,0 +1,15 @@ +package io.dataease.controller.request.chart; + +import io.dataease.dto.chart.ChartDimensionDTO; +import lombok.Data; + +import java.util.List; + +/** + * @Author gin + * @Date 2021/8/10 12:25 下午 + */ +@Data +public class ChartDrillRequest { + private List dimensionList; +} diff --git a/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java index 35e310d379..edf9a5e9d7 100644 --- a/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java +++ b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java @@ -16,4 +16,5 @@ public class ChartExtRequest { //联动过滤条件 private List linkageFilters; + private List drill; } diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java index 2a48769ef6..bb7de60135 100644 --- a/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java +++ b/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java @@ -1,9 +1,11 @@ package io.dataease.dto.chart; import io.dataease.base.domain.ChartViewWithBLOBs; +import io.dataease.controller.request.chart.ChartDrillRequest; import lombok.Getter; import lombok.Setter; +import java.util.List; import java.util.Map; /** @@ -20,4 +22,6 @@ public class ChartViewDTO extends ChartViewWithBLOBs { private Boolean isLeaf; private String pid; private String sql; + + private List dimensionList; } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 709dce5e34..6c3171bee7 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -11,19 +11,12 @@ import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.commons.utils.LogUtil; -import io.dataease.controller.request.chart.ChartExtFilterRequest; -import io.dataease.controller.request.chart.ChartExtRequest; -import io.dataease.controller.request.chart.ChartGroupRequest; -import io.dataease.controller.request.chart.ChartViewRequest; -import io.dataease.controller.request.dataset.DataSetGroupRequest; -import io.dataease.controller.request.dataset.DataSetTableRequest; +import io.dataease.controller.request.chart.*; import io.dataease.datasource.provider.DatasourceProvider; import io.dataease.datasource.provider.ProviderFactory; import io.dataease.datasource.request.DatasourceRequest; import io.dataease.datasource.service.DatasourceService; import io.dataease.dto.chart.*; -import io.dataease.dto.dataset.DataSetGroupDTO; -import io.dataease.dto.dataset.DataSetTableDTO; import io.dataease.dto.dataset.DataSetTableUnionDTO; import io.dataease.dto.dataset.DataTableInfoDTO; import io.dataease.i18n.Translator; @@ -197,6 +190,8 @@ public class ChartViewService { }.getType()); List fieldCustomFilter = new Gson().fromJson(view.getCustomFilter(), new TypeToken>() { }.getType()); + List drill = new Gson().fromJson(view.getDrillFields(), new TypeToken>() { + }.getType()); List customFilter = new ArrayList<>(); for (ChartFieldCustomFilterDTO ele : fieldCustomFilter) { List collect = ele.getFilter().stream().map(f -> { @@ -260,6 +255,38 @@ public class ChartViewService { } } + // 下钻 + boolean isDrill = false; + List drillRequest = requestList.getDrill(); + if (drill.size() > drillRequest.size()) { + for (int i = 0; i < drillRequest.size(); i++) { + ChartDrillRequest request = drillRequest.get(i); + for (ChartDimensionDTO dto : request.getDimensionList()) { + ChartViewFieldDTO chartViewFieldDTO = drill.get(i); + // 将钻取值作为条件传递,将所有钻取字段作为xAxis并加上下一个钻取字段 + if (StringUtils.equalsIgnoreCase(dto.getId(), chartViewFieldDTO.getId())) { + isDrill = true; + DatasetTableField datasetTableField = dataSetTableFieldsService.get(dto.getId()); + ChartViewFieldDTO d = new ChartViewFieldDTO(); + BeanUtils.copyBean(d, datasetTableField); + + ChartExtFilterRequest drillFilter = new ChartExtFilterRequest(); + drillFilter.setFieldId(dto.getId()); + drillFilter.setValue(new ArrayList() {{ + add(dto.getValue()); + }}); + drillFilter.setOperator("in"); + drillFilter.setDatasetTableField(datasetTableField); + extFilterList.add(drillFilter); +// xAxis.add(d); +// if (i == drillRequest.size() - 1) { +// xAxis.add(drill.get(i + 1)); +// } + } + } + } + } + // 获取数据集,需校验权限 DatasetTable table = dataSetTableService.get(view.getTableId()); if (ObjectUtils.isEmpty(table)) { @@ -402,6 +429,11 @@ public class ChartViewService { BeanUtils.copyBean(dto, view); dto.setData(map); dto.setSql(datasourceRequest.getQuery()); + + if (CollectionUtils.isNotEmpty(drillRequest) && !isDrill) { + drillRequest = drillRequest.subList(0, drillRequest.size() - 1); + } + dto.setDimensionList(drillRequest); return dto; } diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 4c2573fcb3..9cc8d32a1f 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -64,6 +64,7 @@ export default { const _store = this.$store // 基于准备好的dom,初始化echarts实例 // 渲染echart等待dom加载完毕,渲染之前先尝试销毁具有相同id的echart 放置多次切换仪表板有重复id情况 + const that = this new Promise((resolve) => { resolve() }).then(() => { // 此dom为echarts图标展示dom this.myChart = this.$echarts.getInstanceByDom(document.getElementById(this.chartId)) @@ -71,6 +72,11 @@ export default { this.myChart = this.$echarts.init(document.getElementById(this.chartId)) } this.drawEcharts() + + this.myChart.off('click') + this.myChart.on('click', function(param) { + that.$emit('onChartClick', param) + }) this.myChart.on('click', function(param) { debugger console.log(JSON.stringify(param.data)) diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index d4d89818d5..0b13132795 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -483,7 +483,7 @@
- +
@@ -738,7 +738,8 @@ export default { filterItem: {}, places: [], attrActiveNames: [], - styleActiveNames: [] + styleActiveNames: [], + drillClickDimensionList: [] } }, computed: { @@ -894,6 +895,7 @@ export default { // this.get(response.data.id); // this.getData(response.data.id) + this.resetDrill() if (getData) { this.getData(response.data.id) } else { @@ -983,7 +985,8 @@ export default { getData(id) { if (id) { ajaxGetData(id, { - filter: [] + filter: [], + drill: this.drillClickDimensionList }).then(response => { this.initTableData(response.data.tableId) this.view = JSON.parse(JSON.stringify(response.data)) @@ -1003,8 +1006,10 @@ export default { if (this.chart.privileges) { this.param.privileges = this.chart.privileges } + this.drillClickDimensionList = response.data.drillClickDimensionList ? response.data.drillClickDimensionList : [] }).catch(err => { this.resetView() + this.resetDrill() this.httpRequest.status = err.response.data.success this.httpRequest.msg = err.response.data.message this.$nextTick(() => { @@ -1487,6 +1492,16 @@ export default { bubbleItemRemove(item) { this.view.extBubble.splice(item.index, 1) this.save(true) + }, + + chartClick(param) { + console.log(param) + this.drillClickDimensionList.push({ dimensionList: param.data.dimensionList }) + this.getData(this.param.id) + }, + + resetDrill() { + this.drillClickDimensionList = [] } } } From affdf3ad00dfd14dea41e6e9d85a1cc17228e437 Mon Sep 17 00:00:00 2001 From: junjie Date: Tue, 10 Aug 2021 17:00:15 +0800 Subject: [PATCH 05/30] =?UTF-8?q?feat:=20=E8=A7=86=E5=9B=BE=E4=B8=8B?= =?UTF-8?q?=E9=92=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/dataease/dto/chart/ChartViewDTO.java | 2 +- .../io/dataease/service/chart/ChartViewService.java | 11 +++++------ frontend/src/store/index.js | 1 - .../src/views/chart/components/ChartComponent.vue | 6 ++---- frontend/src/views/chart/view/ChartEdit.vue | 5 ++++- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java index bb7de60135..035e916527 100644 --- a/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java +++ b/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java @@ -23,5 +23,5 @@ public class ChartViewDTO extends ChartViewWithBLOBs { private String pid; private String sql; - private List dimensionList; + private boolean drill; } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 6c3171bee7..cc80f9d81e 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -258,7 +258,7 @@ public class ChartViewService { // 下钻 boolean isDrill = false; List drillRequest = requestList.getDrill(); - if (drill.size() > drillRequest.size()) { + if (CollectionUtils.isNotEmpty(drillRequest) && (drill.size() >= drillRequest.size())) { for (int i = 0; i < drillRequest.size(); i++) { ChartDrillRequest request = drillRequest.get(i); for (ChartDimensionDTO dto : request.getDimensionList()) { @@ -385,7 +385,9 @@ public class ChartViewService { data = (List) cache; }*/ // 仪表板有参数不实用缓存 - if (CollectionUtils.isNotEmpty(requestList.getFilter()) || CollectionUtils.isNotEmpty(requestList.getLinkageFilters())) { + if (CollectionUtils.isNotEmpty(requestList.getFilter()) + || CollectionUtils.isNotEmpty(requestList.getLinkageFilters()) + || CollectionUtils.isNotEmpty(requestList.getDrill())) { data = datasourceProvider.getData(datasourceRequest); } else { try { @@ -430,10 +432,7 @@ public class ChartViewService { dto.setData(map); dto.setSql(datasourceRequest.getQuery()); - if (CollectionUtils.isNotEmpty(drillRequest) && !isDrill) { - drillRequest = drillRequest.subList(0, drillRequest.size() - 1); - } - dto.setDimensionList(drillRequest); + dto.setDrill(isDrill); return dto; } diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 7114ce2c23..ad150e7fa4 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -162,7 +162,6 @@ const data = { // 添加联动 下钻 等过滤组件 addViewTrackFilter(state, data) { console.log('联动信息', JSON.stringify(data)) - debugger const viewId = data.viewId const trackInfo = state.nowPanelTrackInfo for (let index = 0; index < state.componentData.length; index++) { diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 9cc8d32a1f..f8fe08573e 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -75,10 +75,6 @@ export default { this.myChart.off('click') this.myChart.on('click', function(param) { - that.$emit('onChartClick', param) - }) - this.myChart.on('click', function(param) { - debugger console.log(JSON.stringify(param.data)) const trackFilter = { viewId: viewId, @@ -86,6 +82,8 @@ export default { quotaList: param.data.quotaList } _store.commit('addViewTrackFilter', trackFilter) + + that.$emit('onChartClick', param) }) }) }, diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index 0b13132795..4567f8b0aa 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -751,6 +751,7 @@ export default { }, watch: { 'param': function() { + this.resetDrill() if (this.param.optType === 'new') { // } else { @@ -1006,7 +1007,9 @@ export default { if (this.chart.privileges) { this.param.privileges = this.chart.privileges } - this.drillClickDimensionList = response.data.drillClickDimensionList ? response.data.drillClickDimensionList : [] + if (!response.data.drill) { + this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1) + } }).catch(err => { this.resetView() this.resetDrill() From 347b64eff25c415c5362a4d0b73d5b29516b21c4 Mon Sep 17 00:00:00 2001 From: taojinlong Date: Tue, 10 Aug 2021 17:01:20 +0800 Subject: [PATCH 06/30] feat: pg --- .../datasource/constants/DatasourceTypes.java | 1 + .../datasource/dto/PgConfigration.java | 21 + .../datasource/provider/JdbcProvider.java | 33 +- .../datasource/provider/ProviderFactory.java | 4 + .../io/dataease/provider/pg/PgConstants.java | 43 + .../dataease/provider/pg/PgQueryProvider.java | 911 ++++++++++++++++++ .../service/dataset/DataSetTableService.java | 5 + .../service/dataset/ExtractDataService.java | 16 +- frontend/src/views/system/datasource/form.vue | 37 +- 9 files changed, 1041 insertions(+), 30 deletions(-) create mode 100644 backend/src/main/java/io/dataease/datasource/dto/PgConfigration.java create mode 100644 backend/src/main/java/io/dataease/provider/pg/PgConstants.java create mode 100644 backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java diff --git a/backend/src/main/java/io/dataease/datasource/constants/DatasourceTypes.java b/backend/src/main/java/io/dataease/datasource/constants/DatasourceTypes.java index fcaf060a42..3724c7f8ea 100644 --- a/backend/src/main/java/io/dataease/datasource/constants/DatasourceTypes.java +++ b/backend/src/main/java/io/dataease/datasource/constants/DatasourceTypes.java @@ -3,6 +3,7 @@ package io.dataease.datasource.constants; public enum DatasourceTypes { excel("excel", "excel", "", "", "", "", ""), mysql("mysql", "mysql", "com.mysql.jdbc.Driver", "`", "`", "'", "'"), + pg("pg", "pg", "org.postgresql.Driver", "\"", "\"", "\"", "\""), sqlServer("sqlServer", "sqlServer", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "\"", "\"", "\"", "\""), doris("doris", "doris", "com.mysql.jdbc.Driver", "`", "`", "", ""), oracle("oracle", "oracle", "oracle.jdbc.driver.OracleDriver", "\"", "\"", "\"", "\""); diff --git a/backend/src/main/java/io/dataease/datasource/dto/PgConfigration.java b/backend/src/main/java/io/dataease/datasource/dto/PgConfigration.java new file mode 100644 index 0000000000..4ce5db6c4f --- /dev/null +++ b/backend/src/main/java/io/dataease/datasource/dto/PgConfigration.java @@ -0,0 +1,21 @@ +package io.dataease.datasource.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PgConfigration extends JdbcDTO { + + private String driver = "org.postgresql.Driver"; + + private String schema; + + public String getJdbc() { + // 连接参数先写死,后边要把编码、时区等参数放到数据源的设置中 + return "jdbc:postgresql://HOSTNAME:PORT/DATABASE" + .replace("HOSTNAME", getHost()) + .replace("PORT", getPort().toString()) + .replace("DATABASE", getDataBase()); + } +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java index 12e30186df..dff85bc0e4 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java +++ b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java @@ -3,10 +3,7 @@ package io.dataease.datasource.provider; import com.google.gson.Gson; import com.mchange.v2.c3p0.ComboPooledDataSource; import io.dataease.datasource.constants.DatasourceTypes; -import io.dataease.datasource.dto.MysqlConfigration; -import io.dataease.datasource.dto.OracleConfigration; -import io.dataease.datasource.dto.SqlServerConfigration; -import io.dataease.datasource.dto.TableFiled; +import io.dataease.datasource.dto.*; import io.dataease.datasource.request.DatasourceRequest; import io.dataease.exception.DataEaseException; import io.dataease.i18n.Translator; @@ -222,8 +219,10 @@ public class JdbcProvider extends DatasourceProvider { public List getSchema(DatasourceRequest datasourceRequest) throws Exception { List schemas = new ArrayList<>(); String queryStr = getSchemaSql(datasourceRequest); + System.out.println(queryStr); Connection con = null; try { + System.out.println(new Gson().toJson(datasourceRequest)); con = getConnection(datasourceRequest); Statement statement = con.createStatement(); ResultSet resultSet = statement.executeQuery(queryStr); @@ -309,7 +308,7 @@ public class JdbcProvider extends DatasourceProvider { resultSet.close(); ps.close(); } catch (Exception e) { - DataEaseException.throwException(Translator.get("i18n_datasource_connect_error") + e.getMessage()); + DataEaseException.throwException(e.getMessage()); } finally { if(con != null){con.close();} } @@ -433,6 +432,12 @@ public class JdbcProvider extends DatasourceProvider { props.put( "oracle.net.CONNECT_TIMEOUT" , "5000") ; // props.put( "oracle.jdbc.ReadTimeout" , "5000" ) ; break; + case pg: + PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class); + username = pgConfigration.getUsername(); + password = pgConfigration.getPassword(); + driver = pgConfigration.getDriver(); + jdbcurl = pgConfigration.getJdbc(); default: break; } @@ -477,6 +482,13 @@ public class JdbcProvider extends DatasourceProvider { dataSource.setPassword(oracleConfigration.getPassword()); dataSource.setJdbcUrl(oracleConfigration.getJdbc()); break; + case pg: + PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class); + dataSource.setUser(pgConfigration.getUsername()); + dataSource.setDriverClass(pgConfigration.getDriver()); + dataSource.setPassword(pgConfigration.getPassword()); + dataSource.setJdbcUrl(pgConfigration.getJdbc()); + break; default: break; } @@ -494,6 +506,9 @@ public class JdbcProvider extends DatasourceProvider { case sqlServer: SqlServerConfigration sqlServerConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), SqlServerConfigration.class); return sqlServerConfigration.getDataBase(); + case pg: + PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class); + return pgConfigration.getDataBase(); default: return null; } @@ -517,6 +532,12 @@ public class JdbcProvider extends DatasourceProvider { throw new Exception(Translator.get("i18n_schema_is_empty")); } return "select table_name, owner from all_tables where owner='" + oracleConfigration.getSchema() + "'"; + case pg: + PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class); + if(StringUtils.isEmpty(pgConfigration.getSchema())){ + throw new Exception(Translator.get("i18n_schema_is_empty")); + } + return "SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg%' AND tablename NOT LIKE 'sql_%' AND schemaname='SCHEMA' ;".replace("SCHEMA", pgConfigration.getSchema()); default: return "show tables;"; } @@ -529,6 +550,8 @@ public class JdbcProvider extends DatasourceProvider { return "select * from all_users"; case sqlServer: return "select name from sys.schemas;"; + case pg: + return "SELECT nspname FROM pg_namespace;"; default: return "show tables;"; } diff --git a/backend/src/main/java/io/dataease/datasource/provider/ProviderFactory.java b/backend/src/main/java/io/dataease/datasource/provider/ProviderFactory.java index 88a720571a..d780399648 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/ProviderFactory.java +++ b/backend/src/main/java/io/dataease/datasource/provider/ProviderFactory.java @@ -28,6 +28,8 @@ public class ProviderFactory implements ApplicationContextAware { return context.getBean("jdbc", DatasourceProvider.class); case sqlServer: return context.getBean("jdbc", DatasourceProvider.class); + case pg: + return context.getBean("jdbc", DatasourceProvider.class); default: return context.getBean("jdbc", DatasourceProvider.class); } @@ -42,6 +44,8 @@ public class ProviderFactory implements ApplicationContextAware { return context.getBean("dorisQuery", QueryProvider.class); case sqlServer: return context.getBean("sqlserverQuery", QueryProvider.class); + case pg: + return context.getBean("pgQuery", QueryProvider.class); case oracle: return context.getBean("oracleQuery", QueryProvider.class); default: diff --git a/backend/src/main/java/io/dataease/provider/pg/PgConstants.java b/backend/src/main/java/io/dataease/provider/pg/PgConstants.java new file mode 100644 index 0000000000..e9f9555ae3 --- /dev/null +++ b/backend/src/main/java/io/dataease/provider/pg/PgConstants.java @@ -0,0 +1,43 @@ +package io.dataease.provider.pg; + +import io.dataease.provider.SQLConstants; + +import static io.dataease.datasource.constants.DatasourceTypes.pg; + +/** + * @Author gin + * @Date 2021/7/8 7:22 下午 + */ +public class PgConstants extends SQLConstants { + public static final String KEYWORD_TABLE = pg.getKeywordPrefix() + "%s" + pg.getKeywordSuffix(); + + public static final String KEYWORD_FIX = "%s." + pg.getKeywordPrefix() + "%s" + pg.getKeywordSuffix(); + + public static final String UNIX_TIMESTAMP = "floor(extract(epoch from(( %s - timestamp '1970-01-01 00:00:00')*1000))) "; + + public static final String DATE_FORMAT = "to_char(%s, %s)"; + + public static final String FROM_UNIXTIME = "to_timestamp(%s)"; + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String DEFAULT_DATE_FORMAT = "'YYYY-MM-DD HH24:MI:SS'"; + + public static final String DEFAULT_INT_FORMAT = "numeric(18,0)"; + + public static final String DEFAULT_FLOAT_FORMAT = "numeric(18,2)"; + + public static final String WHERE_VALUE_NULL = "(NULL,'')"; + + public static final String WHERE_VALUE_VALUE = "'%s'"; + + public static final String AGG_COUNT = "COUNT(*)"; + + public static final String AGG_FIELD = "%s(%s)"; + + public static final String WHERE_BETWEEN = "'%s' AND '%s'"; + + public static final String BRACKETS = "(%s)"; + + +} diff --git a/backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java b/backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java new file mode 100644 index 0000000000..9610d2bc8a --- /dev/null +++ b/backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java @@ -0,0 +1,911 @@ +package io.dataease.provider.pg; + +import io.dataease.base.domain.DatasetTableField; +import io.dataease.base.domain.DatasetTableFieldExample; +import io.dataease.base.domain.Datasource; +import io.dataease.base.mapper.DatasetTableFieldMapper; +import io.dataease.commons.constants.DeTypeConstants; +import io.dataease.controller.request.chart.ChartExtFilterRequest; +import io.dataease.dto.chart.ChartCustomFilterDTO; +import io.dataease.dto.chart.ChartViewFieldDTO; +import io.dataease.dto.sqlObj.SQLObj; +import io.dataease.provider.QueryProvider; +import io.dataease.provider.SQLConstants; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static io.dataease.provider.SQLConstants.TABLE_ALIAS_PREFIX; + + + +@Service("pgQuery") +public class PgQueryProvider extends QueryProvider { + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + @Override + public Integer transFieldType(String field) { + field = field.toLowerCase(); + switch (field) { + case "bpchar": + case "varchar": + case "text": + case "tsquery": + case "tsvector": + case "uuid": + case "xml": + case "json": + case "bit": + case "jsonb": + case "cidr": + case "inet": + case "macaddr": + case "txid_snapshot": + case "box": + case "circle": + case "line": + case "lseg": + case "path": + case "point": + case "polygon": + case "bool": + return DeTypeConstants.DE_STRING;// 文本 + case "date": + case "time": + case "timestamp": + case "timestamptz": + case "interval": + return DeTypeConstants.DE_TIME;// 时间 + case "int2": + case "int4": + case "int8": + case "INTEGER": + case "BIGINT": + return DeTypeConstants.DE_INT;// 整型 + case "numeric": + case "float4": + case "float8": + case "money": + return DeTypeConstants.DE_FLOAT;// 浮点 +// case "bool": + case "TINYINT": + return DeTypeConstants.DE_BOOL;// 布尔 + case "bytea": + return DeTypeConstants.DE_Binary;// 二进制 + default: + return DeTypeConstants.DE_STRING; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") AS tmp " + " LIMIT 1000 offset 0"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(fields)) { + for (int i = 0; i < fields.size(); i++) { + DatasetTableField f = fields.get(i); + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format( PgConstants.UNIX_TIMESTAMP, originField); + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format( PgConstants.CAST, originField, PgConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format( PgConstants.CAST, originField, PgConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format( PgConstants.CAST, originField, "timestamp"); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + String cast = String.format( PgConstants.CAST, originField, "bigint"); + fieldName = String.format( PgConstants.FROM_UNIXTIME, cast ); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format( PgConstants.CAST, originField, PgConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + xFields.add(SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build()); + } + } + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", isGroup); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + return st_sql.render(); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null); + } + + @Override + public String createQuerySQLWithPage(String table, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds) { + return createQuerySQL(table, fields, isGroup, null) + " LIMIT " + realSize + " offset " + (page - 1) * pageSize; + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds) { + return createQuerySQL(table, fields, isGroup, null) + " LIMIT " + limit + " offset 0"; + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup) { + return createQuerySQLAsTmp(sql, fields, isGroup) + " LIMIT " + limit + " offset 0"; + } + + @Override + public String createQuerySQLAsTmpWithPage(String sql, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup) { + return createQuerySQLAsTmp(sql, fields, isGroup) + " LIMIT " + realSize + " offset " + (page - 1) * pageSize; + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + List xWheres = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴过滤 +// xWheres.addAll(getXWheres(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.addAll(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + List customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + wheres.addAll(xWheres); + if (customWheres != null) wheres.addAll(customWheres); + if (extWheres != null) wheres.addAll(extWheres); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extStack) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + List xWheres = new ArrayList<>(); + List xOrders = new ArrayList<>(); + List xList = new ArrayList<>(); + xList.addAll(xAxis); + xList.addAll(extStack); + if (CollectionUtils.isNotEmpty(xList)) { + for (int i = 0; i < xList.size(); i++) { + ChartViewFieldDTO x = xList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴过滤 +// xWheres.addAll(getXWheres(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.addAll(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + List customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + wheres.addAll(xWheres); + if (customWheres != null) wheres.addAll(customWheres); + if (extWheres != null) wheres.addAll(extWheres); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpStack(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extStack) { + return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extBubble) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + List xWheres = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴过滤 +// xWheres.addAll(getXWheres(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + List yList = new ArrayList<>(); + yList.addAll(yAxis); + yList.addAll(extBubble); + if (CollectionUtils.isNotEmpty(yList)) { + for (int i = 0; i < yList.size(); i++) { + ChartViewFieldDTO y = yList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.addAll(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + List customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + wheres.addAll(xWheres); + if (customWheres != null) wheres.addAll(customWheres); + if (extWheres != null) wheres.addAll(extWheres); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpScatter(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extBubble) { + return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble); + } + + @Override + public String searchTable(String table) { + return "SELECT table_name FROM information_schema.TABLES WHERE table_name ='" + table + "'"; + } + + @Override + public String getSQLSummary(String table, List yAxis, List customFilter, List extFilterRequestList) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.addAll(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + List customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.addAll(customWheres); + if (extWheres != null) wheres.addAll(extWheres); + List groups = new ArrayList<>(); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLSummaryAsTmp(String sql, List yAxis, List customFilter, List extFilterRequestList) { + return getSQLSummary("(" + sqlFix(sql) + ")", yAxis, customFilter, extFilterRequestList); + } + + @Override + public String wrapSql(String sql) { + sql = sql.trim(); + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + String tmpSql = "SELECT * FROM (" + sql + ") AS tmp " + " LIMIT 0 "; + return tmpSql; + } + + @Override + public String createRawQuerySQL(String table, List fields) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); +// if (f.getDeExtractType() == 4) { // 处理 tinyint +// stringBuilder.append("concat(`").append(f.getOriginName()).append("`,'') AS ").append(f.getDataeaseName()); +// } else { +// stringBuilder.append("`").append(f.getOriginName()).append("` AS ").append(f.getDataeaseName()); +// } + stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName()); + return stringBuilder.toString(); + }).toArray(String[]::new); + return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table); + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields); + } + + public String transMysqlFilterTerm(String term) { + switch (term) { + case "eq": + return " = "; + case "not_eq": + return " <> "; + case "lt": + return " < "; + case "le": + return " <= "; + case "gt": + return " > "; + case "ge": + return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; + case "null": + return " IN "; + case "not_null": + return " IS NOT NULL AND %s <> ''"; + case "between": + return " BETWEEN "; + default: + return ""; + } + } + + public List transCustomFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartCustomFilterDTO request : requestList) { + DatasetTableField field = request.getField(); + if (ObjectUtils.isEmpty(field)) { + continue; + } + String value = request.getValue(); + String whereName = ""; + String whereTerm = transMysqlFilterTerm(request.getTerm()); + String whereValue = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == 1 && field.getDeExtractType() != 1) { + String cast = String.format( PgConstants.CAST, originName, "bigint"); + whereName = String.format( PgConstants.FROM_UNIXTIME, cast); + } else { + whereName = originName; + } + if (StringUtils.equalsIgnoreCase(request.getTerm(), "null")) { + whereValue = PgConstants.WHERE_VALUE_NULL; + } else if (StringUtils.equalsIgnoreCase(request.getTerm(), "not_null")) { + whereTerm = String.format(whereTerm, originName); + } else if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, value); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + return list; + } + + public List transExtFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + DatasetTableField field = request.getDatasetTableField(); + if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + String whereTerm = transMysqlFilterTerm(request.getOperator()); + String whereValue = ""; + + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + + if (field.getDeType() == 1 && field.getDeExtractType() != 1) { + String cast = String.format( PgConstants.CAST, originName, "bigint"); + whereName = String.format( PgConstants.FROM_UNIXTIME, cast); + } else { + whereName = originName; + } + + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + whereValue = "'%" + value.get(0) + "%'"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) { + if (request.getDatasetTableField().getDeType() == 1) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0)))); + String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1)))); + whereValue = String.format( PgConstants.WHERE_BETWEEN, startTime, endTime); + } else { + whereValue = String.format( PgConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, value.get(0)); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + return list; + } + + private String sqlFix(String sql) { + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + return sql; + } + + private String transDateFormat(String dateStyle, String datePattern) { + String split = "-"; + if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) { + split = "-"; + } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { + split = "/"; + } + + switch (dateStyle) { + case "y": + return "'YYYY'"; + case "y_M": + return "'YYYY" + split + "MM'"; + case "y_M_d": + return "'YYYY" + split + "MM" + split + "DD'"; + case "H_m_s": + return "'HH24:MI:SS'"; + case "y_M_d_H_m": + return "'YYYY" + split + "MM" + split + "DD" + " HH24:MI'"; + case "y_M_d_H_m_s": + return "'YYYY" + split + "MM" + split + "DD" + " %H:%i:%S'"; + default: + return "'YYYY-MM-DD HH24:MI:SS'"; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (x.getDeType() == 2 || x.getDeType() == 3) { + fieldName = String.format( PgConstants.UNIX_TIMESTAMP, originField); + } else if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + fieldName = String.format( PgConstants.DATE_FORMAT, originField, format); + } else { + fieldName = originField; + } + } else { + if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getDeExtractType() == DeTypeConstants.DE_STRING) { + fieldName = String.format( PgConstants.DATE_FORMAT, originField, format); + } else { + String cast = String.format( PgConstants.CAST, originField, "bigint"); + String from_unixtime = String.format( PgConstants.FROM_UNIXTIME, cast); + fieldName = String.format( PgConstants.DATE_FORMAT, from_unixtime, format); + } + } else { + fieldName = originField; + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { + String fieldName = ""; + if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { + fieldName = PgConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + fieldName = String.format( PgConstants.AGG_FIELD, y.getSummary(), originField); + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format( PgConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? PgConstants.DEFAULT_INT_FORMAT : PgConstants.DEFAULT_FLOAT_FORMAT); + String agg = String.format( PgConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format( PgConstants.CAST, agg, PgConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format( PgConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? PgConstants.DEFAULT_INT_FORMAT : PgConstants.DEFAULT_FLOAT_FORMAT); + fieldName = String.format( PgConstants.AGG_FIELD, y.getSummary(), cast); + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private List getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) { + y.getFilter().forEach(f -> { + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = PgConstants.WHERE_VALUE_NULL; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereTerm = String.format(whereTerm, originField); + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(fieldAlias) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + return list; + } + + private String calcFieldRegex(String originField, SQLObj tableObj) { + originField = originField.replaceAll("[\\t\\n\\r]]", ""); + // 正则提取[xxx] + String regex = "\\[(.*?)]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originField); + Set ids = new HashSet<>(); + while (matcher.find()) { + String id = matcher.group(1); + ids.add(id); + } + if (CollectionUtils.isEmpty(ids)) { + return originField; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andIdIn(new ArrayList<>(ids)); + List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + for (DatasetTableField ele : calcFields) { + originField = originField.replaceAll("\\[" + ele.getId() + "]", + String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } +} diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index 080882493f..54f5018b93 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -379,6 +379,7 @@ public class DataSetTableService { QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false, ds)); map.put("sql", datasourceRequest.getQuery()); + System.out.println(datasourceRequest.getQuery()); try { data.addAll(datasourceProvider.getData(datasourceRequest)); } catch (Exception e) { @@ -903,7 +904,9 @@ public class DataSetTableService { datasetTableField.setDeType(transFieldType(filed.getFieldType())); datasetTableField.setDeExtractType(transFieldType(filed.getFieldType())); } else { + System.out.println(new Gson().toJson(filed)); Integer fieldType = qp.transFieldType(filed.getFieldType()); + System.out.println(fieldType); datasetTableField.setDeType(fieldType == 4 ? 2 : fieldType); datasetTableField.setDeExtractType(fieldType); } @@ -1087,6 +1090,8 @@ public class DataSetTableService { List fields = (List) fileMap.get("fields"); List newFields = fields.stream().map(TableFiled::getRemarks).collect(Collectors.toList()); List oldFields = datasetTableFields.stream().map(DatasetTableField::getOriginName).collect(Collectors.toList()); + System.out.println("oldFields: " + oldFields); + System.out.println("newFields: "+ newFields); if (!oldFields.equals(newFields)) { DataEaseException.throwException(Translator.get("i18n_excel_colume_change")); } diff --git a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java index 6c90cb0491..54667b4468 100644 --- a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java +++ b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java @@ -192,7 +192,7 @@ public class ExtractDataService { dropDorisTable(DorisTableUtils.dorisTmpName(DorisTableUtils.dorisName(datasetTableId))); } finally { deleteFile("all_scope", datasetTableId); - deleteFile(new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getData()); +// deleteFile(new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getData()); } break; @@ -930,13 +930,15 @@ public class ExtractDataService { } if (datasourceType.equals(DatasourceTypes.excel)) { + System.out.println(Column_Fields); tmp_code = tmp_code.replace("handleExcelIntColumn", handleExcelIntColumn).replace("Column_Fields", Column_Fields); } else { tmp_code = tmp_code.replace("handleExcelIntColumn", "").replace("Column_Fields", Column_Fields); } tmp_code = tmp_code.replace("handleBinaryType", handleBinaryTypeCode); - + + System.out.println(tmp_code); UserDefinedJavaClassDef userDefinedJavaClassDef = new UserDefinedJavaClassDef(UserDefinedJavaClassDef.ClassType.TRANSFORM_CLASS, "Processor", tmp_code); userDefinedJavaClassDef.setActive(true); @@ -1019,13 +1021,13 @@ public class ExtractDataService { } } - private static String handleBinaryType = " \t\tif(\"FEILD\".equalsIgnoreCase(filed)){\n" + + private final static String handleBinaryType = " \t\tif(\"FEILD\".equalsIgnoreCase(filed)){\n" + " get(Fields.Out, filed).setValue(r, \"\");\n" + " get(Fields.Out, filed).getValueMeta().setType(2);\n" + " \t}"; - private static String alterColumnTypeCode = " if(\"FILED\".equalsIgnoreCase(filed)){\n" + + private final static String alterColumnTypeCode = " if(\"FILED\".equalsIgnoreCase(filed)){\n" + "\t if(tmp != null && tmp.equalsIgnoreCase(\"Y\")){\n" + " get(Fields.Out, filed).setValue(r, 1);\n" + " get(Fields.Out, filed).getValueMeta().setType(2);\n" + @@ -1035,7 +1037,7 @@ public class ExtractDataService { " }\n" + " }\n"; - private static String handleExcelIntColumn = " \t\tif(tmp != null && tmp.endsWith(\".0\")){\n" + + private final static String handleExcelIntColumn = " \t\tif(tmp != null && tmp.endsWith(\".0\")){\n" + " try {\n" + " Long.valueOf(tmp.substring(0, tmp.length()-2));\n" + " get(Fields.Out, filed).setValue(r, tmp.substring(0, tmp.length()-2));\n" + @@ -1043,14 +1045,14 @@ public class ExtractDataService { " }catch (Exception e){}\n" + " }"; - private static String handleWraps = " if(tmp != null && ( tmp.contains(\"\\r\") || tmp.contains(\"\\n\"))){\n" + + private final static String handleWraps = " if(tmp != null && ( tmp.contains(\"\\r\") || tmp.contains(\"\\n\"))){\n" + "\t\t\ttmp = tmp.trim();\n" + " tmp = tmp.replaceAll(\"\\r\",\" \");\n" + " tmp = tmp.replaceAll(\"\\n\",\" \");\n" + " get(Fields.Out, filed).setValue(r, tmp);\n" + " } "; - private static String code = "import org.pentaho.di.core.row.ValueMetaInterface;\n" + + private final static String code = "import org.pentaho.di.core.row.ValueMetaInterface;\n" + "import java.util.List;\n" + "import java.io.File;\n" + "import java.security.MessageDigest;\n" + diff --git a/frontend/src/views/system/datasource/form.vue b/frontend/src/views/system/datasource/form.vue index e2ee45c109..a35918376e 100644 --- a/frontend/src/views/system/datasource/form.vue +++ b/frontend/src/views/system/datasource/form.vue @@ -46,13 +46,13 @@ - + {{ $t('datasource.get_schema') }} - + - - - {{ $t('datasource.get_schema') }} - - - - - - - + + + + + + + + + + + + + + + + + + {{ $t('chart.drill') }} + / + {{ $t('chart.dimension') }} + + + + + + +
+ {{ $t('chart.placeholder_field') }} +
+
@@ -879,6 +879,13 @@ export default { if (view.type === 'treemap' && trigger === 'chart') { view.customAttr.label.show = true } + if (view.type === 'treemap' || + view.type.includes('table') || + view.type.includes('text') || + view.type.includes('gauge') || + view.type.includes('radar')) { + view.drillFields = [] + } view.customFilter.forEach(function(ele) { if (ele && !ele.filter) { ele.filter = [] @@ -1498,7 +1505,6 @@ export default { }, chartClick(param) { - console.log(param) this.drillClickDimensionList.push({ dimensionList: param.data.dimensionList }) this.getData(this.param.id) }, From 22d32aafaab7b3b7ec991edf88b516e11f8a328d Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Tue, 10 Aug 2021 17:45:23 +0800 Subject: [PATCH 08/30] =?UTF-8?q?feat:=E6=80=8E=E8=AE=B2=E4=BB=AA=E8=A1=A8?= =?UTF-8?q?=E6=9D=BF=E8=81=94=E5=8A=A8=E6=B8=85=E9=99=A4=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../canvas/components/Editor/CanvasOptBar.vue | 49 +++++++++++++++++++ .../canvas/components/Editor/Preview.vue | 4 +- .../canvas/components/Editor/index.vue | 7 ++- frontend/src/store/index.js | 7 +++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/canvas/components/Editor/CanvasOptBar.vue diff --git a/frontend/src/components/canvas/components/Editor/CanvasOptBar.vue b/frontend/src/components/canvas/components/Editor/CanvasOptBar.vue new file mode 100644 index 0000000000..d3e9a299f1 --- /dev/null +++ b/frontend/src/components/canvas/components/Editor/CanvasOptBar.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/frontend/src/components/canvas/components/Editor/Preview.vue b/frontend/src/components/canvas/components/Editor/Preview.vue index 9eda38c7c8..d40a4ae3ed 100644 --- a/frontend/src/components/canvas/components/Editor/Preview.vue +++ b/frontend/src/components/canvas/components/Editor/Preview.vue @@ -3,6 +3,7 @@ {{ $t('panel.panelNull') }} + + + + { + if (item.linkageFilters && item.linkageFilters.length > 0) { + item.linkageFilters.splice(0, item.linkageFilters.length) + } + }) } }, modules: { From 80548698b963b646c6c010e806624aca9a988751 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Tue, 10 Aug 2021 17:51:11 +0800 Subject: [PATCH 09/30] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0xpack=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=86=85api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataease/auth/api/dto/CurrentUserDto.java | 3 + .../dataease/auth/entity/SysUserEntity.java | 11 + .../dataease/base/domain/SysMsgChannel.java | 5 + .../dataease/base/domain/SysMsgSetting.java | 7 + .../io/dataease/base/domain/SysMsgType.java | 8 + .../java/io/dataease/base/domain/SysUser.java | 18 + .../commons/condition/LicStatusCondition.java | 28 + .../dataease/config/Knife4jConfiguration.java | 17 +- .../controller/sys/SysDeptController.java | 15 +- .../controller/sys/SysRoleController.java | 15 +- .../controller/sys/SysUserController.java | 18 +- .../controller/sys/base/BaseGridRequest.java | 3 + .../controller/sys/base/ConditionEntity.java | 4 + .../sys/request/BatchSettingRequest.java | 7 +- .../controller/sys/request/MsgRequest.java | 4 + .../sys/request/MsgSettingRequest.java | 3 + .../sys/request/SysUserCreateRequest.java | 3 + .../sys/request/SysUserPwdRequest.java | 5 + .../sys/request/SysUserStateRequest.java | 3 + .../sys/response/SettingTreeNode.java | 4 + .../plugins/server/PluginCommonServer.java | 3 + .../dataease/plugins/server/XDeptServer.java | 15 +- .../dataease/plugins/server/XRoleServer.java | 9 + .../dataease/service/sys/SysRoleService.java | 28 +- frontend/src/api/system/dept.js | 44 +- frontend/src/api/system/role.js | 100 ++-- frontend/src/api/system/user.js | 10 +- frontend/src/views/system/dept/form.vue | 161 ------ frontend/src/views/system/dept/index.vue | 521 ------------------ frontend/src/views/system/role/form.vue | 104 ---- frontend/src/views/system/role/index.vue | 276 ---------- frontend/src/views/system/user/form.vue | 7 +- frontend/src/views/system/user/index.vue | 4 +- 33 files changed, 279 insertions(+), 1184 deletions(-) create mode 100644 backend/src/main/java/io/dataease/commons/condition/LicStatusCondition.java delete mode 100644 frontend/src/views/system/dept/form.vue delete mode 100644 frontend/src/views/system/dept/index.vue delete mode 100644 frontend/src/views/system/role/form.vue delete mode 100644 frontend/src/views/system/role/index.vue diff --git a/backend/src/main/java/io/dataease/auth/api/dto/CurrentUserDto.java b/backend/src/main/java/io/dataease/auth/api/dto/CurrentUserDto.java index ab279d815d..9bc1ac61e3 100644 --- a/backend/src/main/java/io/dataease/auth/api/dto/CurrentUserDto.java +++ b/backend/src/main/java/io/dataease/auth/api/dto/CurrentUserDto.java @@ -1,6 +1,7 @@ package io.dataease.auth.api.dto; import io.dataease.auth.entity.SysUserEntity; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.NoArgsConstructor; @@ -11,7 +12,9 @@ import java.util.List; @NoArgsConstructor public class CurrentUserDto extends SysUserEntity implements Serializable { + @ApiModelProperty("角色集合") private List roles; + @ApiModelProperty("权限集合") private List permissions; } diff --git a/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java b/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java index 1bed1ac17b..2eb61eb0b4 100644 --- a/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java +++ b/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java @@ -1,6 +1,7 @@ package io.dataease.auth.entity; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -8,23 +9,33 @@ import java.io.Serializable; public class SysUserEntity implements Serializable { + @ApiModelProperty(hidden = true) private Long userId; + @ApiModelProperty("账号") private String username; + @ApiModelProperty("姓名") private String nickName; + @ApiModelProperty("组织ID") private Long deptId; + @ApiModelProperty(hidden = true) private String password; + @ApiModelProperty("状态") private Integer enabled; + @ApiModelProperty("邮箱") private String email; + @ApiModelProperty("电话") private String phone; + @ApiModelProperty(hidden = true) private String language; + @ApiModelProperty(hidden = true) private Boolean isAdmin; } diff --git a/backend/src/main/java/io/dataease/base/domain/SysMsgChannel.java b/backend/src/main/java/io/dataease/base/domain/SysMsgChannel.java index 0ca1830b37..2bae1b3142 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysMsgChannel.java +++ b/backend/src/main/java/io/dataease/base/domain/SysMsgChannel.java @@ -1,12 +1,17 @@ package io.dataease.base.domain; import java.io.Serializable; + +import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class SysMsgChannel implements Serializable { + + @ApiModelProperty("消息渠道ID") private Long msgChannelId; + @ApiModelProperty("消息渠道名称") private String channelName; private static final long serialVersionUID = 1L; diff --git a/backend/src/main/java/io/dataease/base/domain/SysMsgSetting.java b/backend/src/main/java/io/dataease/base/domain/SysMsgSetting.java index 6d86ed720f..49862f077e 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysMsgSetting.java +++ b/backend/src/main/java/io/dataease/base/domain/SysMsgSetting.java @@ -1,18 +1,25 @@ package io.dataease.base.domain; import java.io.Serializable; + +import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class SysMsgSetting implements Serializable { + @ApiModelProperty(hidden = true) private Long msgSettingId; + @ApiModelProperty("订阅用户ID") private Long userId; + @ApiModelProperty("订阅类型ID") private Long typeId; + @ApiModelProperty("订阅渠道ID") private Long channelId; + @ApiModelProperty("订阅状态ID") private Boolean enable; private static final long serialVersionUID = 1L; diff --git a/backend/src/main/java/io/dataease/base/domain/SysMsgType.java b/backend/src/main/java/io/dataease/base/domain/SysMsgType.java index fd27679478..97262451b5 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysMsgType.java +++ b/backend/src/main/java/io/dataease/base/domain/SysMsgType.java @@ -1,18 +1,26 @@ package io.dataease.base.domain; import java.io.Serializable; + +import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class SysMsgType implements Serializable { + + @ApiModelProperty("消息类型ID") private Long msgTypeId; + @ApiModelProperty("上级类型ID") private Long pid; + @ApiModelProperty("消息类型名称") private String typeName; + @ApiModelProperty(hidden = true) private String router; + @ApiModelProperty(hidden = true) private String callback; private static final long serialVersionUID = 1L; diff --git a/backend/src/main/java/io/dataease/base/domain/SysUser.java b/backend/src/main/java/io/dataease/base/domain/SysUser.java index 8f62905999..6ebfbcf4d3 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysUser.java +++ b/backend/src/main/java/io/dataease/base/domain/SysUser.java @@ -1,40 +1,58 @@ package io.dataease.base.domain; import java.io.Serializable; + +import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class SysUser implements Serializable { + @ApiModelProperty(value = "用户ID" , allowEmptyValue = false, position = 0) private Long userId; + @ApiModelProperty(value = "组织ID" , allowEmptyValue = false, position = 7) private Long deptId; + @ApiModelProperty(value = "账号" , required = true) private String username; + @ApiModelProperty(value = "姓名" , required = true, position = 2) private String nickName; + @ApiModelProperty(value = "性别" ,allowableValues = "男,女", allowEmptyValue = true, position = 5) private String gender; + @ApiModelProperty(value = "电话" , allowEmptyValue = true, position = 1) private String phone; + @ApiModelProperty(value = "邮箱" , required = true, position = 3) private String email; + @ApiModelProperty(value = "密码" , required = true, position = 4) private String password; + @ApiModelProperty(hidden = true) private Boolean isAdmin; + @ApiModelProperty(value = "状态" , allowableValues = "1,0", required = true, position = 6) private Long enabled; + @ApiModelProperty(hidden = true) private String createBy; + @ApiModelProperty(hidden = true) private String updateBy; + @ApiModelProperty(hidden = true) private Long pwdResetTime; + @ApiModelProperty(hidden = true) private Long createTime; + @ApiModelProperty(hidden = true) private Long updateTime; + @ApiModelProperty(hidden = true) private String language; private static final long serialVersionUID = 1L; diff --git a/backend/src/main/java/io/dataease/commons/condition/LicStatusCondition.java b/backend/src/main/java/io/dataease/commons/condition/LicStatusCondition.java new file mode 100644 index 0000000000..b9eb7b18dd --- /dev/null +++ b/backend/src/main/java/io/dataease/commons/condition/LicStatusCondition.java @@ -0,0 +1,28 @@ +package io.dataease.commons.condition; + +import io.dataease.commons.license.DefaultLicenseService; +import io.dataease.commons.license.F2CLicenseResponse; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; + + + +public class LicStatusCondition implements Condition { + + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + // BeanDefinitionRegistry registry = conditionContext.getRegistry(); + + DefaultLicenseService defaultLicenseService = conditionContext.getBeanFactory().getBean(DefaultLicenseService.class); + /*if (null == defaultLicenseService) { + registry.registerBeanDefinition(); + }*/ + if (ObjectUtils.isNotEmpty(defaultLicenseService)) { + F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense(); + return F2CLicenseResponse.Status.valid == f2CLicenseResponse.getStatus(); + } + return false; + } +} diff --git a/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java b/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java index 7a58bb54ee..766742073c 100644 --- a/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java +++ b/backend/src/main/java/io/dataease/config/Knife4jConfiguration.java @@ -1,13 +1,10 @@ package io.dataease.config; -import cn.hutool.core.collection.CollectionUtil; import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; +import io.dataease.commons.condition.LicStatusCondition; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpHeaders; +import org.springframework.context.annotation.*; import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; import springfox.documentation.builders.*; import springfox.documentation.oas.annotations.EnableOpenApi; @@ -15,6 +12,8 @@ import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; + +import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @@ -29,6 +28,7 @@ public class Knife4jConfiguration { private String version; + @Autowired public Knife4jConfiguration(OpenApiExtensionResolver openApiExtensionResolver) { this.openApiExtensionResolver = openApiExtensionResolver; @@ -64,6 +64,13 @@ public class Knife4jConfiguration { return defaultApi("系统管理", "io.dataease.controller.sys"); } + @Bean(value = "pluginsApi") + /*@DependsOn(value = "licStatusCondition")*/ + @Conditional(LicStatusCondition.class) + public Docket pluginsApi() { + return defaultApi("插件管理", "io.dataease.plugins.server"); + } + private ApiInfo apiInfo(){ return new ApiInfoBuilder() diff --git a/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java b/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java index 421aaafa25..38ee1745f5 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java @@ -4,14 +4,14 @@ import io.dataease.base.domain.SysDept; import io.dataease.commons.utils.BeanUtils; import io.dataease.controller.ResultHolder; import io.dataease.controller.sys.base.BaseGridRequest; -import io.dataease.controller.sys.request.DeptCreateRequest; +/*import io.dataease.controller.sys.request.DeptCreateRequest; import io.dataease.controller.sys.request.DeptDeleteRequest; -import io.dataease.controller.sys.request.DeptStatusRequest; +import io.dataease.controller.sys.request.DeptStatusRequest;*/ import io.dataease.controller.sys.response.DeptNodeResponse; import io.dataease.controller.sys.response.DeptTreeNode; import io.dataease.service.sys.DeptService; import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +/*import io.swagger.annotations.ApiOperation;*/ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -46,7 +46,6 @@ public class SysDeptController extends ResultHolder { @PostMapping("/search") public List search(@RequestBody BaseGridRequest request){ List nodes = deptService.nodesTreeByCondition(request); - //List nodes = deptService.nodesByPid(pid); List nodeResponses = nodes.stream().map(node -> { DeptNodeResponse deptNodeResponse = BeanUtils.copyBean(new DeptNodeResponse(), node); deptNodeResponse.setHasChildren(node.getSubCount() > 0); @@ -57,14 +56,14 @@ public class SysDeptController extends ResultHolder { return nodeResponses; } - @ApiOperation("查询部门") + /*@ApiOperation("查询部门") @PostMapping("/root") public ResultHolder rootData(){ List root = deptService.nodesByPid(null); return success(root); - } + }*/ - @ApiOperation("新增部门") + /*@ApiOperation("新增部门") @PostMapping("/create") public void create(@RequestBody DeptCreateRequest dept){ deptService.add(dept); @@ -84,7 +83,7 @@ public class SysDeptController extends ResultHolder { @PostMapping("/updateStatus") public void updateStatus(@RequestBody DeptStatusRequest request){ deptService.updateStatus(request); - } + }*/ @PostMapping("/nodesByDeptId/{deptId}") public List nodesByDeptId(@PathVariable("deptId") Long deptId){ diff --git a/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java b/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java index 38ab9ead04..5ba5cca08e 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java @@ -1,30 +1,30 @@ package io.dataease.controller.sys; -import com.github.pagehelper.Page; +/*import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.dataease.base.domain.SysRole; import io.dataease.commons.utils.PageUtils; import io.dataease.commons.utils.Pager; import io.dataease.controller.sys.base.BaseGridRequest; -import io.dataease.controller.sys.request.RoleMenusRequest; +import io.dataease.controller.sys.request.RoleMenusRequest;*/ import io.dataease.controller.sys.response.RoleUserItem; import io.dataease.service.sys.SysRoleService; import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +/*import io.swagger.annotations.ApiOperation;*/ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; import javax.annotation.Resource; import java.util.List; -@ApiIgnore +/*@ApiIgnore @RestController @RequiredArgsConstructor @Api(tags = "系统:角色管理") @RequestMapping("/api/role") -public class SysRoleController { - +public class SysRoleController {*/ + /* @Resource private SysRoleService sysRoleService; @@ -74,4 +74,5 @@ public class SysRoleController { public List all(){ return sysRoleService.allRoles(); } -} + */ +/*}*/ diff --git a/backend/src/main/java/io/dataease/controller/sys/SysUserController.java b/backend/src/main/java/io/dataease/controller/sys/SysUserController.java index 08fa39bd9b..daf98f1796 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysUserController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysUserController.java @@ -12,7 +12,9 @@ import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.request.SysUserCreateRequest; import io.dataease.controller.sys.request.SysUserPwdRequest; import io.dataease.controller.sys.request.SysUserStateRequest; +import io.dataease.controller.sys.response.RoleUserItem; import io.dataease.controller.sys.response.SysUserGridResponse; +import io.dataease.service.sys.SysRoleService; import io.dataease.service.sys.SysUserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -32,6 +34,9 @@ public class SysUserController { @Resource private SysUserService sysUserService; + @Resource + private SysRoleService sysRoleService; + @ApiOperation("查询用户") @PostMapping("/userGrid/{goPage}/{pageSize}") public Pager> userGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody BaseGridRequest request) { @@ -68,26 +73,27 @@ public class SysUserController { sysUserService.updateStatus(request); } - @ApiOperation("用户更新密码") + @ApiOperation("更新当前用户密码") @PostMapping("/updatePwd") public void updatePwd(@RequestBody SysUserPwdRequest request){ sysUserService.updatePwd(request); } - @ApiOperation("管理员更新密码") + @ApiOperation("更新指定用户密码") @PostMapping("/adminUpdatePwd") public void adminUpdatePwd(@RequestBody SysUserPwdRequest request){ sysUserService.adminUpdatePwd(request); } - @ApiOperation("个人信息") + @ApiOperation("当前用户信息") @PostMapping("/personInfo") public CurrentUserDto personInfo() { CurrentUserDto user = AuthUtils.getUser(); return user; } + @ApiIgnore @ApiOperation("更新个人信息") @PostMapping("/updatePersonInfo") public void updatePersonInfo(@RequestBody SysUserCreateRequest request){ @@ -104,4 +110,10 @@ public class SysUserController { } }); } + + @ApiOperation("查询所有角色") + @PostMapping("/all") + public List all(){ + return sysRoleService.allRoles(); + } } diff --git a/backend/src/main/java/io/dataease/controller/sys/base/BaseGridRequest.java b/backend/src/main/java/io/dataease/controller/sys/base/BaseGridRequest.java index 7ad000f0a8..0e645dab29 100644 --- a/backend/src/main/java/io/dataease/controller/sys/base/BaseGridRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/base/BaseGridRequest.java @@ -1,6 +1,7 @@ package io.dataease.controller.sys.base; import io.dataease.base.mapper.ext.query.GridExample; +import io.swagger.annotations.ApiModelProperty; import org.apache.commons.collections.CollectionUtils; import java.io.Serializable; @@ -9,6 +10,7 @@ import java.util.List; public class BaseGridRequest implements Serializable { + @ApiModelProperty("查询条件") private List conditions; public List getConditions() { @@ -27,6 +29,7 @@ public class BaseGridRequest implements Serializable { this.orders = orders; } + @ApiModelProperty("排序描述") private List orders; public GridExample convertExample(){ diff --git a/backend/src/main/java/io/dataease/controller/sys/base/ConditionEntity.java b/backend/src/main/java/io/dataease/controller/sys/base/ConditionEntity.java index 0da0774c41..304cfcf588 100644 --- a/backend/src/main/java/io/dataease/controller/sys/base/ConditionEntity.java +++ b/backend/src/main/java/io/dataease/controller/sys/base/ConditionEntity.java @@ -1,5 +1,6 @@ package io.dataease.controller.sys.base; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -7,10 +8,13 @@ import java.io.Serializable; @Data public class ConditionEntity implements Serializable { + @ApiModelProperty(value = "字段") private String field; + @ApiModelProperty(value = "操作符") private String operator; + @ApiModelProperty(value = "字段值") private Object value; } diff --git a/backend/src/main/java/io/dataease/controller/sys/request/BatchSettingRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/BatchSettingRequest.java index f318e7f1dd..1da1a41e2f 100644 --- a/backend/src/main/java/io/dataease/controller/sys/request/BatchSettingRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/request/BatchSettingRequest.java @@ -1,5 +1,6 @@ package io.dataease.controller.sys.request; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -7,10 +8,10 @@ import java.util.List; @Data public class BatchSettingRequest implements Serializable { - + @ApiModelProperty("消息类型ID集合") private List typeIds; - + @ApiModelProperty("消息类型ID") private Long channelId; - + @ApiModelProperty("订阅状态") private Boolean enable; } diff --git a/backend/src/main/java/io/dataease/controller/sys/request/MsgRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/MsgRequest.java index 30f55e4093..3645287be2 100644 --- a/backend/src/main/java/io/dataease/controller/sys/request/MsgRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/request/MsgRequest.java @@ -1,5 +1,6 @@ package io.dataease.controller.sys.request; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -10,9 +11,12 @@ public class MsgRequest implements Serializable { private static final long serialVersionUID = 1920091635946508658L; + @ApiModelProperty("消息类型ID") private Long type; + @ApiModelProperty("是否订阅") private Boolean status; + @ApiModelProperty("排序描述") private List orders; } diff --git a/backend/src/main/java/io/dataease/controller/sys/request/MsgSettingRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/MsgSettingRequest.java index 68ac29e79c..3e59a31efb 100644 --- a/backend/src/main/java/io/dataease/controller/sys/request/MsgSettingRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/request/MsgSettingRequest.java @@ -1,6 +1,7 @@ package io.dataease.controller.sys.request; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -8,7 +9,9 @@ import java.io.Serializable; @Data public class MsgSettingRequest implements Serializable { + @ApiModelProperty("消息类型ID") private Long typeId; + @ApiModelProperty("消息渠道ID") private Long channelId; } diff --git a/backend/src/main/java/io/dataease/controller/sys/request/SysUserCreateRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/SysUserCreateRequest.java index e5d24f98f4..8f1149ead6 100644 --- a/backend/src/main/java/io/dataease/controller/sys/request/SysUserCreateRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/request/SysUserCreateRequest.java @@ -1,13 +1,16 @@ package io.dataease.controller.sys.request; import io.dataease.base.domain.SysUser; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.util.ArrayList; import java.util.List; @Data public class SysUserCreateRequest extends SysUser { + @ApiModelProperty(value = "角色ID集合", required = true, position = 7) private List roleIds; } diff --git a/backend/src/main/java/io/dataease/controller/sys/request/SysUserPwdRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/SysUserPwdRequest.java index 2627deeede..7f8c2aa3f1 100644 --- a/backend/src/main/java/io/dataease/controller/sys/request/SysUserPwdRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/request/SysUserPwdRequest.java @@ -1,6 +1,7 @@ package io.dataease.controller.sys.request; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -8,9 +9,13 @@ import java.io.Serializable; @Data public class SysUserPwdRequest implements Serializable { + @ApiModelProperty(value = "用户ID", required = true) private Long userId; + @ApiModelProperty(value = "旧密码(密文)", required = true) private String password; + @ApiModelProperty(hidden = true) private String repeatPassword; + @ApiModelProperty(value = "新密码(明文)", required = true) private String newPassword; diff --git a/backend/src/main/java/io/dataease/controller/sys/request/SysUserStateRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/SysUserStateRequest.java index 4a2fd9ef8c..379eb14d47 100644 --- a/backend/src/main/java/io/dataease/controller/sys/request/SysUserStateRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/request/SysUserStateRequest.java @@ -1,5 +1,6 @@ package io.dataease.controller.sys.request; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -7,7 +8,9 @@ import java.io.Serializable; @Data public class SysUserStateRequest implements Serializable { + @ApiModelProperty(value = "用户ID", required = true) private Long userId; + @ApiModelProperty(value = "状态", required = true, allowableValues = "1,0") private Long enabled; } diff --git a/backend/src/main/java/io/dataease/controller/sys/response/SettingTreeNode.java b/backend/src/main/java/io/dataease/controller/sys/response/SettingTreeNode.java index bbbd574c00..74d3f6a718 100644 --- a/backend/src/main/java/io/dataease/controller/sys/response/SettingTreeNode.java +++ b/backend/src/main/java/io/dataease/controller/sys/response/SettingTreeNode.java @@ -1,6 +1,7 @@ package io.dataease.controller.sys.response; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -11,9 +12,12 @@ public class SettingTreeNode implements Serializable { private static final long serialVersionUID = -2416283978185545199L; + @ApiModelProperty("消息类型ID") private Long id; + @ApiModelProperty("消息类型名称") private String name; + @ApiModelProperty("子节点") private List children; } diff --git a/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java b/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java index fd75f0d08a..225542842f 100644 --- a/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java @@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + import javax.servlet.http.HttpServletResponse; import java.io.BufferedInputStream; import java.io.IOException; @@ -17,6 +19,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +@ApiIgnore @RestController @RequestMapping("/api/pluginCommon") public class PluginCommonServer { diff --git a/backend/src/main/java/io/dataease/plugins/server/XDeptServer.java b/backend/src/main/java/io/dataease/plugins/server/XDeptServer.java index 4a6c0bb6f1..e58fe09995 100644 --- a/backend/src/main/java/io/dataease/plugins/server/XDeptServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/XDeptServer.java @@ -11,14 +11,19 @@ import io.dataease.plugins.xpack.dept.dto.request.XpackMoveDept; import io.dataease.plugins.xpack.dept.dto.response.XpackDeptTreeNode; import io.dataease.plugins.xpack.dept.dto.response.XpackSysDept; import io.dataease.plugins.xpack.dept.service.DeptXpackService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + import java.util.List; import java.util.stream.Collectors; - +@Api(tags = "xpack:部门管理") @RequestMapping("/plugin/dept") @RestController public class XDeptServer { + @ApiOperation("查询子节点") @PostMapping("/childNodes/{pid}") public List childNodes(@PathVariable("pid") Long pid){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); @@ -33,6 +38,7 @@ public class XDeptServer { return nodeResponses; } + @ApiOperation("搜索组织树") @PostMapping("/search") public List search(@RequestBody XpackGridRequest request){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); @@ -47,6 +53,7 @@ public class XDeptServer { return nodeResponses; } + @ApiIgnore @PostMapping("/root") public List rootData(){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); @@ -54,18 +61,21 @@ public class XDeptServer { return nodes; } + @ApiOperation("创建") @PostMapping("/create") public int create(@RequestBody XpackCreateDept dept){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); return deptService.add(dept); } + @ApiOperation("删除") @PostMapping("/delete") public void delete(@RequestBody List requests){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); deptService.batchDelete(requests); } + @ApiOperation("更新") @PostMapping("/update") public int update(@RequestBody XpackCreateDept dept){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); @@ -73,12 +83,15 @@ public class XDeptServer { } + @ApiIgnore + @ApiOperation("删除") @PostMapping("/nodesByDeptId/{deptId}") public List nodesByDeptId(@PathVariable("deptId") Long deptId){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); return deptService.searchTree(deptId); } + @ApiOperation("移动") @PostMapping("/move") public void move(@RequestBody XpackMoveDept xpackMoveDept){ DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class); diff --git a/backend/src/main/java/io/dataease/plugins/server/XRoleServer.java b/backend/src/main/java/io/dataease/plugins/server/XRoleServer.java index 97905e18c5..b9493a0e62 100644 --- a/backend/src/main/java/io/dataease/plugins/server/XRoleServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/XRoleServer.java @@ -10,14 +10,19 @@ import io.dataease.plugins.config.SpringContextUtil; import io.dataease.plugins.xpack.role.dto.response.XpackRoleDto; import io.dataease.plugins.xpack.role.dto.response.XpackRoleItemDto; import io.dataease.plugins.xpack.role.service.RoleXpackService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; import java.util.List; +@Api(tags = "xpack:角色管理") @RequestMapping("/plugin/role") @RestController public class XRoleServer { + @ApiOperation("新增角色") @PostMapping("/create") public void create(@RequestBody XpackRoleDto role){ RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class); @@ -25,6 +30,7 @@ public class XRoleServer { } + @ApiOperation("删除角色") @PostMapping("/delete/{roleId}") public void delete(@PathVariable("roleId") Long roleId){ RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class); @@ -32,12 +38,14 @@ public class XRoleServer { } + @ApiOperation("更新角色") @PostMapping("/update") public void update(@RequestBody XpackRoleDto role){ RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class); roleXpackService.update(role); } + @ApiOperation("分页查询") @PostMapping("/roleGrid/{goPage}/{pageSize}") public Pager> roleGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody XpackGridRequest request) { RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class); @@ -46,6 +54,7 @@ public class XRoleServer { return listPager; } + @ApiIgnore @PostMapping("/all") public List all() { RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class); diff --git a/backend/src/main/java/io/dataease/service/sys/SysRoleService.java b/backend/src/main/java/io/dataease/service/sys/SysRoleService.java index a27649b558..558c0b7f96 100644 --- a/backend/src/main/java/io/dataease/service/sys/SysRoleService.java +++ b/backend/src/main/java/io/dataease/service/sys/SysRoleService.java @@ -1,38 +1,38 @@ package io.dataease.service.sys; -import io.dataease.base.domain.SysRole; +/*import io.dataease.base.domain.SysRole; import io.dataease.base.domain.SysUsersRolesExample; import io.dataease.base.mapper.SysRoleMapper; -import io.dataease.base.mapper.SysUsersRolesMapper; +import io.dataease.base.mapper.SysUsersRolesMapper;*/ import io.dataease.base.mapper.ext.ExtSysRoleMapper; -import io.dataease.controller.sys.base.BaseGridRequest; -import io.dataease.controller.sys.request.RoleMenusRequest; +/*import io.dataease.controller.sys.base.BaseGridRequest; +import io.dataease.controller.sys.request.RoleMenusRequest;*/ import io.dataease.controller.sys.response.RoleUserItem; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; +/*import org.springframework.transaction.annotation.Transactional;*/ import javax.annotation.Resource; -import java.util.HashMap; +/*import java.util.HashMap;*/ import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; +/*import java.util.Map; +import java.util.stream.Collectors;*/ @Service public class SysRoleService { - @Resource - private SysRoleMapper mapper; + /*@Resource + private SysRoleMapper mapper;*/ @Resource private ExtSysRoleMapper extSysRoleMapper; - @Resource - private SysUsersRolesMapper sysUsersRolesMapper; + /*@Resource + private SysUsersRolesMapper sysUsersRolesMapper;*/ - public int add(SysRole role){ + /*public int add(SysRole role){ Long now = System.currentTimeMillis(); role.setCreateTime(now); role.setUpdateTime(now); @@ -77,7 +77,7 @@ public class SysRoleService { return map; }).collect(Collectors.toList()); return extSysRoleMapper.batchInsertRoleMenu(maps); - } + }*/ public List allRoles(){ return extSysRoleMapper.queryAll(); diff --git a/frontend/src/api/system/dept.js b/frontend/src/api/system/dept.js index a371ee9998..b35bb78e67 100644 --- a/frontend/src/api/system/dept.js +++ b/frontend/src/api/system/dept.js @@ -17,29 +17,29 @@ export function loadTable(data) { }) } -export function addDept(data) { - return request({ - url: '/api/dept/create', - method: 'post', - data - }) -} +// export function addDept(data) { +// return request({ +// url: '/api/dept/create', +// method: 'post', +// data +// }) +// } -export function delDept(ids) { - return request({ - url: '/api/dept/delete', - method: 'post', - data: ids - }) -} +// export function delDept(ids) { +// return request({ +// url: '/api/dept/delete', +// method: 'post', +// data: ids +// }) +// } -export function editDept(data) { - return request({ - url: '/api/dept/update', - method: 'post', - data - }) -} +// export function editDept(data) { +// return request({ +// url: '/api/dept/update', +// method: 'post', +// data +// }) +// } export function treeByDeptId(deptId) { return request({ @@ -48,4 +48,4 @@ export function treeByDeptId(deptId) { }) } -export default { addDept, delDept, editDept, getDeptTree, loadTable, treeByDeptId } +// export default { addDept, delDept, editDept, getDeptTree, loadTable, treeByDeptId } diff --git a/frontend/src/api/system/role.js b/frontend/src/api/system/role.js index 07be60da4e..dd7326f889 100644 --- a/frontend/src/api/system/role.js +++ b/frontend/src/api/system/role.js @@ -1,57 +1,57 @@ -import request from '@/utils/request' +// import request from '@/utils/request' -export function allRoles() { - return request({ - url: '/api/role/all', - method: 'post', - loading: true - }) -} +// export function allRoles() { +// return request({ +// url: '/api/user/all', +// method: 'post', +// loading: true +// }) +// } -export function roleGrid(pageIndex, pageSize, data) { - return request({ - url: '/api/role/roleGrid/' + pageIndex + '/' + pageSize, - method: 'post', - data, - loading: true - }) -} +// export function roleGrid(pageIndex, pageSize, data) { +// return request({ +// url: '/api/role/roleGrid/' + pageIndex + '/' + pageSize, +// method: 'post', +// data, +// loading: true +// }) +// } -export function delRole(pid) { - return request({ - url: '/api/role/delete/' + pid, - method: 'post' - }) -} +// export function delRole(pid) { +// return request({ +// url: '/api/role/delete/' + pid, +// method: 'post' +// }) +// } -export function addRole(data) { - return request({ - url: '/api/role/create', - method: 'post', - data - }) -} +// export function addRole(data) { +// return request({ +// url: '/api/role/create', +// method: 'post', +// data +// }) +// } -export function editRole(data) { - return request({ - url: '/api/role/update', - method: 'post', - data - }) -} +// export function editRole(data) { +// return request({ +// url: '/api/role/update', +// method: 'post', +// data +// }) +// } -export function addRoleMenus(data) { - return request({ - url: '/api/role/saveRolesMenus', - method: 'post', - data - }) -} +// export function addRoleMenus(data) { +// return request({ +// url: '/api/role/saveRolesMenus', +// method: 'post', +// data +// }) +// } -export function menuIds(roleId) { - return request({ - url: '/api/role/menuIds/' + roleId, - method: 'post' - }) -} -export default { addRole, editRole, delRole, roleGrid, allRoles, addRoleMenus, menuIds } +// export function menuIds(roleId) { +// return request({ +// url: '/api/role/menuIds/' + roleId, +// method: 'post' +// }) +// } +// export default { addRole, editRole, delRole, roleGrid, allRoles, addRoleMenus, menuIds } diff --git a/frontend/src/api/system/user.js b/frontend/src/api/system/user.js index fc23d2b260..f3db990e04 100644 --- a/frontend/src/api/system/user.js +++ b/frontend/src/api/system/user.js @@ -81,4 +81,12 @@ export const updatePersonPwd = (data) => { }) } -export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd } +export const allRoles = () => { + return request({ + url: '/api/user/all', + method: 'post', + loading: true + }) +} + +export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd, allRoles } diff --git a/frontend/src/views/system/dept/form.vue b/frontend/src/views/system/dept/form.vue deleted file mode 100644 index 8b090ed13b..0000000000 --- a/frontend/src/views/system/dept/form.vue +++ /dev/null @@ -1,161 +0,0 @@ - - - diff --git a/frontend/src/views/system/dept/index.vue b/frontend/src/views/system/dept/index.vue deleted file mode 100644 index d4ea1402af..0000000000 --- a/frontend/src/views/system/dept/index.vue +++ /dev/null @@ -1,521 +0,0 @@ - - - - - diff --git a/frontend/src/views/system/role/form.vue b/frontend/src/views/system/role/form.vue deleted file mode 100644 index 7a9930f673..0000000000 --- a/frontend/src/views/system/role/form.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - diff --git a/frontend/src/views/system/role/index.vue b/frontend/src/views/system/role/index.vue deleted file mode 100644 index 27a2399d88..0000000000 --- a/frontend/src/views/system/role/index.vue +++ /dev/null @@ -1,276 +0,0 @@ - - - - diff --git a/frontend/src/views/system/user/form.vue b/frontend/src/views/system/user/form.vue index 25b1887457..72d71aec53 100644 --- a/frontend/src/views/system/user/form.vue +++ b/frontend/src/views/system/user/form.vue @@ -72,16 +72,11 @@ + + diff --git a/frontend/src/styles/deicon/demo.css b/frontend/src/styles/deicon/demo.css index b7af3aa35d..a67054a0a0 100644 --- a/frontend/src/styles/deicon/demo.css +++ b/frontend/src/styles/deicon/demo.css @@ -3,9 +3,9 @@ font-family: "iconfont logo"; src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), - url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), - url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), - url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); } .logo { @@ -215,35 +215,35 @@ margin: 1em 0; } -.markdown > p, -.markdown > blockquote, -.markdown > .highlight, -.markdown > ol, -.markdown > ul { +.markdown>p, +.markdown>blockquote, +.markdown>.highlight, +.markdown>ol, +.markdown>ul { width: 80%; } -.markdown ul > li { +.markdown ul>li { list-style: circle; } -.markdown > ul li, -.markdown blockquote ul > li { +.markdown>ul li, +.markdown blockquote ul>li { margin-left: 20px; padding-left: 4px; } -.markdown > ul li p, -.markdown > ol li p { +.markdown>ul li p, +.markdown>ol li p { margin: 0.6em 0; } -.markdown ol > li { +.markdown ol>li { list-style: decimal; } -.markdown > ol li, -.markdown blockquote ol > li { +.markdown>ol li, +.markdown blockquote ol>li { margin-left: 20px; padding-left: 4px; } @@ -260,7 +260,7 @@ font-weight: 600; } -.markdown > table { +.markdown>table { border-collapse: collapse; border-spacing: 0px; empty-cells: show; @@ -269,20 +269,20 @@ margin-bottom: 24px; } -.markdown > table th { +.markdown>table th { white-space: nowrap; color: #333; font-weight: 600; } -.markdown > table th, -.markdown > table td { +.markdown>table th, +.markdown>table td { border: 1px solid #e9e9e9; padding: 8px 16px; text-align: left; } -.markdown > table th { +.markdown>table th { background: #F7F7F7; } @@ -318,8 +318,8 @@ display: inline-block; } -.markdown > br, -.markdown > p > br { +.markdown>br, +.markdown>p>br { clear: both; } @@ -453,13 +453,13 @@ pre[class*="language-"] { overflow: auto; } -:not(pre) > code[class*="language-"], +:not(pre)>code[class*="language-"], pre[class*="language-"] { background: #f5f2f0; } /* Inline code */ -:not(pre) > code[class*="language-"] { +:not(pre)>code[class*="language-"] { padding: .1em; border-radius: .3em; white-space: normal; diff --git a/frontend/src/styles/deicon/demo_index.html b/frontend/src/styles/deicon/demo_index.html index e01657bfe5..e997334f0c 100644 --- a/frontend/src/styles/deicon/demo_index.html +++ b/frontend/src/styles/deicon/demo_index.html @@ -54,6 +54,48 @@
    +
  • + +
    线性图标-取消下钻
    +
    &#xe973;
    +
  • + +
  • + +
    线性图标-取消下钻
    +
    &#xe6ed;
    +
  • + +
  • + +
    联动
    +
    &#xe6f7;
    +
  • + +
  • + +
    下钻
    +
    &#xe613;
    +
  • + +
  • + +
    上钻
    +
    &#xe61f;
    +
  • + +
  • + +
    取消联动
    +
    &#xe637;
    +
  • + +
  • + +
    edit-2
    +
    &#xe604;
    +
  • +
  • edit-2
    @@ -318,9 +360,9 @@
    @font-face {
       font-family: 'iconfont';
    -  src: url('iconfont.woff2?t=1627282547459') format('woff2'),
    -       url('iconfont.woff?t=1627282547459') format('woff'),
    -       url('iconfont.ttf?t=1627282547459') format('truetype');
    +  src: url('iconfont.woff2?t=1628652979833') format('woff2'),
    +       url('iconfont.woff?t=1628652979833') format('woff'),
    +       url('iconfont.ttf?t=1628652979833') format('truetype');
     }
     

    第二步:定义使用 iconfont 的样式

    @@ -346,6 +388,69 @@
      +
    • + +
      + 线性图标-取消下钻 +
      +
      .icon-quxiaoshangzuan +
      +
    • + +
    • + +
      + 线性图标-取消下钻 +
      +
      .icon-quxiaoxiazuan +
      +
    • + +
    • + +
      + 联动 +
      +
      .icon-linkage +
      +
    • + +
    • + +
      + 下钻 +
      +
      .icon-xiazuan +
      +
    • + +
    • + +
      + 上钻 +
      +
      .icon-shangzuan +
      +
    • + +
    • + +
      + 取消联动 +
      +
      .icon-quxiaoliandong +
      +
    • + +
    • + +
      + edit-2 +
      +
      .icon-edit-outline +
      +
    • +
    • @@ -742,6 +847,62 @@
        +
      • + +
        线性图标-取消下钻
        +
        #icon-quxiaoshangzuan
        +
      • + +
      • + +
        线性图标-取消下钻
        +
        #icon-quxiaoxiazuan
        +
      • + +
      • + +
        联动
        +
        #icon-linkage
        +
      • + +
      • + +
        下钻
        +
        #icon-xiazuan
        +
      • + +
      • + +
        上钻
        +
        #icon-shangzuan
        +
      • + +
      • + +
        取消联动
        +
        #icon-quxiaoliandong
        +
      • + +
      • + +
        edit-2
        +
        #icon-edit-outline
        +
      • +
      • RV6qxl7L13?M600#=-EPuy?$Z^(J@GZOM`0f!*Tn9 zsbjR;3^`h0^$MkMt?Tw}A2bM(&tdjDPM>Iq2md%q2qYY5j7Tuf!V<1=7D+<;mu?K& z2Y<{O7U#nZc5ksPVQ+#;NP2%84K=$$xISdFX>DOIkFniFTF2?JcVicaZOY8&IJVQi zfRPTG4LuU6Ky=sPuS|29fcfq76W7GT)k5Yt-ec$zi<^-AI#`qT z$p>5`lz$*w@gehAFU#UY{%1KH`dcWP%_lU9Rcn$T7fl~%w91d^=AH*%)%S30DrJ&@ z@5l!Uc4sK1D6F*;hweb~;eMU0^mgvfApM{J()O8XAQ=q?QkwS=vL{Gvf-VOHI(A4K zWfg-9#*WwIJ#7`>W!X2tu6Nh^ZREv=cPS&^Usvto%7X{YD1OZ2%8NCP;&@3Fj`ru_ zgI(!q&K>*G;|C<^;SHihiVOl9ZHt07qUEzkke5S0g9q#sPxx?6x~&c}whyb+?QBk* z9Zx57LtjXoK&0lB3z=|5;tD($N)<3{LudK}~sk1-wMfC?#*rIK0C&pMg z4}hNjOt8_mfd%U>MZ>CpzMLJv|M)fgwSlkB`}+&yQ0a^ ztS9Ds)R~%FHsDjTR4i|TNYeF7OEXGsQZGV4H0Cn?gqD*N+f3&`Y=%gmlRG;)7iDuf z)TZBEvH3Cj{Hm;xudft1esh{0=nFH4`Anb-HKSe7{}78{K`b6YsvQNeo1kuXlTY%^ zNrwPRxNeJuUcwMt+|7&{>C#+MbI zY+C+RxN9Q497(L+*NT+WCz=xX)oa~Xomh@cq?@GHSm3WaEi^k4Y;i9@?6fSCuu56r zwglS|3oSDXH7RUsVPNEzwnCVcMFW%WxDvSI9|>s##>&AT=|@CNXt)m}wV@KX5r_Z& zfO^KNnz&+pL4m$Fu4Yx`fyNp`Wm;OLp{DTwc$!x)Y8W2w!lRf}{HJ4|Or4)=ix+*$ zf;yFceK&7ykajn{%kSGRjgsh>6>LxQ)?&@wzJZVsdt&L{(nKqXm0~=Ge=0iPRNA?i zJuxKY(q$FD)`W=}<({8a9VlzQJN@ov^zHHgIS{)+8$R2xw{3Of+imraXQxlh86MYf zZG2~OKi{P-4)2kCOtK-)s6_)von_WmKe_RZrSI{q^p#14Pa0-eV~ER-j?S+Z?r=4p zIW|qTQ)-g#G|@K&7BbuY+P7_+;cp-*_-U%}9Aogd;DY z1rv_@2N-0W6H-s(6w=^7W81cNzc0R?*^X3-b=PxH1MNVpB$xA31ZZy7rb$afHjdD= zArn`Axg%G;Q=FI6?(9jZ+`Zn9nm9FK(pNvf&t@EgI&S{^ugxtnCe6L~6G&f&M_!+J zD0HbbahJ{s`IjwT^lr_RC&7Q;p7O?Z!bNXgUiY`>Xlq&SX?j{z8sl1Kn>_>1Y_;cJ zL&V7S+|x7@2S%7A0coTHY7i1g?$N(|dg-uWhJeQiPo2qPiwuu)WiP0)gURpfv_TwT= z$-zmEzbNZX#y)$b*{BZNoX-q+%8Z_p+b6x5O zl-)6FCVvVjfiXkNhfXZFuCSh1I<$i0umEswc5P4XrwyOgeRi~A#d?k+Bao<^*z{$S z5duw$d@*_;5=eNXvyaC*VnIUAZ>Iib6_Y1Fd^lyYHe}{hh(V+pK9_X@JekjtA?{EE?jVvh9x+aVa+q1H=+LR$tzapj zb>eYu1mdQWp2*1&5tAbuPrR0o6wV#d+OHVRiUii}%EY9PD#E1KU_$$We(wAHO2K~0Yl=8P9eL~iLQ?d2((7?b;%|XH$vxCQT z63l;cw){M_xl@nVGcz}JS=&U{4<9xyLXQ0h6gJNZCod{AbB7bxbMynqhTkOeTx=1Vjc{T^o^+P(j^;uag%+9b?w^XVmPm0Vtv3o z-uI{Od-N0k`uZ3B2D*OXQ$tfzW!TW9+F zn3YZc2Ua6C&bYW$Zp!-KBKOFN*#UupW8zpiW{x2NOIAGbU#^Wio&);VKaQcS=~9nT zD)2}_3=b0o;BrT^61&rNN}UeqD*x+jx6jB6wT32Vr%cjZl9Y&x4dc@-C$r1wrSzOg ztFCqzvy53HE0PzRO`A3ta^7WwmFdNc6kY0d_IVvC-AMCz+j4$a#A@^Th0$PRjszm^ z#wm<3H0n$xdW8sE846v&PO=#s(OAStA1MtKoJ=S$1Oqoh7x-;!V+V4^b5xwRjsRCV zmG2ap8lF*|T%E2R4ql)|Vp`h(-(GPT>ZuSXMCn zVK)ZmnJ&e*KE`gw%0D7zMVDx32vcXn^fBvY!XLdq2wB;I=7Aj7&1)PHE@52>-@|REV5}nq*sgf$ z^Wx$5bfe?%(w_k(FWu^w(u*ep`ixUf<79|&l-W3C|9EA8$?p9ttMkY2ah;dRnnAP^ zb)>>yytq?mGDJ6uEu2I<51r+}?w|$O2=*xc8Y@8GJgN{8o4iIV(8>;ssL;rsymR@j zwh>5*Ij7##d8M<%Qf3V-LQ1e2IyYNfIj5V|a(`cn&wpT(z!TiB?GN@e@dty4(vgEn z6Eu)dA9_7Y!`6(y9_phTpPKOFWPuUE@=&9|4YckVg6SD2aIS>FPp}{fz~ct~b~x5b zvqQ!j>*~^*6SvsHGZ?GQmVV)Id>{higKYqGKQKzwx}2z}X)}Z+mLob^Ej8X7mU?Q$ z#iic6{owq81tbvuBTh)TOh;cFC`<#S?)=uB>5lt|rG2K2`$X%W_B8z1Py3m6RatS7 z&1R04v7g0#77w*UOOU!N&CPPhy?>_NsjWG(%Qb3h;!Exvh#z3>JQ{zLR5)@ZIX>=b z{Lc6tXz0!z219Eyc%)&d-dYU^=2rzdf)1`zr2Wi#Ai}^7(V%kjr^*o##@Q+AKB&=* zrO_iryTK@OH-4>HTzn1RU807kiX{_ZkxUhRG5yP3WQy&V)yuqZy|Q+hXXic`=&KHV z5vc0)@BHh#7cDO$UbtSUPsvr;hq6Qhp6s@IGBOc;g&amNkoo}#ea#=HY&&`zIg6er zULoKN`lbyX6n6=A^ag}qDMN>m@<$4f{IcAmuqrmO=iH>YU5Z{%evOtFmSS&u_S^#4 zE6FwN4jD&6*lTR?6hva@173+^3iC+}3!v)Pj=ieA)vD^(swp3= znMnE`)QpeYSY6|&0ShZ`F$%613zTDNWJ<8Mg7F^MNBH>FsaG#w&Al4b9Lexy&QVwN zj=GS+Fo{}vU4qB9?Did8m%5P(!7Tug$5CDmGCLN3MmzoFHr3k%5M_6&beRO1`8n(AP_qI7&duWAUsRY=B(j&6}1n_I!`X=+pY%F+G1{3-*mU3ROX>R)IH3WRXxWRZoR&HU0-n`#2QY1 zCT!60i_NtB%H}$LqnQ1NEgAX8mUaAR3-1JzUfn5}%!PI zsbe74@-nT+wH`7ZWhyvm#j{zuB4;X1mmeHXszabKxcv>5g*?Pi3gu7<)lmC5$9>i$ z-!}Y1g-*BE9}Gw1$#gbfELZEzcDFwqPv@)a8~c&a5?}8Kl3!Eui<>P{N06B&3(B+$ z&N8T?S56D;33e}S|Al`@o~4p#3|xK+jcqH`-sd~SFM0)d8V@`f56#+ z27xD+>j1pci>A`MTvub`{a%SrF*x(#FBXGU9wE zBkj6F>OE-<7w3I0jpR=mcYIOEuv9#2p`6PpSHxQrU?-_%X_8NSvT{=pJ<0000u C<27ag From 99aac19d46c4c755537a773dab0c0d53bd64b2a1 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 11 Aug 2021 14:58:29 +0800 Subject: [PATCH 22/30] =?UTF-8?q?feat:=20=E5=8C=85=E8=A3=85api=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/dataease/auth/config/ShiroConfig.java | 1 + .../io/dataease/auth/filter/F2CDocFilter.java | 26 +++++++++++++++++++ .../auth/service/impl/ShiroServiceImpl.java | 3 ++- .../dataease/controller/IndexController.java | 21 +++++++++++++++ frontend/public/nolic.html | 13 ++++++++++ frontend/src/nolic/Nolic.vue | 16 ++++++++++++ frontend/src/nolic/nolic-router.js | 17 ++++++++++++ frontend/src/nolic/nolic.js | 26 +++++++++++++++++++ frontend/src/views/nolic/index.vue | 9 +++++++ frontend/vue.config.js | 5 ++++ 10 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/io/dataease/auth/filter/F2CDocFilter.java create mode 100644 frontend/public/nolic.html create mode 100644 frontend/src/nolic/Nolic.vue create mode 100644 frontend/src/nolic/nolic-router.js create mode 100644 frontend/src/nolic/nolic.js create mode 100644 frontend/src/views/nolic/index.vue diff --git a/backend/src/main/java/io/dataease/auth/config/ShiroConfig.java b/backend/src/main/java/io/dataease/auth/config/ShiroConfig.java index a3d6e190de..764aefb3f3 100644 --- a/backend/src/main/java/io/dataease/auth/config/ShiroConfig.java +++ b/backend/src/main/java/io/dataease/auth/config/ShiroConfig.java @@ -51,6 +51,7 @@ public class ShiroConfig { filterMap.put("jwt", new JWTFilter()); filterMap.put("logout", new F2CLogoutFilter()); filterMap.put("link", new F2CLinkFilter()); + filterMap.put("doc", new F2CDocFilter()); factoryBean.setSecurityManager(securityManager); factoryBean.setLoginUrl("/login"); factoryBean.setUnauthorizedUrl("/login"); diff --git a/backend/src/main/java/io/dataease/auth/filter/F2CDocFilter.java b/backend/src/main/java/io/dataease/auth/filter/F2CDocFilter.java new file mode 100644 index 0000000000..022180c4b3 --- /dev/null +++ b/backend/src/main/java/io/dataease/auth/filter/F2CDocFilter.java @@ -0,0 +1,26 @@ +package io.dataease.auth.filter; + +import org.apache.shiro.web.filter.authc.AnonymousFilter; + +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +public class F2CDocFilter extends AnonymousFilter { + + @Override + protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) { + HttpServletRequest req = (HttpServletRequest) request; + String path = "/deApi"; + try { + req.getRequestDispatcher(path).forward(req, response); + } catch (ServletException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return true; + } +} diff --git a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java index a6cdf4ec83..c12a511e21 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java @@ -20,7 +20,8 @@ public class ShiroServiceImpl implements ShiroService { // 配置过滤:不会被拦截的链接 -> 放行 start ---------------------------------------------------------- // 放行Swagger2页面,需要放行这些 - filterChainDefinitionMap.put("/doc.html",ANON); + filterChainDefinitionMap.put("/doc.html**","doc"); + filterChainDefinitionMap.put("/deApi**",ANON); filterChainDefinitionMap.put("/swagger-ui.html",ANON); filterChainDefinitionMap.put("/swagger-ui/**",ANON); filterChainDefinitionMap.put("/swagger/**",ANON); diff --git a/backend/src/main/java/io/dataease/controller/IndexController.java b/backend/src/main/java/io/dataease/controller/IndexController.java index 7a48d8f564..19c83d007f 100644 --- a/backend/src/main/java/io/dataease/controller/IndexController.java +++ b/backend/src/main/java/io/dataease/controller/IndexController.java @@ -1,13 +1,21 @@ package io.dataease.controller; +import io.dataease.commons.license.DefaultLicenseService; +import io.dataease.commons.license.F2CLicenseResponse; +import io.dataease.exception.DataEaseException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import javax.annotation.Resource; + @Controller @RequestMapping public class IndexController { + @Resource + private DefaultLicenseService defaultLicenseService; + @GetMapping(value = "/") public String index() { return "index.html"; @@ -28,5 +36,18 @@ public class IndexController { return "test.html"; } + @GetMapping("/deApi") + public String deApi() { + F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense(); + switch (f2CLicenseResponse.getStatus()) { + case valid: + return "doc.html"; + default: + // DataEaseException.throwException("Invalid License."); + return "nolic.html"; + } + // return "index.html"; + } + } diff --git a/frontend/public/nolic.html b/frontend/public/nolic.html new file mode 100644 index 0000000000..89f3ecbc52 --- /dev/null +++ b/frontend/public/nolic.html @@ -0,0 +1,13 @@ + + + + + + + + DataEase + + +
        + + diff --git a/frontend/src/nolic/Nolic.vue b/frontend/src/nolic/Nolic.vue new file mode 100644 index 0000000000..3824ab98da --- /dev/null +++ b/frontend/src/nolic/Nolic.vue @@ -0,0 +1,16 @@ + + + diff --git a/frontend/src/nolic/nolic-router.js b/frontend/src/nolic/nolic-router.js new file mode 100644 index 0000000000..4730048019 --- /dev/null +++ b/frontend/src/nolic/nolic-router.js @@ -0,0 +1,17 @@ +import Vue from 'vue' +import Router from 'vue-router' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'home', + component: () => import('../views/nolic/index.vue'), + meta: { + title: '首页' + } + } + ] +}) diff --git a/frontend/src/nolic/nolic.js b/frontend/src/nolic/nolic.js new file mode 100644 index 0000000000..f3110de5ae --- /dev/null +++ b/frontend/src/nolic/nolic.js @@ -0,0 +1,26 @@ +import Vue from 'vue' +import Nolic from './Nolic.vue' +import router from './nolic-router' +import store from '../store' +import '@/styles/index.scss' // global css +import i18n from '../lang' // internationalization +import ElementUI from 'element-ui' +import '@/components/canvas/custom-component' // 注册自定义组件 +import widgets from '@/components/widget' +import * as echarts from 'echarts' +import UmyUi from 'umy-ui' + +Vue.use(UmyUi) +Vue.prototype.$echarts = echarts +Vue.config.productionTip = false +Vue.use(widgets) +Vue.use(ElementUI, { + + i18n: (key, value) => i18n.t(key, value) +}) +new Vue({ + router, + store, + i18n, + render: h => h(Nolic) +}).$mount('#nolic') diff --git a/frontend/src/views/nolic/index.vue b/frontend/src/views/nolic/index.vue new file mode 100644 index 0000000000..0ce8caa15f --- /dev/null +++ b/frontend/src/views/nolic/index.vue @@ -0,0 +1,9 @@ + + + diff --git a/frontend/vue.config.js b/frontend/vue.config.js index 1fbffca388..8005c12a4a 100644 --- a/frontend/vue.config.js +++ b/frontend/vue.config.js @@ -40,6 +40,11 @@ module.exports = { entry: 'src/link/link.js', template: 'public/link.html', filename: 'link.html' + }, + nolic: { + entry: 'src/nolic/nolic.js', + template: 'public/nolic.html', + filename: 'nolic.html' } }, configureWebpack: { From 5d2340975cf83bfb2fcac0b60bb52639fb2eb0c3 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 11 Aug 2021 15:52:49 +0800 Subject: [PATCH 23/30] =?UTF-8?q?fix:=20=E6=95=B0=E6=8D=AE=E9=9B=86?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E8=8E=B7=E5=8F=96=E6=8E=A5=E5=8F=97=E4=BA=BA?= =?UTF-8?q?=E6=9D=83=E9=99=90=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/dataease/auth/service/impl/ExtAuthServiceImpl.java | 6 ++++-- .../java/io/dataease/base/mapper/ext/ExtAuthMapper.java | 3 ++- .../java/io/dataease/base/mapper/ext/ExtAuthMapper.xml | 7 +++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/io/dataease/auth/service/impl/ExtAuthServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/ExtAuthServiceImpl.java index 07eccc92c1..e141cc1b62 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/ExtAuthServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/ExtAuthServiceImpl.java @@ -43,9 +43,11 @@ public class ExtAuthServiceImpl implements ExtAuthService { @Override public AuthURD resourceTarget(String resourceId) { AuthURD authURD = new AuthURD(); - SysAuthExample example = new SysAuthExample(); + /*SysAuthExample example = new SysAuthExample(); example.createCriteria().andAuthSourceEqualTo(resourceId); - List sysAuths = sysAuthMapper.selectByExample(example); + List sysAuths = sysAuthMapper.selectByExample(example);*/ + List sysAuths = extAuthMapper.queryByResource(resourceId); + Map> authMap = sysAuths.stream().collect(Collectors.groupingBy(SysAuth::getAuthTargetType)); if (!CollectionUtils.isEmpty(authMap.get("user"))) { authURD.setUserIds(authMap.get("user").stream().map(item -> Long.parseLong(item.getAuthTarget())).collect(Collectors.toList())); diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.java index fe7d57a75b..9e987aa586 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.java @@ -1,6 +1,7 @@ package io.dataease.base.mapper.ext; +import io.dataease.base.domain.SysAuth; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -12,6 +13,6 @@ public interface ExtAuthMapper { List queryUserIdWithDeptIds(@Param("deptIds") List deptIds); - + List queryByResource(@Param("resourceId") String resourceId); // Set queryUserIdWithRD(@Param("roleIds") List roleIds, @Param("deptIds") List deptIds); } diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.xml index 991709ff3b..8e961576f2 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtAuthMapper.xml @@ -23,5 +23,12 @@ + + + From 85c744f6798bb3d88979a9db77797e9ac29348ce Mon Sep 17 00:00:00 2001 From: junjie Date: Wed, 11 Aug 2021 17:01:51 +0800 Subject: [PATCH 24/30] =?UTF-8?q?feat:=20=E8=A7=86=E5=9B=BE=E4=B8=8A?= =?UTF-8?q?=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/dataease/dto/chart/ChartViewDTO.java | 4 ++ .../service/chart/ChartViewService.java | 4 ++ frontend/src/views/chart/view/ChartEdit.vue | 15 +++++- frontend/src/views/chart/view/DrillPath.vue | 47 +++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 frontend/src/views/chart/view/DrillPath.vue diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java index 81629da981..a431983eb6 100644 --- a/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java +++ b/backend/src/main/java/io/dataease/dto/chart/ChartViewDTO.java @@ -1,9 +1,11 @@ package io.dataease.dto.chart; import io.dataease.base.domain.ChartViewWithBLOBs; +import io.dataease.controller.request.chart.ChartExtFilterRequest; import lombok.Getter; import lombok.Setter; +import java.util.List; import java.util.Map; /** @@ -22,4 +24,6 @@ public class ChartViewDTO extends ChartViewWithBLOBs { private String sql; private boolean drill; + + private List drillFilters; } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index caeb64d58c..ef86ad47e6 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -256,6 +256,7 @@ public class ChartViewService { } // 下钻 + List drillFilters = new ArrayList<>(); boolean isDrill = false; List drillRequest = requestList.getDrill(); if (CollectionUtils.isNotEmpty(drillRequest) && (drill.size() > drillRequest.size())) { @@ -279,6 +280,8 @@ public class ChartViewService { drillFilter.setDatasetTableField(datasetTableField); extFilterList.add(drillFilter); + drillFilters.add(drillFilter); + if (!checkDrillExist(xAxis, extStack, d, view)) { xAxis.add(d); } @@ -439,6 +442,7 @@ public class ChartViewService { dto.setSql(datasourceRequest.getQuery()); dto.setDrill(isDrill); + dto.setDrillFilters(drillFilters); return dto; } diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index 085d54956a..df8529901a 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -494,6 +494,9 @@
    +
    + +
    @@ -603,6 +606,7 @@ import ChartDragItem from '../components/drag-item/ChartDragItem' import DrillItem from '../components/drag-item/DrillItem' import ResultFilterEditor from '../components/filter/ResultFilterEditor' import ChartComponent from '../components/ChartComponent' +import DrillPath from '@/views/chart/view/DrillPath' import bus from '@/utils/bus' import DatasetChartDetail from '../../dataset/common/DatasetChartDetail' // shape attr,component style @@ -663,7 +667,8 @@ export default { DimensionItem, draggable, ChartDragItem, - DrillItem + DrillItem, + DrillPath }, props: { param: { @@ -739,7 +744,8 @@ export default { places: [], attrActiveNames: [], styleActiveNames: [], - drillClickDimensionList: [] + drillClickDimensionList: [], + drillFilters: [] } }, computed: { @@ -1017,6 +1023,7 @@ export default { if (!response.data.drill) { this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1) } + this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters)) }).catch(err => { this.resetView() this.resetDrill() @@ -1513,6 +1520,10 @@ export default { resetDrill() { this.drillClickDimensionList = [] + }, + drillJump(index) { + this.drillClickDimensionList = this.drillClickDimensionList.slice(0, index) + this.getData(this.param.id) } } } diff --git a/frontend/src/views/chart/view/DrillPath.vue b/frontend/src/views/chart/view/DrillPath.vue new file mode 100644 index 0000000000..b3370eae0d --- /dev/null +++ b/frontend/src/views/chart/view/DrillPath.vue @@ -0,0 +1,47 @@ + + + + + From e11d6ff7d9cfa5f73b966530a8fd28f8a7bde854 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Wed, 11 Aug 2021 17:49:31 +0800 Subject: [PATCH 25/30] =?UTF-8?q?feat:=E4=BB=AA=E8=A1=A8=E6=9D=BF=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E9=92=BB=E5=8F=96=E5=92=8C=E8=81=94=E5=8A=A8=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E5=AD=98=E5=9C=A8=E6=97=B6=EF=BC=8C=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E7=94=B1=E7=94=A8=E6=88=B7=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Editor/ComponentWrapper.vue | 4 +- .../components/Editor/SettingMenuTest.vue | 181 ++++++++++++++++++ .../canvas/components/Editor/ViewTrackBar.vue | 121 +++--------- frontend/src/lang/en.js | 4 +- frontend/src/lang/tw.js | 4 +- frontend/src/lang/zh.js | 4 +- .../views/chart/components/ChartComponent.vue | 59 ++++-- 7 files changed, 265 insertions(+), 112 deletions(-) create mode 100644 frontend/src/components/canvas/components/Editor/SettingMenuTest.vue diff --git a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue index 80992dfe8f..88216e9e1a 100644 --- a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue +++ b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue @@ -7,7 +7,6 @@ @mousedown="elementMouseDown" > - +
    +
    + + TEST + + {{ $t('panel.copy') }} + {{ $t('panel.delete') }} + {{ $t('panel.topComponent') }} + {{ $t('panel.bottomComponent') }} + {{ $t('panel.upComponent') }} + {{ $t('panel.downComponent') }} + 联动设置 + + +
    +
    + + + + + diff --git a/frontend/src/components/canvas/components/Editor/ViewTrackBar.vue b/frontend/src/components/canvas/components/Editor/ViewTrackBar.vue index c55ce512c7..998e339b02 100644 --- a/frontend/src/components/canvas/components/Editor/ViewTrackBar.vue +++ b/frontend/src/components/canvas/components/Editor/ViewTrackBar.vue @@ -1,124 +1,55 @@ diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 2e66018e6b..9328202b86 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1179,7 +1179,9 @@ export default { panel_save_tips: 'Do you want to save the changes you made to.', panel_save_warn_tips: "Your changes will be lost if you don't save them!", do_not_save: "Don't Save", - save_and_close: 'Save' + save_and_close: 'Save', + drill: 'drill', + linkage: 'linkage' }, plugin: { local_install: 'Local installation', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 12c3625fee..2d8dcfbea3 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -1179,7 +1179,9 @@ export default { panel_save_tips: '仪表板已变动,是否保存?', panel_save_warn_tips: '如果未保存,你对仪表板做的变更将会丢失!', do_not_save: '不保存', - save: '保存' + save: '保存', + drill: '下钻', + linkage: '联动' }, plugin: { local_install: '本地安裝', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 503a0c9c6c..4e4c656373 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1181,7 +1181,9 @@ export default { panel_save_tips: '仪表板已变动,是否保存?', panel_save_warn_tips: '如果未保存,你对仪表板做的变更将会丢失!', do_not_save: '不保存', - save: '保存' + save: '保存', + drill: '下钻', + linkage: '联动' }, plugin: { local_install: '本地安装', diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 7e46dc6e99..6e91946a57 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -1,5 +1,6 @@ @@ -18,9 +19,11 @@ import { baseTreemapOption } from '../chart/treemap/treemap' // import eventBus from '@/components/canvas/utils/eventBus' import { uuid } from 'vue-uuid' import { geoJson } from '@/api/map/map' +import ViewTrackBar from '@/components/canvas/components/Editor/ViewTrackBar' export default { name: 'ChartComponent', + components: { ViewTrackBar }, props: { chart: { type: Object, @@ -32,13 +35,33 @@ export default { default: function() { return {} } + }, + trackMenu: { + type: Array, + required: false, + default: function() { + return ['drill', 'linkage'] + } } }, data() { return { myChart: {}, chartId: uuid.v1(), - currentGeoJson: null + currentGeoJson: null, + showTrackBar: true, + trackBarStyle: { + position: 'absolute', + left: '0px', + top: '0px' + }, + pointParam: null + } + }, + + computed: { + trackBarStyleTime() { + return this.trackBarStyle } }, watch: { @@ -60,8 +83,6 @@ export default { }, methods: { preDraw() { - const viewId = this.chart.id - const _store = this.$store // 基于准备好的dom,初始化echarts实例 // 渲染echart等待dom加载完毕,渲染之前先尝试销毁具有相同id的echart 放置多次切换仪表板有重复id情况 const that = this @@ -75,15 +96,14 @@ export default { this.myChart.off('click') this.myChart.on('click', function(param) { - console.log(JSON.stringify(param.data)) - const trackFilter = { - viewId: viewId, - dimensionList: param.data.dimensionList, - quotaList: param.data.quotaList + that.pointParam = param + if (that.trackMenu.length === 1) { // 只有一个事件直接调用 + that.trackClick(that.trackMenu[0]) + } else { // 视图关联多个事件 + that.trackBarStyle.left = param.event.offsetX + 'px' + that.trackBarStyle.top = (param.event.offsetY - 15) + 'px' + that.$refs.viewTrack.trackButtonClick() } - _store.commit('addViewTrackFilter', trackFilter) - - that.$emit('onChartClick', param) }) }) }, @@ -169,6 +189,23 @@ export default { // 指定图表的配置项和数据 const chart = this.myChart chart.resize() + }, + trackClick(trackAction) { + const linkageParam = { + viewId: this.chart.id, + dimensionList: this.pointParam.data.dimensionList, + quotaList: this.pointParam.data.quotaList + } + switch (trackAction) { + case 'drill': + this.$emit('onChartClick', this.pointParam) + break + case 'linkage': + this.$store.commit('addViewTrackFilter', linkageParam) + break + default: + break + } } } } From c75f9c5fb76cab121362691d78deb19e81397d7a Mon Sep 17 00:00:00 2001 From: junjie Date: Wed, 11 Aug 2021 18:10:34 +0800 Subject: [PATCH 26/30] =?UTF-8?q?feat:=20=E8=A7=86=E5=9B=BE=E4=B8=8B?= =?UTF-8?q?=E9=92=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/dataease/service/chart/ChartViewService.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index ef86ad47e6..02e0094fb7 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -430,6 +430,17 @@ public class ChartViewService { } else { mapChart = transChartData(xAxis, yAxis, view, data); } + // 钻取模式,去除前几层维度值,只保留当前层 + if (isDrill) { + List xList = (List) mapChart.get("x"); + List xNewList = new ArrayList<>(); + for (String x : xList) { + String[] split = x.split("\n"); + x = split[split.length - 1]; + xNewList.add(x); + } + mapChart.put("x", xNewList); + } // table组件,明细表,也用于导出数据 Map mapTableNormal = transTableNormal(xAxis, yAxis, view, data, extStack); From 5ddd0a034df5affdbd94f15f5b6b4b71b2b8b66d Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Wed, 11 Aug 2021 18:32:10 +0800 Subject: [PATCH 27/30] =?UTF-8?q?feat:=E4=BB=AA=E8=A1=A8=E6=9D=BF=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=A7=86=E5=9B=BE=E4=B8=8B=E9=92=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../canvas/custom-component/UserView.vue | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index 1d61d5893e..390de3af56 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -16,7 +16,7 @@ {{ $t('chart.chart_error_tips') }}
- + @@ -37,6 +37,7 @@ import { BASE_CHART_STRING } from '@/views/chart/chart/chart' import eventBus from '@/components/canvas/utils/eventBus' import { deepCopy } from '@/components/canvas/utils/utils' import { getToken, getLinkToken } from '@/utils/auth' + export default { name: 'UserView', components: { ChartComponent, TableNormal, LabelNormal }, @@ -77,7 +78,8 @@ export default { refId: null, chart: BASE_CHART_STRING, requestStatus: 'waiting', - message: null + message: null, + drillClickDimensionList: [] } }, computed: { @@ -85,6 +87,7 @@ export default { const filter = {} filter.filter = this.element.filters filter.linkageFilters = this.element.linkageFilters + filter.drill = this.drillClickDimensionList return filter }, filters() { @@ -191,6 +194,10 @@ export default { // 将视图传入echart组件 if (response.success) { this.chart = response.data + this.chart.drillFields = this.chart.drillFields ? JSON.parse(this.chart.drillFields) : [] + if (!response.data.drill) { + this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1) + } this.requestStatus = 'merging' this.mergeStyle() this.requestStatus = 'success' @@ -225,6 +232,22 @@ export default { tableChart.customAttr = JSON.stringify(tableChart.customAttr) tableChart.customStyle = JSON.stringify(tableChart.customStyle) eventBus.$emit('openChartDetailsDialog', { chart: this.chart, tableChart: tableChart }) + }, + + chartClick(param) { + debugger + if (this.drillClickDimensionList.length < this.chart.drillFields.length - 1) { + this.drillClickDimensionList.push({ dimensionList: param.data.dimensionList }) + this.getData(this.element.propValue.viewId) + } + }, + + resetDrill() { + this.drillClickDimensionList = [] + }, + drillJump(index) { + this.drillClickDimensionList = this.drillClickDimensionList.slice(0, index) + this.getData(this.element.propValue.viewId) } } } From 3d5ffb8cfe2b90d7dce4f516811a0f9d30ddd7c2 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Wed, 11 Aug 2021 18:41:05 +0800 Subject: [PATCH 28/30] =?UTF-8?q?feat:=E4=BB=AA=E8=A1=A8=E6=9D=BF=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=A7=86=E5=9B=BE=E4=B8=8A=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/canvas/custom-component/UserView.vue | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index 390de3af56..f481795914 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -19,6 +19,9 @@ +
+ +
@@ -37,10 +40,11 @@ import { BASE_CHART_STRING } from '@/views/chart/chart/chart' import eventBus from '@/components/canvas/utils/eventBus' import { deepCopy } from '@/components/canvas/utils/utils' import { getToken, getLinkToken } from '@/utils/auth' +import DrillPath from '@/views/chart/view/DrillPath' export default { name: 'UserView', - components: { ChartComponent, TableNormal, LabelNormal }, + components: { ChartComponent, TableNormal, LabelNormal, DrillPath }, props: { element: { type: Object, @@ -79,7 +83,8 @@ export default { chart: BASE_CHART_STRING, requestStatus: 'waiting', message: null, - drillClickDimensionList: [] + drillClickDimensionList: [], + drillFilters: [] } }, computed: { @@ -198,6 +203,7 @@ export default { if (!response.data.drill) { this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1) } + this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters)) this.requestStatus = 'merging' this.mergeStyle() this.requestStatus = 'success' From b29d4b3cf267a8a608e506eda192d6c6fe57ac91 Mon Sep 17 00:00:00 2001 From: junjie Date: Wed, 11 Aug 2021 18:44:07 +0800 Subject: [PATCH 29/30] =?UTF-8?q?feat:=20=E8=A7=86=E5=9B=BE=E4=B8=8B?= =?UTF-8?q?=E9=92=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/chart/ChartViewService.java | 115 ++++++++++-------- 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 02e0094fb7..3ab743ceb9 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -419,27 +419,16 @@ public class ChartViewService { // 图表组件可再扩展 Map mapChart; if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { - mapChart = transStackChartData(xAxis, yAxis, view, data, extStack); + mapChart = transStackChartData(xAxis, yAxis, view, data, extStack, isDrill); } else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) { - mapChart = transScatterData(xAxis, yAxis, view, data, extBubble); + mapChart = transScatterData(xAxis, yAxis, view, data, extBubble, isDrill); } else if (StringUtils.containsIgnoreCase(view.getType(), "radar")) { - mapChart = transRadarChartData(xAxis, yAxis, view, data); + mapChart = transRadarChartData(xAxis, yAxis, view, data, isDrill); } else if (StringUtils.containsIgnoreCase(view.getType(), "text") || StringUtils.containsIgnoreCase(view.getType(), "gauge")) { - mapChart = transNormalChartData(xAxis, yAxis, view, data); + mapChart = transNormalChartData(xAxis, yAxis, view, data, isDrill); } else { - mapChart = transChartData(xAxis, yAxis, view, data); - } - // 钻取模式,去除前几层维度值,只保留当前层 - if (isDrill) { - List xList = (List) mapChart.get("x"); - List xNewList = new ArrayList<>(); - for (String x : xList) { - String[] split = x.split("\n"); - x = split[split.length - 1]; - xNewList.add(x); - } - mapChart.put("x", xNewList); + mapChart = transChartData(xAxis, yAxis, view, data, isDrill); } // table组件,明细表,也用于导出数据 Map mapTableNormal = transTableNormal(xAxis, yAxis, view, data, extStack); @@ -512,7 +501,7 @@ public class ChartViewService { } // 基础图形 - private Map transChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data) { + private Map transChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, boolean isDrill) { Map map = new HashMap<>(); List x = new ArrayList<>(); @@ -553,11 +542,15 @@ public class ChartViewService { } series.get(j).getData().add(axisChartDataDTO); } - for (int i = 0; i < xAxis.size(); i++) { - if (i == xAxis.size() - 1) { - a.append(d[i]); - } else { - a.append(d[i]).append("\n"); + if (isDrill) { + a.append(d[xAxis.size() - 1]); + } else { + for (int i = 0; i < xAxis.size(); i++) { + if (i == xAxis.size() - 1) { + a.append(d[i]); + } else { + a.append(d[i]).append("\n"); + } } } x.add(a.toString()); @@ -569,7 +562,7 @@ public class ChartViewService { } // 常规图形 - private Map transNormalChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data) { + private Map transNormalChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, boolean isDrill) { Map map = new HashMap<>(); List x = new ArrayList<>(); @@ -583,11 +576,15 @@ public class ChartViewService { } for (String[] d : data) { StringBuilder a = new StringBuilder(); - for (int i = 0; i < xAxis.size(); i++) { - if (i == xAxis.size() - 1) { - a.append(d[i]); - } else { - a.append(d[i]).append("\n"); + if (isDrill) { + a.append(d[xAxis.size() - 1]); + } else { + for (int i = 0; i < xAxis.size(); i++) { + if (i == xAxis.size() - 1) { + a.append(d[i]); + } else { + a.append(d[i]).append("\n"); + } } } x.add(a.toString()); @@ -607,7 +604,7 @@ public class ChartViewService { } // radar图 - private Map transRadarChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data) { + private Map transRadarChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, boolean isDrill) { Map map = new HashMap<>(); List x = new ArrayList<>(); @@ -621,11 +618,15 @@ public class ChartViewService { } for (String[] d : data) { StringBuilder a = new StringBuilder(); - for (int i = 0; i < xAxis.size(); i++) { - if (i == xAxis.size() - 1) { - a.append(d[i]); - } else { - a.append(d[i]).append("\n"); + if (isDrill) { + a.append(d[xAxis.size() - 1]); + } else { + for (int i = 0; i < xAxis.size(); i++) { + if (i == xAxis.size() - 1) { + a.append(d[i]); + } else { + a.append(d[i]).append("\n"); + } } } x.add(a.toString()); @@ -645,7 +646,7 @@ public class ChartViewService { } // 堆叠图 - private Map transStackChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, List extStack) { + private Map transStackChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, List extStack, boolean isDrill) { Map map = new HashMap<>(); List x = new ArrayList<>(); @@ -659,11 +660,15 @@ public class ChartViewService { // 构建横轴 for (String[] d : data) { StringBuilder a = new StringBuilder(); - for (int i = 0; i < xAxis.size(); i++) { - if (i == xAxis.size() - 1) { - a.append(d[i]); - } else { - a.append(d[i]).append("\n"); + if (isDrill) { + a.append(d[xAxis.size() - 1]); + } else { + for (int i = 0; i < xAxis.size(); i++) { + if (i == xAxis.size() - 1) { + a.append(d[i]); + } else { + a.append(d[i]).append("\n"); + } } } x.add(a.toString()); @@ -770,11 +775,15 @@ public class ChartViewService { } series.get(j).getData().add(axisChartDataDTO); } - for (int i = 0; i < xAxis.size(); i++) { - if (i == xAxis.size() - 1) { - a.append(d[i]); - } else { - a.append(d[i]).append("\n"); + if (isDrill) { + a.append(d[xAxis.size() - 1]); + } else { + for (int i = 0; i < xAxis.size(); i++) { + if (i == xAxis.size() - 1) { + a.append(d[i]); + } else { + a.append(d[i]).append("\n"); + } } } x.add(a.toString()); @@ -787,7 +796,7 @@ public class ChartViewService { } // 散点图 - private Map transScatterData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, List extBubble) { + private Map transScatterData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, List extBubble, boolean isDrill) { Map map = new HashMap<>(); List x = new ArrayList<>(); @@ -803,11 +812,15 @@ public class ChartViewService { String[] d = data.get(i1); StringBuilder a = new StringBuilder(); - for (int i = 0; i < xAxis.size(); i++) { - if (i == xAxis.size() - 1) { - a.append(d[i]); - } else { - a.append(d[i]).append("\n"); + if (isDrill) { + a.append(d[xAxis.size() - 1]); + } else { + for (int i = 0; i < xAxis.size(); i++) { + if (i == xAxis.size() - 1) { + a.append(d[i]); + } else { + a.append(d[i]).append("\n"); + } } } x.add(a.toString()); From d9c7885c88909ef641f7374d7a9d7aef1caa15d9 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Thu, 12 Aug 2021 10:15:10 +0800 Subject: [PATCH 30/30] =?UTF-8?q?feat:=E4=BB=AA=E8=A1=A8=E6=9D=BF=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E6=A0=B9=E6=8D=AE=E4=B8=80=E4=B8=AA=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=9C=89=E5=A4=9A=E4=BA=8B=E4=BB=B6=E6=9D=A5?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E6=98=AF=E5=90=A6=E5=87=BA=E7=8E=B0=E5=BC=B9?= =?UTF-8?q?=E6=A1=86=EF=BC=8C=E5=8D=95=E4=BA=8B=E4=BB=B6=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E8=A7=A6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../canvas/custom-component/UserView.vue | 24 ++++++++++++++++--- .../views/chart/components/ChartComponent.vue | 4 ++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index f481795914..f0ef6e4f13 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -16,7 +16,7 @@ {{ $t('chart.chart_error_tips') }} - +
@@ -84,7 +84,8 @@ export default { requestStatus: 'waiting', message: null, drillClickDimensionList: [], - drillFilters: [] + drillFilters: [], + drillFields: [] } }, computed: { @@ -107,8 +108,23 @@ export default { console.log('linkageFilters:' + JSON.stringify(this.element.linkageFilters)) return JSON.parse(JSON.stringify(this.element.linkageFilters)) }, + trackMenu() { + const trackMenuInfo = [] + let linkageCount = 0 + this.chart.data.fields && this.chart.data.fields.forEach(item => { + const sourceInfo = this.chart.id + '#' + item.id + if (this.nowPanelTrackInfo[sourceInfo]) { + linkageCount++ + } + }) + linkageCount && trackMenuInfo.push('linkage') + this.drillFields.length && trackMenuInfo.push('drill') + console.log('trackMenuInfo' + JSON.stringify(trackMenuInfo)) + return trackMenuInfo + }, ...mapState([ - 'canvasStyleData' + 'canvasStyleData', + 'nowPanelTrackInfo' ]) }, @@ -200,10 +216,12 @@ export default { if (response.success) { this.chart = response.data this.chart.drillFields = this.chart.drillFields ? JSON.parse(this.chart.drillFields) : [] + debugger if (!response.data.drill) { this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1) } this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters)) + this.drillFields = JSON.parse(JSON.stringify(response.data.drillFields)) this.requestStatus = 'merging' this.mergeStyle() this.requestStatus = 'success' diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 6e91946a57..121fce342c 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -40,7 +40,7 @@ export default { type: Array, required: false, default: function() { - return ['drill', 'linkage'] + return ['drill'] } } }, @@ -97,7 +97,7 @@ export default { this.myChart.off('click') this.myChart.on('click', function(param) { that.pointParam = param - if (that.trackMenu.length === 1) { // 只有一个事件直接调用 + if (that.trackMenu.length < 2) { // 只有一个事件直接调用 that.trackClick(that.trackMenu[0]) } else { // 视图关联多个事件 that.trackBarStyle.left = param.event.offsetX + 'px'