diff --git a/.gitignore b/.gitignore index d7a4223552..dd0d793cda 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ pnpm-debug.log* *.classpath *.project .settings/ +.lh package-lock.json diff --git a/backend/pom.xml b/backend/pom.xml index 5415073b33..d30a28ec21 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -5,7 +5,7 @@ dataease-server io.dataease - 1.2.0 + 1.3.0 4.0.0 @@ -214,7 +214,7 @@ org.jsoup jsoup - 1.10.3 + 1.14.2 @@ -226,7 +226,7 @@ org.apache.commons commons-compress - 1.20 + 1.21 @@ -252,11 +252,11 @@ 20171018 - + net.oneandone.reflections8 @@ -316,7 +316,7 @@ io.dataease dataease-plugin-interface - 1.2 + 1.3 @@ -338,10 +338,21 @@ + + + + + + + + + ru.yandex.clickhouse + clickhouse-jdbc + 0.3.1 + diff --git a/backend/src/main/java/io/dataease/auth/api/AuthApi.java b/backend/src/main/java/io/dataease/auth/api/AuthApi.java index 5cdbd7151c..f5e72afbb0 100644 --- a/backend/src/main/java/io/dataease/auth/api/AuthApi.java +++ b/backend/src/main/java/io/dataease/auth/api/AuthApi.java @@ -5,7 +5,6 @@ import io.dataease.auth.api.dto.CurrentUserDto; import io.dataease.auth.api.dto.LoginDto; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -41,4 +40,13 @@ public interface AuthApi { @PostMapping("/validateName") Boolean validateName(Map nameDto); + @ApiOperation("是否开启ldap") + @PostMapping("/isOpenLdap") + boolean isOpenLdap(); + + + @ApiOperation("是否开启oidc") + @PostMapping("/isOpenOidc") + boolean isOpenOidc(); + } diff --git a/backend/src/main/java/io/dataease/auth/api/dto/LoginDto.java b/backend/src/main/java/io/dataease/auth/api/dto/LoginDto.java index c1f0adc052..62af1ce003 100644 --- a/backend/src/main/java/io/dataease/auth/api/dto/LoginDto.java +++ b/backend/src/main/java/io/dataease/auth/api/dto/LoginDto.java @@ -13,4 +13,12 @@ public class LoginDto implements Serializable { @ApiModelProperty(value = "密码", required = true) private String password; + + /** + * 0: 默认登录 + * 1:ldap登录 + * 2:单点登录 + */ + @ApiModelProperty(value = "登录方式", required = true, allowableValues = "0, 1, 2") + private int loginType; } diff --git a/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java b/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java index ade63a71ce..e018cca48a 100644 --- a/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java +++ b/backend/src/main/java/io/dataease/auth/entity/TokenInfo.java @@ -13,6 +13,8 @@ public class TokenInfo implements Serializable { private Long userId; + /* private String idToken; */ + public String format(){ return username + "," +userId; } diff --git a/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java b/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java index cd5b76320f..3587c52404 100644 --- a/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java +++ b/backend/src/main/java/io/dataease/auth/filter/F2CLogoutFilter.java @@ -4,7 +4,6 @@ import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.LogoutFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; diff --git a/backend/src/main/java/io/dataease/auth/server/AuthServer.java b/backend/src/main/java/io/dataease/auth/server/AuthServer.java index 74bf04c371..57bce9fbaa 100644 --- a/backend/src/main/java/io/dataease/auth/server/AuthServer.java +++ b/backend/src/main/java/io/dataease/auth/server/AuthServer.java @@ -14,20 +14,26 @@ import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.CodingUtil; import io.dataease.commons.utils.LogUtil; import io.dataease.commons.utils.ServletUtils; - import io.dataease.exception.DataEaseException; import io.dataease.i18n.Translator; +import io.dataease.plugins.config.SpringContextUtil; +import io.dataease.plugins.util.PluginUtils; +import io.dataease.plugins.xpack.ldap.dto.request.LdapValidateRequest; +import io.dataease.plugins.xpack.ldap.dto.response.ValidateResult; +import io.dataease.plugins.xpack.ldap.service.LdapXpackService; +import io.dataease.plugins.xpack.oidc.service.OidcXpackService; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; - import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.servlet.http.HttpServletRequest; + @RestController public class AuthServer implements AuthApi { @@ -35,10 +41,29 @@ public class AuthServer implements AuthApi { private AuthUserService authUserService; + + @Override public Object login(@RequestBody LoginDto loginDto) throws Exception { String username = loginDto.getUsername(); String password = loginDto.getPassword(); + + + String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, password); + // 增加ldap登录方式 + Integer loginType = loginDto.getLoginType(); + boolean isSupportLdap = authUserService.supportLdap(); + if (loginType == 1 && isSupportLdap) { + LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); + LdapValidateRequest request = LdapValidateRequest.builder().userName(username).password(pwd).build(); + ValidateResult validateResult = ldapXpackService.login(request); + if (!validateResult.isSuccess()) { + DataEaseException.throwException(validateResult.getMsg()); + } + username = validateResult.getUserName(); + } + // 增加ldap登录方式 + SysUserEntity user = authUserService.getUserByName(username); if (ObjectUtils.isEmpty(user)) { @@ -48,14 +73,19 @@ public class AuthServer implements AuthApi { DataEaseException.throwException(Translator.get("i18n_id_or_pwd_error")); } String realPwd = user.getPassword(); - //私钥解密 - String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, password); - //md5加密 - pwd = CodingUtil.md5(pwd); - if (!StringUtils.equals(pwd, realPwd)) { - DataEaseException.throwException(Translator.get("i18n_id_or_pwd_error")); + // 普通登录需要验证密码 + if (loginType == 0 || !isSupportLdap) { + //私钥解密 + + //md5加密 + pwd = CodingUtil.md5(pwd); + + if (!StringUtils.equals(pwd, realPwd)) { + DataEaseException.throwException(Translator.get("i18n_id_or_pwd_error")); + } } + Map result = new HashMap<>(); TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).build(); String token = JWTUtils.sign(tokenInfo, realPwd); @@ -85,6 +115,16 @@ public class AuthServer implements AuthApi { @Override public String logout() { String token = ServletUtils.getToken(); + + if (isOpenOidc()) { + HttpServletRequest request = ServletUtils.request(); + String idToken = request.getHeader("IdToken"); + if (StringUtils.isNotBlank(idToken)) { + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + oidcXpackService.logout(idToken); + } + + } if (StringUtils.isEmpty(token) || StringUtils.equals("null", token) || StringUtils.equals("undefined", token)) { return "success"; } @@ -108,6 +148,23 @@ public class AuthServer implements AuthApi { return true; } + @Override + public boolean isOpenLdap() { + Boolean licValid = PluginUtils.licValid(); + if(!licValid) return false; + boolean open = authUserService.supportLdap(); + return open; + } + + @Override + public boolean isOpenOidc() { + Boolean licValid = PluginUtils.licValid(); + if(!licValid) return false; + return authUserService.supportOidc(); + } + + + /*@Override public Boolean isLogin() { return null; diff --git a/backend/src/main/java/io/dataease/auth/service/AuthUserService.java b/backend/src/main/java/io/dataease/auth/service/AuthUserService.java index 8154412bbd..22462d5fe9 100644 --- a/backend/src/main/java/io/dataease/auth/service/AuthUserService.java +++ b/backend/src/main/java/io/dataease/auth/service/AuthUserService.java @@ -13,6 +13,8 @@ public interface AuthUserService { SysUserEntity getUserByName(String username); + SysUserEntity getUserBySub(String sub); + List roles(Long userId); List permissions(Long userId); @@ -21,6 +23,10 @@ public interface AuthUserService { void clearCache(Long userId); + boolean supportLdap(); + + Boolean supportOidc(); + } diff --git a/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java index 5e7b31d617..fe11af4de1 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java @@ -8,6 +8,11 @@ import io.dataease.base.mapper.ext.AuthMapper; import io.dataease.auth.service.AuthUserService; import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.utils.LogUtil; +import io.dataease.plugins.config.SpringContextUtil; +import io.dataease.plugins.xpack.ldap.service.LdapXpackService; +import io.dataease.plugins.xpack.oidc.service.OidcXpackService; + +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; @@ -16,6 +21,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -46,6 +52,11 @@ public class AuthUserServiceImpl implements AuthUserService { return authMapper.findUserByName(username); } + @Override + public SysUserEntity getUserBySub(String sub) { + return authMapper.findUserBySub(sub); + } + @Override public List roles(Long userId){ return authMapper.roleCodes(userId); @@ -102,4 +113,23 @@ public class AuthUserServiceImpl implements AuthUserService { LogUtil.info("正在清除用户缓存【{}】",userId); } + @Override + public boolean supportLdap() { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LdapXpackService.class)); + if(beansOfType.keySet().size() == 0) return false; + LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); + if(ObjectUtils.isEmpty(ldapXpackService)) return false; + return ldapXpackService.isOpen(); + } + + @Override + public Boolean supportOidc() { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((OidcXpackService.class)); + if(beansOfType.keySet().size() == 0) return false; + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + if(ObjectUtils.isEmpty(oidcXpackService)) return false; + return oidcXpackService.isSuuportOIDC(); + } + + } diff --git a/backend/src/main/java/io/dataease/auth/service/impl/DynamicMenuServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/DynamicMenuServiceImpl.java index 70b7f9f280..667aaa09e6 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/DynamicMenuServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/DynamicMenuServiceImpl.java @@ -13,7 +13,6 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; 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 0e9361b330..aecb307469 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 @@ -56,8 +56,15 @@ public class ShiroServiceImpl implements ShiroService { // filterChainDefinitionMap.put("/axios.map", ANON); filterChainDefinitionMap.put("/api/auth/login", ANON); - filterChainDefinitionMap.put("/api/auth/logout", ANON); + // filterChainDefinitionMap.put("/api/auth/logout", ANON); filterChainDefinitionMap.put("/api/auth/validateName", ANON); + filterChainDefinitionMap.put("/api/auth/isOpenLdap", ANON); + filterChainDefinitionMap.put("/api/auth/isOpenOidc", ANON); + filterChainDefinitionMap.put("/api/pluginCommon/component/*", ANON); + filterChainDefinitionMap.put("/plugin/oidc/authInfo", ANON); + filterChainDefinitionMap.put("/sso/callBack*", ANON); + + filterChainDefinitionMap.put("/unauth", ANON); filterChainDefinitionMap.put("/display/**", ANON); filterChainDefinitionMap.put("/tokenExpired", ANON); diff --git a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java index 7736983d55..544c7a9cb8 100644 --- a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java +++ b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java @@ -2,16 +2,18 @@ package io.dataease.auth.util; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.JWTCreator.Builder; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.DecodedJWT; +import com.auth0.jwt.interfaces.Verification; import io.dataease.auth.entity.TokenInfo; +import io.dataease.auth.entity.TokenInfo.TokenInfoBuilder; import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.exception.DataEaseException; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.core.env.Environment; - import java.util.Date; @@ -34,10 +36,13 @@ public class JWTUtils { */ public static boolean verify(String token, TokenInfo tokenInfo, String secret) { Algorithm algorithm = Algorithm.HMAC256(secret); - JWTVerifier verifier = JWT.require(algorithm) + Verification verification = JWT.require(algorithm) .withClaim("username", tokenInfo.getUsername()) - .withClaim("userId", tokenInfo.getUserId()) - .build(); + .withClaim("userId", tokenInfo.getUserId()); + /* if (StringUtils.isNotBlank(tokenInfo.getIdToken())) { + verification.withClaim("idToken", tokenInfo.getIdToken()); + } */ + JWTVerifier verifier = verification.build(); verifier.verify(token); return true; } @@ -50,10 +55,15 @@ public class JWTUtils { DecodedJWT jwt = JWT.decode(token); String username = jwt.getClaim("username").asString(); Long userId = jwt.getClaim("userId").asLong(); + // String idToken = jwt.getClaim("idToken").asString(); if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) ){ DataEaseException.throwException("token格式错误!"); } - TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).build(); + TokenInfoBuilder tokenInfoBuilder = TokenInfo.builder().username(username).userId(userId); + /* if (StringUtils.isNotBlank(idToken)) { + tokenInfoBuilder.idToken(idToken); + } */ + TokenInfo tokenInfo = tokenInfoBuilder.build(); return tokenInfo; } @@ -107,12 +117,14 @@ public class JWTUtils { try { Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME); Algorithm algorithm = Algorithm.HMAC256(secret); - // 附带username信息 - return JWT.create() + Builder builder = JWT.create() .withClaim("username", tokenInfo.getUsername()) - .withClaim("userId", tokenInfo.getUserId()) - .withExpiresAt(date) - .sign(algorithm); + .withClaim("userId", tokenInfo.getUserId()); + /* if (StringUtils.isNotBlank(tokenInfo.getIdToken())) { + builder.withClaim("idToken", tokenInfo.getIdToken()); + } */ + return builder.withExpiresAt(date).sign(algorithm); + } catch (Exception e) { return null; } diff --git a/backend/src/main/java/io/dataease/base/domain/ChartView.java b/backend/src/main/java/io/dataease/base/domain/ChartView.java index 2bb2de365e..f8e662c1d5 100644 --- a/backend/src/main/java/io/dataease/base/domain/ChartView.java +++ b/backend/src/main/java/io/dataease/base/domain/ChartView.java @@ -1,31 +1,28 @@ package io.dataease.base.domain; import java.io.Serializable; - -import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class ChartView implements Serializable { - @ApiModelProperty("ID") private String id; - @ApiModelProperty("名称") + private String name; - @ApiModelProperty("场景ID") + private String sceneId; - @ApiModelProperty("表ID") + private String tableId; - @ApiModelProperty("类型") + private String type; - @ApiModelProperty("标题") + private String title; - @ApiModelProperty("创建者") + private String createBy; - @ApiModelProperty("创建时间") + private Long createTime; - @ApiModelProperty("更新时间") + private Long updateTime; - @ApiModelProperty("样式优先级") + private String stylePriority; private static final long serialVersionUID = 1L; diff --git a/backend/src/main/java/io/dataease/base/domain/ChartViewWithBLOBs.java b/backend/src/main/java/io/dataease/base/domain/ChartViewWithBLOBs.java index 5ac886681d..61779e0cdd 100644 --- a/backend/src/main/java/io/dataease/base/domain/ChartViewWithBLOBs.java +++ b/backend/src/main/java/io/dataease/base/domain/ChartViewWithBLOBs.java @@ -15,15 +15,17 @@ public class ChartViewWithBLOBs extends ChartView implements Serializable { private String xAxis; @ApiModelProperty("y轴") private String yAxis; + @ApiModelProperty("副y轴") + private String yAxisExt; @ApiModelProperty("堆叠") private String extStack; @ApiModelProperty("气泡") private String extBubble; - @ApiModelProperty("客户端属性") + @ApiModelProperty("图形属性") private String customAttr; - @ApiModelProperty("客户端样式") + @ApiModelProperty("组件样式") private String customStyle; - @ApiModelProperty("客户端过滤条件") + @ApiModelProperty("过滤条件") private String customFilter; @ApiModelProperty("下钻字段") private String drillFields; diff --git a/backend/src/main/java/io/dataease/base/domain/Datasource.java b/backend/src/main/java/io/dataease/base/domain/Datasource.java index 86b2bca643..37dfeefa85 100644 --- a/backend/src/main/java/io/dataease/base/domain/Datasource.java +++ b/backend/src/main/java/io/dataease/base/domain/Datasource.java @@ -1,29 +1,26 @@ package io.dataease.base.domain; import java.io.Serializable; - -import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class Datasource implements Serializable { - @ApiModelProperty("ID") private String id; - @ApiModelProperty("名称") + private String name; - @ApiModelProperty("描述") + private String desc; - @ApiModelProperty("类型") + private String type; - @ApiModelProperty("创建时间") + private Long createTime; - @ApiModelProperty("更新时间") + private Long updateTime; - @ApiModelProperty("创建者") + private String createBy; - @ApiModelProperty("状态") + private String status; - @ApiModelProperty("配置") + private String configuration; private static final long serialVersionUID = 1L; diff --git a/backend/src/main/java/io/dataease/base/domain/PanelPdfTemplate.java b/backend/src/main/java/io/dataease/base/domain/PanelPdfTemplate.java new file mode 100644 index 0000000000..4df504b8fc --- /dev/null +++ b/backend/src/main/java/io/dataease/base/domain/PanelPdfTemplate.java @@ -0,0 +1,21 @@ +package io.dataease.base.domain; + +import java.io.Serializable; +import lombok.Data; + +@Data +public class PanelPdfTemplate implements Serializable { + private String id; + + private String name; + + private Long createTime; + + private String createUser; + + private Integer sort; + + private String templateContent; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/domain/PanelPdfTemplateExample.java b/backend/src/main/java/io/dataease/base/domain/PanelPdfTemplateExample.java new file mode 100644 index 0000000000..3f3b9d343a --- /dev/null +++ b/backend/src/main/java/io/dataease/base/domain/PanelPdfTemplateExample.java @@ -0,0 +1,530 @@ +package io.dataease.base.domain; + +import java.util.ArrayList; +import java.util.List; + +public class PanelPdfTemplateExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public PanelPdfTemplateExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andIdIsNull() { + addCriterion("id is null"); + return (Criteria) this; + } + + public Criteria andIdIsNotNull() { + addCriterion("id is not null"); + return (Criteria) this; + } + + public Criteria andIdEqualTo(String value) { + addCriterion("id =", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotEqualTo(String value) { + addCriterion("id <>", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThan(String value) { + addCriterion("id >", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThanOrEqualTo(String value) { + addCriterion("id >=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThan(String value) { + addCriterion("id <", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThanOrEqualTo(String value) { + addCriterion("id <=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLike(String value) { + addCriterion("id like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotLike(String value) { + addCriterion("id not like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdIn(List values) { + addCriterion("id in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdNotIn(List values) { + addCriterion("id not in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdBetween(String value1, String value2) { + addCriterion("id between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andIdNotBetween(String value1, String value2) { + addCriterion("id not between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andNameIsNull() { + addCriterion("`name` is null"); + return (Criteria) this; + } + + public Criteria andNameIsNotNull() { + addCriterion("`name` is not null"); + return (Criteria) this; + } + + public Criteria andNameEqualTo(String value) { + addCriterion("`name` =", value, "name"); + return (Criteria) this; + } + + public Criteria andNameNotEqualTo(String value) { + addCriterion("`name` <>", value, "name"); + return (Criteria) this; + } + + public Criteria andNameGreaterThan(String value) { + addCriterion("`name` >", value, "name"); + return (Criteria) this; + } + + public Criteria andNameGreaterThanOrEqualTo(String value) { + addCriterion("`name` >=", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLessThan(String value) { + addCriterion("`name` <", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLessThanOrEqualTo(String value) { + addCriterion("`name` <=", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLike(String value) { + addCriterion("`name` like", value, "name"); + return (Criteria) this; + } + + public Criteria andNameNotLike(String value) { + addCriterion("`name` not like", value, "name"); + return (Criteria) this; + } + + public Criteria andNameIn(List values) { + addCriterion("`name` in", values, "name"); + return (Criteria) this; + } + + public Criteria andNameNotIn(List values) { + addCriterion("`name` not in", values, "name"); + return (Criteria) this; + } + + public Criteria andNameBetween(String value1, String value2) { + addCriterion("`name` between", value1, value2, "name"); + return (Criteria) this; + } + + public Criteria andNameNotBetween(String value1, String value2) { + addCriterion("`name` not between", value1, value2, "name"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNull() { + addCriterion("create_time is null"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNotNull() { + addCriterion("create_time is not null"); + return (Criteria) this; + } + + public Criteria andCreateTimeEqualTo(Long value) { + addCriterion("create_time =", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotEqualTo(Long value) { + addCriterion("create_time <>", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThan(Long value) { + addCriterion("create_time >", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) { + addCriterion("create_time >=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThan(Long value) { + addCriterion("create_time <", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThanOrEqualTo(Long value) { + addCriterion("create_time <=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeIn(List values) { + addCriterion("create_time in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotIn(List values) { + addCriterion("create_time not in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeBetween(Long value1, Long value2) { + addCriterion("create_time between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotBetween(Long value1, Long value2) { + addCriterion("create_time not between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateUserIsNull() { + addCriterion("create_user is null"); + return (Criteria) this; + } + + public Criteria andCreateUserIsNotNull() { + addCriterion("create_user is not null"); + return (Criteria) this; + } + + public Criteria andCreateUserEqualTo(String value) { + addCriterion("create_user =", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotEqualTo(String value) { + addCriterion("create_user <>", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserGreaterThan(String value) { + addCriterion("create_user >", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserGreaterThanOrEqualTo(String value) { + addCriterion("create_user >=", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserLessThan(String value) { + addCriterion("create_user <", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserLessThanOrEqualTo(String value) { + addCriterion("create_user <=", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserLike(String value) { + addCriterion("create_user like", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotLike(String value) { + addCriterion("create_user not like", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserIn(List values) { + addCriterion("create_user in", values, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotIn(List values) { + addCriterion("create_user not in", values, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserBetween(String value1, String value2) { + addCriterion("create_user between", value1, value2, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotBetween(String value1, String value2) { + addCriterion("create_user not between", value1, value2, "createUser"); + return (Criteria) this; + } + + public Criteria andSortIsNull() { + addCriterion("sort is null"); + return (Criteria) this; + } + + public Criteria andSortIsNotNull() { + addCriterion("sort is not null"); + return (Criteria) this; + } + + public Criteria andSortEqualTo(Integer value) { + addCriterion("sort =", value, "sort"); + return (Criteria) this; + } + + public Criteria andSortNotEqualTo(Integer value) { + addCriterion("sort <>", value, "sort"); + return (Criteria) this; + } + + public Criteria andSortGreaterThan(Integer value) { + addCriterion("sort >", value, "sort"); + return (Criteria) this; + } + + public Criteria andSortGreaterThanOrEqualTo(Integer value) { + addCriterion("sort >=", value, "sort"); + return (Criteria) this; + } + + public Criteria andSortLessThan(Integer value) { + addCriterion("sort <", value, "sort"); + return (Criteria) this; + } + + public Criteria andSortLessThanOrEqualTo(Integer value) { + addCriterion("sort <=", value, "sort"); + return (Criteria) this; + } + + public Criteria andSortIn(List values) { + addCriterion("sort in", values, "sort"); + return (Criteria) this; + } + + public Criteria andSortNotIn(List values) { + addCriterion("sort not in", values, "sort"); + return (Criteria) this; + } + + public Criteria andSortBetween(Integer value1, Integer value2) { + addCriterion("sort between", value1, value2, "sort"); + return (Criteria) this; + } + + public Criteria andSortNotBetween(Integer value1, Integer value2) { + addCriterion("sort not between", value1, value2, "sort"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} \ No newline at end of file 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 6ebfbcf4d3..8867cc75c4 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysUser.java +++ b/backend/src/main/java/io/dataease/base/domain/SysUser.java @@ -1,59 +1,45 @@ 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 Integer from; + + private String sub; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/domain/SysUserExample.java b/backend/src/main/java/io/dataease/base/domain/SysUserExample.java index 27cef73bb8..1b8fc36618 100644 --- a/backend/src/main/java/io/dataease/base/domain/SysUserExample.java +++ b/backend/src/main/java/io/dataease/base/domain/SysUserExample.java @@ -1153,6 +1153,136 @@ public class SysUserExample { addCriterion("`language` not between", value1, value2, "language"); return (Criteria) this; } + + public Criteria andFromIsNull() { + addCriterion("`from` is null"); + return (Criteria) this; + } + + public Criteria andFromIsNotNull() { + addCriterion("`from` is not null"); + return (Criteria) this; + } + + public Criteria andFromEqualTo(Integer value) { + addCriterion("`from` =", value, "from"); + return (Criteria) this; + } + + public Criteria andFromNotEqualTo(Integer value) { + addCriterion("`from` <>", value, "from"); + return (Criteria) this; + } + + public Criteria andFromGreaterThan(Integer value) { + addCriterion("`from` >", value, "from"); + return (Criteria) this; + } + + public Criteria andFromGreaterThanOrEqualTo(Integer value) { + addCriterion("`from` >=", value, "from"); + return (Criteria) this; + } + + public Criteria andFromLessThan(Integer value) { + addCriterion("`from` <", value, "from"); + return (Criteria) this; + } + + public Criteria andFromLessThanOrEqualTo(Integer value) { + addCriterion("`from` <=", value, "from"); + return (Criteria) this; + } + + public Criteria andFromIn(List values) { + addCriterion("`from` in", values, "from"); + return (Criteria) this; + } + + public Criteria andFromNotIn(List values) { + addCriterion("`from` not in", values, "from"); + return (Criteria) this; + } + + public Criteria andFromBetween(Integer value1, Integer value2) { + addCriterion("`from` between", value1, value2, "from"); + return (Criteria) this; + } + + public Criteria andFromNotBetween(Integer value1, Integer value2) { + addCriterion("`from` not between", value1, value2, "from"); + return (Criteria) this; + } + + public Criteria andSubIsNull() { + addCriterion("sub is null"); + return (Criteria) this; + } + + public Criteria andSubIsNotNull() { + addCriterion("sub is not null"); + return (Criteria) this; + } + + public Criteria andSubEqualTo(String value) { + addCriterion("sub =", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotEqualTo(String value) { + addCriterion("sub <>", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubGreaterThan(String value) { + addCriterion("sub >", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubGreaterThanOrEqualTo(String value) { + addCriterion("sub >=", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubLessThan(String value) { + addCriterion("sub <", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubLessThanOrEqualTo(String value) { + addCriterion("sub <=", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubLike(String value) { + addCriterion("sub like", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotLike(String value) { + addCriterion("sub not like", value, "sub"); + return (Criteria) this; + } + + public Criteria andSubIn(List values) { + addCriterion("sub in", values, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotIn(List values) { + addCriterion("sub not in", values, "sub"); + return (Criteria) this; + } + + public Criteria andSubBetween(String value1, String value2) { + addCriterion("sub between", value1, value2, "sub"); + return (Criteria) this; + } + + public Criteria andSubNotBetween(String value1, String value2) { + addCriterion("sub not between", value1, value2, "sub"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/src/main/java/io/dataease/base/mapper/ChartViewMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ChartViewMapper.xml index 10137408e3..72b2eaaca0 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ChartViewMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ChartViewMapper.xml @@ -16,6 +16,7 @@ + @@ -87,7 +88,7 @@ style_priority - x_axis, y_axis, ext_stack, ext_bubble, custom_attr, custom_style, custom_filter, + x_axis, y_axis, y_axis_ext, ext_stack, ext_bubble, custom_attr, custom_style, custom_filter, drill_fields, snapshot + select + + distinct + + + , + + from panel_pdf_template + + + + + order by ${orderByClause} + + + + + + delete from panel_pdf_template + where id = #{id,jdbcType=VARCHAR} + + + delete from panel_pdf_template + + + + + + insert into panel_pdf_template (id, `name`, create_time, + create_user, sort, template_content + ) + values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, + #{createUser,jdbcType=VARCHAR}, #{sort,jdbcType=INTEGER}, #{templateContent,jdbcType=LONGVARCHAR} + ) + + + insert into panel_pdf_template + + + id, + + + `name`, + + + create_time, + + + create_user, + + + sort, + + + template_content, + + + + + #{id,jdbcType=VARCHAR}, + + + #{name,jdbcType=VARCHAR}, + + + #{createTime,jdbcType=BIGINT}, + + + #{createUser,jdbcType=VARCHAR}, + + + #{sort,jdbcType=INTEGER}, + + + #{templateContent,jdbcType=LONGVARCHAR}, + + + + + + update panel_pdf_template + + + id = #{record.id,jdbcType=VARCHAR}, + + + `name` = #{record.name,jdbcType=VARCHAR}, + + + create_time = #{record.createTime,jdbcType=BIGINT}, + + + create_user = #{record.createUser,jdbcType=VARCHAR}, + + + sort = #{record.sort,jdbcType=INTEGER}, + + + template_content = #{record.templateContent,jdbcType=LONGVARCHAR}, + + + + + + + + update panel_pdf_template + set id = #{record.id,jdbcType=VARCHAR}, + `name` = #{record.name,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + create_user = #{record.createUser,jdbcType=VARCHAR}, + sort = #{record.sort,jdbcType=INTEGER}, + template_content = #{record.templateContent,jdbcType=LONGVARCHAR} + + + + + + update panel_pdf_template + set id = #{record.id,jdbcType=VARCHAR}, + `name` = #{record.name,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + create_user = #{record.createUser,jdbcType=VARCHAR}, + sort = #{record.sort,jdbcType=INTEGER} + + + + + + update panel_pdf_template + + + `name` = #{name,jdbcType=VARCHAR}, + + + create_time = #{createTime,jdbcType=BIGINT}, + + + create_user = #{createUser,jdbcType=VARCHAR}, + + + sort = #{sort,jdbcType=INTEGER}, + + + template_content = #{templateContent,jdbcType=LONGVARCHAR}, + + + where id = #{id,jdbcType=VARCHAR} + + + update panel_pdf_template + set `name` = #{name,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + create_user = #{createUser,jdbcType=VARCHAR}, + sort = #{sort,jdbcType=INTEGER}, + template_content = #{templateContent,jdbcType=LONGVARCHAR} + where id = #{id,jdbcType=VARCHAR} + + + update panel_pdf_template + set `name` = #{name,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + create_user = #{createUser,jdbcType=VARCHAR}, + sort = #{sort,jdbcType=INTEGER} + where id = #{id,jdbcType=VARCHAR} + + \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml b/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml index 41f42fc47a..b779a3a538 100644 --- a/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/SysUserMapper.xml @@ -18,6 +18,8 @@ + + @@ -79,7 +81,8 @@ user_id, dept_id, username, nick_name, gender, phone, email, `password`, is_admin, - enabled, create_by, update_by, pwd_reset_time, create_time, update_time, `language` + enabled, create_by, update_by, pwd_reset_time, create_time, update_time, `language`, + `from`, sub @@ -285,6 +302,12 @@ `language` = #{record.language,jdbcType=VARCHAR}, + + `from` = #{record.from,jdbcType=INTEGER}, + + + sub = #{record.sub,jdbcType=VARCHAR}, + @@ -307,7 +330,9 @@ pwd_reset_time = #{record.pwdResetTime,jdbcType=BIGINT}, create_time = #{record.createTime,jdbcType=BIGINT}, update_time = #{record.updateTime,jdbcType=BIGINT}, - `language` = #{record.language,jdbcType=VARCHAR} + `language` = #{record.language,jdbcType=VARCHAR}, + `from` = #{record.from,jdbcType=INTEGER}, + sub = #{record.sub,jdbcType=VARCHAR} @@ -360,6 +385,12 @@ `language` = #{language,jdbcType=VARCHAR}, + + `from` = #{from,jdbcType=INTEGER}, + + + sub = #{sub,jdbcType=VARCHAR}, + where user_id = #{userId,jdbcType=BIGINT} @@ -379,7 +410,9 @@ pwd_reset_time = #{pwdResetTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT}, update_time = #{updateTime,jdbcType=BIGINT}, - `language` = #{language,jdbcType=VARCHAR} + `language` = #{language,jdbcType=VARCHAR}, + `from` = #{from,jdbcType=INTEGER}, + sub = #{sub,jdbcType=VARCHAR} where user_id = #{userId,jdbcType=BIGINT} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java index d082a0faea..2b1355256f 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.java @@ -25,6 +25,8 @@ public interface AuthMapper { SysUserEntity findUserByName(@Param("username") String username); + SysUserEntity findUserBySub(@Param("sub") String sub); + List roles(@Param("userId") Long userId); diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml index 981dfc5c93..3492d7ec10 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/AuthMapper.xml @@ -28,6 +28,10 @@ select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin from sys_user where username = #{username} + + - select id , name , `desc` ,`type` , configuration ,create_time ,update_time, + select datasource.*, authInfo.privileges as `privileges` from (select GET_V_AUTH_MODEL_ID_P_USE (#{extendCondition}, 'link') cids) t,datasource left join ( @@ -55,7 +55,7 @@ @@ -27,7 +27,7 @@ FIND_IN_SET(chart_view.id,cids) - order by create_time desc + order by `type` desc,name asc diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java index b12402e76e..40e31cd7af 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java @@ -7,4 +7,6 @@ import java.util.List; public interface ExtSysUserMapper { List query(GridExample example); + + List ldapUserNames(Integer from); } diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml index b7af624db4..cc1bfa5e25 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml @@ -62,4 +62,8 @@ left join sys_role r on r.role_id = sur.role_id where sur.user_id = #{user_id} + + diff --git a/backend/src/main/java/io/dataease/commons/constants/AuthConstants.java b/backend/src/main/java/io/dataease/commons/constants/AuthConstants.java index b78abf26f8..4e06f9216f 100644 --- a/backend/src/main/java/io/dataease/commons/constants/AuthConstants.java +++ b/backend/src/main/java/io/dataease/commons/constants/AuthConstants.java @@ -6,6 +6,7 @@ public class AuthConstants { public final static String USER_CACHE_NAME = "users_info"; public final static String USER_ROLE_CACHE_NAME = "users_roles_info"; public final static String USER_PERMISSION_CACHE_NAME = "users_permissions_info"; + public final static String ID_TOKEN_KEY = "IdToken"; } diff --git a/backend/src/main/java/io/dataease/commons/constants/DeTypeConstants.java b/backend/src/main/java/io/dataease/commons/constants/DeTypeConstants.java index 50a925c2ee..a03ca54f05 100644 --- a/backend/src/main/java/io/dataease/commons/constants/DeTypeConstants.java +++ b/backend/src/main/java/io/dataease/commons/constants/DeTypeConstants.java @@ -7,6 +7,7 @@ public class DeTypeConstants { public final static Integer DE_INT = 2; public final static Integer DE_FLOAT = 3; public final static Integer DE_BOOL = 4; - public final static Integer DE_Binary = 5; + public final static Integer DE_LOCATION = 5; + public final static Integer DE_BINARY = 6; } diff --git a/backend/src/main/java/io/dataease/commons/license/DefaultLicenseService.java b/backend/src/main/java/io/dataease/commons/license/DefaultLicenseService.java index f79f9afc54..fd30061367 100644 --- a/backend/src/main/java/io/dataease/commons/license/DefaultLicenseService.java +++ b/backend/src/main/java/io/dataease/commons/license/DefaultLicenseService.java @@ -45,9 +45,12 @@ public class DefaultLicenseService { } return f2CLicenseResponse; }catch (Exception e){ - e.printStackTrace(); - return F2CLicenseResponse.invalid(e.getMessage()); + LogUtil.error(e.getMessage()); + // e.printStackTrace(); + // return F2CLicenseResponse.invalid(e.getMessage()); + return F2CLicenseResponse.noRecord(); } + } diff --git a/backend/src/main/java/io/dataease/commons/utils/DateUtils.java b/backend/src/main/java/io/dataease/commons/utils/DateUtils.java index e750ced0c6..4da7f5721b 100644 --- a/backend/src/main/java/io/dataease/commons/utils/DateUtils.java +++ b/backend/src/main/java/io/dataease/commons/utils/DateUtils.java @@ -95,7 +95,7 @@ public class DateUtils { } - public static void main(String[] args) throws Exception { + /* public static void main(String[] args) throws Exception { // System.out.println("start:"); Date paramTime = getTime(getTimeString(new Long("1607672440731"))); @@ -110,7 +110,7 @@ public class DateUtils { // System.out.println(getTimeString(--countTimeLong)); - } + } */ /** diff --git a/backend/src/main/java/io/dataease/commons/utils/ExcelReaderUtil.java b/backend/src/main/java/io/dataease/commons/utils/ExcelReaderUtil.java index 53249d256b..c2f80fbdff 100644 --- a/backend/src/main/java/io/dataease/commons/utils/ExcelReaderUtil.java +++ b/backend/src/main/java/io/dataease/commons/utils/ExcelReaderUtil.java @@ -68,8 +68,8 @@ public class ExcelReaderUtil { } } - public static void main(String[] args) throws Exception { + /* public static void main(String[] args) throws Exception { String file ="Metersphere_case_DataEase功能用例.xlsx"; ExcelReaderUtil.readExcel(file, new FileInputStream("/Users/taojinlong/Desktop/" + file)); - } + } */ } diff --git a/backend/src/main/java/io/dataease/controller/panel/PanelPdfTemplateController.java b/backend/src/main/java/io/dataease/controller/panel/PanelPdfTemplateController.java new file mode 100644 index 0000000000..9d9bef9d16 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/panel/PanelPdfTemplateController.java @@ -0,0 +1,33 @@ +package io.dataease.controller.panel; + +import com.github.xiaoymin.knife4j.annotations.ApiSupport; +import io.dataease.base.domain.PanelPdfTemplate; +import io.dataease.service.panel.PanelPdfTemplateService; +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + + +/** + * Author: wangjiahao + * Date: 2021-03-05 + * Description: + */ +@Api(tags = "仪表板:PDF导出模板") +@ApiSupport(order = 170) +@RestController +@RequestMapping("pdf-template") +public class PanelPdfTemplateController { + + @Resource + private PanelPdfTemplateService panelPdfTemplateService; + + @GetMapping("queryAll") + public List queryAll(){ + return panelPdfTemplateService.queryAll(); + } + + +} diff --git a/backend/src/main/java/io/dataease/controller/sys/MsgController.java b/backend/src/main/java/io/dataease/controller/sys/MsgController.java index 729edbae37..b100aea861 100644 --- a/backend/src/main/java/io/dataease/controller/sys/MsgController.java +++ b/backend/src/main/java/io/dataease/controller/sys/MsgController.java @@ -6,7 +6,6 @@ import com.github.xiaoymin.knife4j.annotations.ApiSupport; import io.dataease.base.domain.SysMsgChannel; import io.dataease.base.domain.SysMsgSetting; import io.dataease.base.domain.SysMsgType; -import io.dataease.commons.exception.DEException; import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.PageUtils; import io.dataease.commons.utils.Pager; @@ -71,6 +70,12 @@ public class MsgController { sysMsgService.setBatchReaded(msgIds); } + @ApiOperation("全部设置已读") + @PostMapping("/allRead") + public void allRead() { + sysMsgService.setAllRead(); + } + @ApiOperation("批量删除") @PostMapping("/batchDelete") public void batchDelete(@RequestBody List msgIds) { 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 0a1052f787..fc8978f56c 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysUserController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysUserController.java @@ -10,6 +10,7 @@ import io.dataease.commons.utils.AuthUtils; 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.LdapAddRequest; import io.dataease.controller.sys.request.SysUserCreateRequest; import io.dataease.controller.sys.request.SysUserPwdRequest; import io.dataease.controller.sys.request.SysUserStateRequest; @@ -127,4 +128,18 @@ public class SysUserController { Pager> listPager = PageUtils.setPageInfo(page, sysRoleService.query(request)); return listPager; } + + + @ApiOperation("同步用户") + @PostMapping("/sync") + public void importLdap(@RequestBody LdapAddRequest request) { + sysUserService.saveLdapUsers(request); + } + + @ApiOperation("已同步用户") + @PostMapping("/existLdapUsers") + public List getExistLdapUsers() { + return sysUserService.ldapUserNames(); + } + } diff --git a/backend/src/main/java/io/dataease/controller/sys/request/LdapAddRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/LdapAddRequest.java new file mode 100644 index 0000000000..e115541fcf --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/sys/request/LdapAddRequest.java @@ -0,0 +1,19 @@ +package io.dataease.controller.sys.request; + +import io.dataease.plugins.common.entity.XpackLdapUserEntity; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +public class LdapAddRequest implements Serializable { + + private Long deptId; + + private List roleIds; + + private Long enabled; + + private List users; +} 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 3724c7f8ea..c9da730433 100644 --- a/backend/src/main/java/io/dataease/datasource/constants/DatasourceTypes.java +++ b/backend/src/main/java/io/dataease/datasource/constants/DatasourceTypes.java @@ -6,7 +6,9 @@ public enum DatasourceTypes { 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", "\"", "\"", "\"", "\""); + oracle("oracle", "oracle", "oracle.jdbc.driver.OracleDriver", "\"", "\"", "\"", "\""), + ck("ch", "ch", "ru.yandex.clickhouse.ClickHouseDriver", "`", "`", "'", "'"), + es("es", "es", "", "\"", "\"", "\"", "\""); private String feature; private String desc; diff --git a/backend/src/main/java/io/dataease/datasource/dto/CHConfigration.java b/backend/src/main/java/io/dataease/datasource/dto/CHConfigration.java new file mode 100644 index 0000000000..5031769a5e --- /dev/null +++ b/backend/src/main/java/io/dataease/datasource/dto/CHConfigration.java @@ -0,0 +1,19 @@ +package io.dataease.datasource.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CHConfigration extends JdbcDTO { + + private String driver = "ru.yandex.clickhouse.ClickHouseDriver"; + + public String getJdbc() { + // 连接参数先写死,后边要把编码、时区等参数放到数据源的设置中 + return "jdbc:clickhouse://HOSTNAME:PORT/DATABASE" + .replace("HOSTNAME", getHost().trim()) + .replace("PORT", getPort().toString().trim()) + .replace("DATABASE", getDataBase().trim()); + } +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/datasource/dto/EsConfigDTO.java b/backend/src/main/java/io/dataease/datasource/dto/EsConfigDTO.java new file mode 100644 index 0000000000..b879eeb309 --- /dev/null +++ b/backend/src/main/java/io/dataease/datasource/dto/EsConfigDTO.java @@ -0,0 +1,16 @@ +package io.dataease.datasource.dto; + + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class EsConfigDTO { + private String url; + private String username; + private String password; + private String version; + private String uri; + private String dataSourceType = "es"; +} diff --git a/backend/src/main/java/io/dataease/datasource/dto/MysqlConfigration.java b/backend/src/main/java/io/dataease/datasource/dto/MysqlConfigration.java index a94e3d0c4a..fcaeec3906 100644 --- a/backend/src/main/java/io/dataease/datasource/dto/MysqlConfigration.java +++ b/backend/src/main/java/io/dataease/datasource/dto/MysqlConfigration.java @@ -11,7 +11,7 @@ public class MysqlConfigration extends JdbcDTO { public String getJdbc() { // 连接参数先写死,后边要把编码、时区等参数放到数据源的设置中 - return "jdbc:mysql://HOSTNAME:PORT/DATABASE?characterEncoding=UTF-8&connectTimeout=5000" + return "jdbc:mysql://HOSTNAME:PORT/DATABASE?characterEncoding=UTF-8&connectTimeout=5000&useSSL=false" .replace("HOSTNAME", getHost().trim()) .replace("PORT", getPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); diff --git a/backend/src/main/java/io/dataease/datasource/dto/es/EsReponse.java b/backend/src/main/java/io/dataease/datasource/dto/es/EsReponse.java new file mode 100644 index 0000000000..d40f214d53 --- /dev/null +++ b/backend/src/main/java/io/dataease/datasource/dto/es/EsReponse.java @@ -0,0 +1,29 @@ +package io.dataease.datasource.dto.es; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class EsReponse { + private Listcolumns = new ArrayList<>(); + private Listrows = new ArrayList<>(); + private String cursor; + private Integer status; + private Error error; + private String version; + + @Data + public class Error{ + private String type; + private String reason; + } + + @Data + public class Column { + private String name; + private String type; + } + +} diff --git a/backend/src/main/java/io/dataease/datasource/dto/es/Requst.java b/backend/src/main/java/io/dataease/datasource/dto/es/Requst.java new file mode 100644 index 0000000000..1e0bb8a608 --- /dev/null +++ b/backend/src/main/java/io/dataease/datasource/dto/es/Requst.java @@ -0,0 +1,9 @@ +package io.dataease.datasource.dto.es; + +import lombok.Data; + +@Data +public class Requst { + private String query; + private Integer fetch_size = 10000; +} diff --git a/backend/src/main/java/io/dataease/datasource/dto/es/RequstWithCursor.java b/backend/src/main/java/io/dataease/datasource/dto/es/RequstWithCursor.java new file mode 100644 index 0000000000..cb79c3460e --- /dev/null +++ b/backend/src/main/java/io/dataease/datasource/dto/es/RequstWithCursor.java @@ -0,0 +1,8 @@ +package io.dataease.datasource.dto.es; + +import lombok.Data; + +@Data +public class RequstWithCursor extends Requst{ + private String cursor; +} diff --git a/backend/src/main/java/io/dataease/datasource/provider/EsProvider.java b/backend/src/main/java/io/dataease/datasource/provider/EsProvider.java new file mode 100644 index 0000000000..4e0bf23afb --- /dev/null +++ b/backend/src/main/java/io/dataease/datasource/provider/EsProvider.java @@ -0,0 +1,258 @@ +package io.dataease.datasource.provider; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.gson.Gson; +import com.mchange.v2.c3p0.ComboPooledDataSource; +import io.dataease.commons.utils.HttpClientConfig; +import io.dataease.commons.utils.HttpClientUtil; +import io.dataease.datasource.dto.*; +import io.dataease.datasource.dto.es.EsReponse; +import io.dataease.datasource.dto.es.Requst; +import io.dataease.datasource.dto.es.RequstWithCursor; +import io.dataease.datasource.request.DatasourceRequest; +import io.dataease.exception.DataEaseException; +import io.dataease.i18n.Translator; +import io.dataease.provider.es.EsQueryProvider; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpHeaders; +import org.springframework.stereotype.Service; + +import java.nio.charset.StandardCharsets; +import java.util.*; + +@Service("es") +public class EsProvider extends DatasourceProvider { + + private static Map jdbcConnection = new HashMap<>(); + private static int initPoolSize = 5; + private static int maxConnections = 200; + + /** + * 增加缓存机制 key 由 'provider_sql_' dsr.datasource.id dsr.table dsr.query共4部分组成,命中则使用缓存直接返回不再执行sql逻辑 + * @param dsr + * @return + * @throws Exception + */ + /** + * 这里使用声明式缓存不是很妥当 + * 改为chartViewService中使用编程式缓存 + @Cacheable( + value = JdbcConstants.JDBC_PROVIDER_KEY, + key = "'provider_sql_' + #dsr.datasource.id + '_' + #dsr.table + '_' + #dsr.query", + condition = "#dsr.pageSize == null || #dsr.pageSize == 0L" + ) + */ + @Override + public List getData(DatasourceRequest dsr) throws Exception { + List list = new LinkedList<>(); + try { + EsConfigDTO esConfigDTO = new Gson().fromJson(dsr.getDatasource().getConfiguration(), EsConfigDTO.class); + + HttpClientConfig httpClientConfig = new HttpClientConfig(); + String auth = esConfigDTO.getUsername() + ":" + esConfigDTO.getPassword(); + byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8)); + httpClientConfig.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + new String(encodedAuth)); + Requst requst = new Requst(); + requst.setQuery(dsr.getQuery()); + requst.setFetch_size(dsr.getFetchSize()); + String url = esConfigDTO.getUrl().endsWith("/") ? esConfigDTO.getUrl() + esConfigDTO.getUri() + "?format=json" : esConfigDTO.getUrl() + "/" + esConfigDTO.getUri() + "?format=json"; + String response = HttpClientUtil.post(url, new Gson().toJson(requst), httpClientConfig); + EsReponse esReponse = new Gson().fromJson(response, EsReponse.class); + + list.addAll(fetchResult(esReponse)); + if(dsr.isPageable()){ + Integer realSize = dsr.getPage() * dsr.getPageSize() < list.size() ? dsr.getPage() * dsr.getPageSize(): list.size(); + list = list.subList((dsr.getPage() - 1) * dsr.getPageSize(), realSize); + } + if(!dsr.isPreviewData()){ + while (StringUtils.isNotEmpty(esReponse.getCursor())) { + RequstWithCursor requstWithCursor = new RequstWithCursor(); + requstWithCursor.setQuery(dsr.getQuery()); + requstWithCursor.setFetch_size(dsr.getFetchSize()); + requstWithCursor.setCursor(esReponse.getCursor()); + response = HttpClientUtil.post(url, new Gson().toJson(requstWithCursor), httpClientConfig); + esReponse = new Gson().fromJson(response, EsReponse.class); + list.addAll(fetchResult(esReponse)); + } + } + } catch (Exception e) { + DataEaseException.throwException(e); + } + return list; + } + + @Override + public List fetchResult(DatasourceRequest datasourceRequest) throws Exception { + List list = new LinkedList<>(); + try { + String response = exexQuery(datasourceRequest, datasourceRequest.getQuery(), "?format=json"); + list = fetchResult(response); + } catch (Exception e) { + DataEaseException.throwException(e); + } + return list; + } + + private List fetchResult(String response) throws Exception { + EsReponse esReponse = new Gson().fromJson(response, EsReponse.class); + return fetchResult(esReponse); + } + + private List fetchResult(EsReponse esReponse) throws Exception { + List list = new LinkedList<>(); + if(esReponse.getError() != null){ + throw new Exception(esReponse.getError().getReason()); + } + list.addAll(esReponse.getRows()); + return list; + } + + @Override + public List fetchResultField(DatasourceRequest datasourceRequest) throws Exception { + List tableFileds = new ArrayList<>(); + try { + String response = exexQuery(datasourceRequest, datasourceRequest.getQuery(), "?format=json"); + tableFileds = fetchResultField(response); + } catch (Exception e) { + DataEaseException.throwException(e); + } + return tableFileds; + } + + private List fetchResultField(String response) throws Exception { + List fieldList = new ArrayList<>(); + EsReponse esReponse = new Gson().fromJson(response, EsReponse.class); + if(esReponse.getError() != null){ + throw new Exception(esReponse.getError().getReason()); + } + + for (String[] row : esReponse.getRows()) { + TableFiled field = new TableFiled(); + field.setFieldName(row[0]); + field.setRemarks(row[0]); + field.setFieldType(row[2]); + field.setFieldSize(EsQueryProvider.transFieldTypeSize(row[2])); + fieldList.add(field); + } + return fieldList; + } + + @Override + public Map fetchResultAndField(DatasourceRequest datasourceRequest) throws Exception { + Map result = new HashMap<>(); + try { + String response = exexQuery(datasourceRequest, datasourceRequest.getQuery(), "?format=json"); + result.put("dataList", fetchResult(response)); + result.put("fieldList", fetchResultField(response)); + } catch (Exception e) { + DataEaseException.throwException(e); + } + return result; + } + + @Override + public void handleDatasource(DatasourceRequest datasourceRequest, String type) throws Exception { + } + + @Override + public List getTables(DatasourceRequest datasourceRequest) throws Exception { + List tables = new ArrayList<>(); + try { + String response = exexQuery(datasourceRequest, "show tables", "?format=json"); + tables = fetchTables(response); + } catch (Exception e) { + DataEaseException.throwException(e); + } + return tables; + } + + private List fetchTables(String response) throws Exception { + List tables = new ArrayList<>(); + EsReponse esReponse = new Gson().fromJson(response, EsReponse.class); + if(esReponse.getError() != null){ + throw new Exception(esReponse.getError().getReason()); + } + + for (String[] row : esReponse.getRows()) { + if(row.length == 3 && row[1].equalsIgnoreCase("TABLE") && row[2].equalsIgnoreCase("INDEX")){ + tables.add(row[0]); + } + if(row.length == 2 && row[1].equalsIgnoreCase("BASE TABLE")){ + tables.add(row[0]); + } + } + return tables; + } + + @Override + public List getSchema(DatasourceRequest datasourceRequest) throws Exception { + return new ArrayList<>(); + } + + @Override + public List getTableFileds(DatasourceRequest datasourceRequest) throws Exception { + List tableFileds = new ArrayList<>(); + try { + String response = exexQuery(datasourceRequest, "desc " + datasourceRequest.getTable(), "?format=json"); + tableFileds = fetchResultField(response); + } catch (Exception e) { + DataEaseException.throwException(e); + } + return tableFileds; + } + + @Override + public void checkStatus(DatasourceRequest datasourceRequest) throws Exception { + EsConfigDTO esConfigDTO = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), EsConfigDTO.class); + String response = exexGetQuery(datasourceRequest); + String version = JSONObject.parseObject(response).getJSONObject("version").getString("number"); + if(Integer.valueOf(version.substring(0,1)) < 6 ){ + throw new Exception(Translator.get("i18n_es_limit")); + } + if(Integer.valueOf(version.substring(2,3)) < 3 ){ + throw new Exception(Translator.get("i18n_es_limit")); + } + if(Integer.valueOf(version.substring(0,1)) == 6 ) { + esConfigDTO.setUri("_xpack/sql"); + } + if(Integer.valueOf(version.substring(0,1)) == 7 ) { + esConfigDTO.setUri("_sql"); + } + datasourceRequest.getDatasource().setConfiguration(new Gson().toJson(esConfigDTO)); + getTables(datasourceRequest); + } + + private String exexQuery(DatasourceRequest datasourceRequest, String sql, String uri){ + EsConfigDTO esConfigDTO = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), EsConfigDTO.class); + uri = esConfigDTO.getUri()+uri; + HttpClientConfig httpClientConfig = new HttpClientConfig(); + if(StringUtils.isNotEmpty(esConfigDTO.getUsername()) && StringUtils.isNotEmpty(esConfigDTO.getPassword())){ + String auth = esConfigDTO.getUsername() + ":" + esConfigDTO.getPassword(); + byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8)); + httpClientConfig.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + new String(encodedAuth)); + } + + Requst requst = new Requst(); + requst.setQuery(sql); + requst.setFetch_size(datasourceRequest.getFetchSize()); + String url = esConfigDTO.getUrl().endsWith("/") ? esConfigDTO.getUrl() + uri : esConfigDTO.getUrl() + "/" + uri; + String response = HttpClientUtil.post(url, new Gson().toJson(requst), httpClientConfig); + return response; + } + + private String exexGetQuery(DatasourceRequest datasourceRequest){ + EsConfigDTO esConfigDTO = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), EsConfigDTO.class); + HttpClientConfig httpClientConfig = new HttpClientConfig(); + if(StringUtils.isNotEmpty(esConfigDTO.getUsername()) && StringUtils.isNotEmpty(esConfigDTO.getPassword())){ + String auth = esConfigDTO.getUsername() + ":" + esConfigDTO.getPassword(); + byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8)); + httpClientConfig.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + new String(encodedAuth)); + } + + String response = HttpClientUtil.get(esConfigDTO.getUrl(), httpClientConfig); + return response; + } + +} 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 5918a7f361..9ccda9d154 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java +++ b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java @@ -7,6 +7,7 @@ import io.dataease.datasource.dto.*; import io.dataease.datasource.request.DatasourceRequest; import io.dataease.exception.DataEaseException; import io.dataease.i18n.Translator; +import io.dataease.provider.QueryProvider; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import java.beans.PropertyVetoException; @@ -40,7 +41,7 @@ public class JdbcProvider extends DatasourceProvider { List list = new LinkedList<>(); Connection connection = null; try { - connection = getConnectionFromPool(dsr); + connection = getConnection(dsr); Statement stat = connection.createStatement(); ResultSet rs = stat.executeQuery(dsr.getQuery()); list = fetchResult(rs); @@ -127,7 +128,7 @@ public class JdbcProvider extends DatasourceProvider { connection = getConnectionFromPool(datasourceRequest); Statement stat = connection.createStatement(); rs = stat.executeQuery(datasourceRequest.getQuery()); - return fetchResultField(rs); + return fetchResultField(rs, datasourceRequest); } catch (SQLException e) { DataEaseException.throwException(e); } catch (Exception e) { @@ -152,7 +153,7 @@ public class JdbcProvider extends DatasourceProvider { Statement stat = connection.createStatement(); rs = stat.executeQuery(datasourceRequest.getQuery()); dataList = fetchResult(rs); - fieldList = fetchResultField(rs); + fieldList = fetchResultField(rs, datasourceRequest); result.put("dataList", dataList); result.put("fieldList", fieldList); return result; @@ -168,10 +169,11 @@ public class JdbcProvider extends DatasourceProvider { return new HashMap<>(); } - private List fetchResultField(ResultSet rs) throws Exception { + private List fetchResultField(ResultSet rs, DatasourceRequest datasourceRequest) throws Exception { List fieldList = new ArrayList<>(); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); + QueryProvider qp = ProviderFactory.getQueryProvider(datasourceRequest.getDatasource().getType()); for (int j = 0; j < columnCount; j++) { String f = metaData.getColumnName(j + 1); String l = StringUtils.isNotEmpty(metaData.getColumnLabel(j + 1)) ? metaData.getColumnLabel(j + 1) : f; @@ -180,7 +182,12 @@ public class JdbcProvider extends DatasourceProvider { field.setFieldName(l); field.setRemarks(l); field.setFieldType(t); - field.setFieldSize(metaData.getColumnDisplaySize(j + 1)); + + if(datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.ck.name())){ + field.setFieldSize(qp.transFieldSize(t)); + }else { + field.setFieldSize(metaData.getColumnDisplaySize(j + 1)); + } if(t.equalsIgnoreCase("LONG")){field.setFieldSize(65533);} //oracle LONG if(StringUtils.isNotEmpty(t) && t.toLowerCase().contains("date") && field.getFieldSize() < 50 ){ field.setFieldSize(50); @@ -196,7 +203,7 @@ public class JdbcProvider extends DatasourceProvider { String queryStr = getTablesSql(datasourceRequest); Connection con = null; try { - con = getConnectionFromPool(datasourceRequest); + con = getConnection(datasourceRequest); Statement statement = con.createStatement(); ResultSet resultSet = statement.executeQuery(queryStr); while (resultSet.next()) { @@ -250,15 +257,20 @@ public class JdbcProvider extends DatasourceProvider { ResultSet resultSet = databaseMetaData.getColumns(null, "%", datasourceRequest.getTable(), "%"); while (resultSet.next()) { String tableName = resultSet.getString("TABLE_NAME"); - String database = resultSet.getString("TABLE_CAT"); + String database = null; + if(datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.ck.name())){ + database = resultSet.getString("TABLE_SCHEM"); + }else { + database = resultSet.getString("TABLE_CAT"); + } if(database != null){ if (tableName.equals(datasourceRequest.getTable()) && database.equalsIgnoreCase(getDatabase(datasourceRequest))) { - TableFiled tableFiled = getTableFiled(resultSet); + TableFiled tableFiled = getTableFiled(resultSet, datasourceRequest); list.add(tableFiled); } }else { if (tableName.equals(datasourceRequest.getTable())) { - TableFiled tableFiled = getTableFiled(resultSet); + TableFiled tableFiled = getTableFiled(resultSet, datasourceRequest); list.add(tableFiled); } } @@ -276,7 +288,7 @@ public class JdbcProvider extends DatasourceProvider { return list; } - private TableFiled getTableFiled(ResultSet resultSet) throws SQLException { + private TableFiled getTableFiled(ResultSet resultSet, DatasourceRequest datasourceRequest) throws SQLException { TableFiled tableFiled = new TableFiled(); String colName = resultSet.getString("COLUMN_NAME"); tableFiled.setFieldName(colName); @@ -285,13 +297,19 @@ public class JdbcProvider extends DatasourceProvider { remarks = colName; } tableFiled.setRemarks(remarks); - tableFiled.setFieldSize(Integer.valueOf(resultSet.getString("COLUMN_SIZE"))); String dbType = resultSet.getString("TYPE_NAME").toUpperCase(); tableFiled.setFieldType(dbType); if(dbType.equalsIgnoreCase("LONG")){tableFiled.setFieldSize(65533);} if(StringUtils.isNotEmpty(dbType) && dbType.toLowerCase().contains("date") && tableFiled.getFieldSize() < 50 ){ tableFiled.setFieldSize(50); } + + if(datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.ck.name())){ + QueryProvider qp = ProviderFactory.getQueryProvider(datasourceRequest.getDatasource().getType()); + tableFiled.setFieldSize(qp.transFieldSize(dbType)); + }else { + tableFiled.setFieldSize(Integer.valueOf(resultSet.getString("COLUMN_SIZE"))); + } return tableFiled; } @@ -436,6 +454,14 @@ public class JdbcProvider extends DatasourceProvider { password = pgConfigration.getPassword(); driver = pgConfigration.getDriver(); jdbcurl = pgConfigration.getJdbc(); + break; + case ck: + CHConfigration chConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), CHConfigration.class); + username = chConfigration.getUsername(); + password = chConfigration.getPassword(); + driver = chConfigration.getDriver(); + jdbcurl = chConfigration.getJdbc(); + break; default: break; } @@ -493,6 +519,14 @@ public class JdbcProvider extends DatasourceProvider { dataSource.setJdbcUrl(pgConfigration.getJdbc()); jdbcDTO = pgConfigration; break; + case ck: + CHConfigration chConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), CHConfigration.class); + dataSource.setUser(chConfigration.getUsername()); + dataSource.setDriverClass(chConfigration.getDriver()); + dataSource.setPassword(chConfigration.getPassword()); + dataSource.setJdbcUrl(chConfigration.getJdbc()); + jdbcDTO = chConfigration; + break; default: break; } @@ -515,7 +549,8 @@ public class JdbcProvider extends DatasourceProvider { PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class); return pgConfigration.getDataBase(); default: - return null; + JdbcDTO jdbcDTO = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcDTO.class); + return jdbcDTO.getDataBase(); } } @@ -528,6 +563,9 @@ public class JdbcProvider extends DatasourceProvider { return "show tables;"; case sqlServer: SqlServerConfigration sqlServerConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), SqlServerConfigration.class); + if(StringUtils.isEmpty(sqlServerConfigration.getSchema())){ + throw new Exception(Translator.get("i18n_schema_is_empty")); + } return "SELECT TABLE_NAME FROM DATABASE.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = 'DS_SCHEMA' ;" .replace("DATABASE", sqlServerConfigration.getDataBase()) .replace("DS_SCHEMA", sqlServerConfigration.getSchema()); @@ -543,6 +581,9 @@ public class JdbcProvider extends DatasourceProvider { 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()); + case ck: + CHConfigration chConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), CHConfigration.class); + return "SELECT name FROM system.tables where database='DATABASE';".replace("DATABASE", chConfigration.getDataBase()); 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 d780399648..b05acd9d44 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/ProviderFactory.java +++ b/backend/src/main/java/io/dataease/datasource/provider/ProviderFactory.java @@ -30,6 +30,8 @@ public class ProviderFactory implements ApplicationContextAware { return context.getBean("jdbc", DatasourceProvider.class); case pg: return context.getBean("jdbc", DatasourceProvider.class); + case es: + return context.getBean("es", DatasourceProvider.class); default: return context.getBean("jdbc", DatasourceProvider.class); } @@ -48,6 +50,10 @@ public class ProviderFactory implements ApplicationContextAware { return context.getBean("pgQuery", QueryProvider.class); case oracle: return context.getBean("oracleQuery", QueryProvider.class); + case es: + return context.getBean("esQuery", QueryProvider.class); + case ck: + return context.getBean("ckQuery", QueryProvider.class); default: return context.getBean("mysqlQuery", QueryProvider.class); } diff --git a/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java b/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java index 9521b50af5..ebf237e3fd 100644 --- a/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java +++ b/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java @@ -11,8 +11,12 @@ public class DatasourceRequest { protected String query; protected String table; protected Datasource datasource; - private Long pageSize; - private Long startPage; + private Integer pageSize; + private Integer page; + private Integer realSize; + private Integer fetchSize = 10000; + private boolean pageable = false; + private boolean previewData = false; } diff --git a/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java b/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java index 529cdb16af..ab02e97586 100644 --- a/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java +++ b/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java @@ -7,6 +7,7 @@ import io.dataease.base.mapper.*; import io.dataease.base.mapper.ext.ExtDataSourceMapper; import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.commons.exception.DEException; +import io.dataease.commons.model.AuthURD; import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.CommonThreadPool; import io.dataease.commons.utils.LogUtil; @@ -25,6 +26,8 @@ import io.dataease.dto.dataset.DataTableInfoDTO; import io.dataease.exception.DataEaseException; import io.dataease.i18n.Translator; import io.dataease.service.dataset.DataSetGroupService; +import io.dataease.service.message.DeMsgutil; + import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -34,7 +37,10 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.UUID; @Service @@ -59,9 +65,10 @@ public class DatasourceService { datasource.setUpdateTime(currentTimeMillis); datasource.setCreateTime(currentTimeMillis); datasource.setCreateBy(String.valueOf(AuthUtils.getUser().getUsername())); + checkAndUpdateDatasourceStatus(datasource); datasourceMapper.insertSelective(datasource); handleConnectionPool(datasource, "add"); - checkAndUpdateDatasourceStatus(datasource); + return datasource; } @@ -123,9 +130,9 @@ public class DatasourceService { checkName(datasource); datasource.setCreateTime(null); datasource.setUpdateTime(System.currentTimeMillis()); + checkAndUpdateDatasourceStatus(datasource); datasourceMapper.updateByPrimaryKeySelective(datasource); handleConnectionPool(datasource, "edit"); - checkAndUpdateDatasourceStatus(datasource); } public ResultHolder validate(Datasource datasource) throws Exception { @@ -238,7 +245,8 @@ public class DatasourceService { public void updateDatasourceStatus(){ List datasources = datasourceMapper.selectByExampleWithBLOBs(new DatasourceExample()); datasources.forEach(datasource -> { - checkAndUpdateDatasourceStatus(datasource); + // checkAndUpdateDatasourceStatus(datasource); + checkAndUpdateDatasourceStatus(datasource, true); }); } @@ -249,10 +257,47 @@ public class DatasourceService { datasourceRequest.setDatasource(datasource); datasourceProvider.checkStatus(datasourceRequest); datasource.setStatus("Success"); - datasourceMapper.updateByPrimaryKeySelective(datasource); } catch (Exception e) { datasource.setStatus("Error"); - datasourceMapper.updateByPrimaryKeySelective(datasource); } } + + private void checkAndUpdateDatasourceStatus(Datasource datasource, Boolean withMsg){ + try { + DatasourceProvider datasourceProvider = ProviderFactory.getProvider(datasource.getType()); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDatasource(datasource); + datasourceProvider.checkStatus(datasourceRequest); + datasource.setStatus("Success"); + datasourceMapper.updateByPrimaryKeySelective(datasource); + } catch (Exception e) { + Datasource temp = datasourceMapper.selectByPrimaryKey(datasource.getId()); + datasource.setStatus("Error"); + if (!StringUtils.equals(temp.getStatus(), "Error")) { + sendWebMsg(datasource); + datasourceMapper.updateByPrimaryKeySelective(datasource); + } + + } + } + + + private void sendWebMsg(Datasource datasource) { + + String id = datasource.getId(); + AuthURD authURD = AuthUtils.authURDR(id); + Set userIds = AuthUtils.userIdsByURD(authURD); + Long typeId = 8L;// 代表数据源失效 + Gson gson = new Gson(); + userIds.forEach(userId -> { + Map param = new HashMap<>(); + param.put("id", id); + param.put("name", datasource.getName()); + + + String content = "数据源【" + datasource.getName() + "】无效"; + + DeMsgutil.sendMsg(userId, typeId, 1L, content, gson.toJson(param)); + }); + } } diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java index 2d90dfbcbf..221ff0d218 100644 --- a/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java +++ b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java @@ -44,4 +44,6 @@ public class ChartViewFieldDTO implements Serializable { private String datePattern; private Integer extField; + + private String chartType; } diff --git a/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java b/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java index 8637a0beb1..f50d6d04ed 100644 --- a/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java +++ b/backend/src/main/java/io/dataease/plugins/config/LoadjarUtil.java @@ -2,6 +2,7 @@ package io.dataease.plugins.config; import io.dataease.base.domain.MyPlugin; import io.dataease.plugins.loader.ClassloaderResponsity; +import io.dataease.plugins.loader.ControllerLoader; import io.dataease.plugins.loader.ModuleClassLoader; import io.dataease.plugins.loader.MybatisLoader; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +20,9 @@ public class LoadjarUtil { @Autowired private MybatisLoader mybatisLoader; + @Autowired + private ControllerLoader controllerLoader; + public List loadJar(String jarPath, MyPlugin myPlugin) throws Exception{ File jar = new File(jarPath); URI uri = jar.toURI(); @@ -34,6 +38,10 @@ public class LoadjarUtil { Thread.currentThread().setContextClassLoader(classLoader); classLoader.initBean(); mybatisLoader.loadMybatis(myPlugin); + + List controllers = classLoader.getRegisteredController(); + controllerLoader.registerController(controllers); + ClassloaderResponsity.getInstance().addClassLoader(moduleName,classLoader); diff --git a/backend/src/main/java/io/dataease/plugins/loader/ControllerLoader.java b/backend/src/main/java/io/dataease/plugins/loader/ControllerLoader.java new file mode 100644 index 0000000000..99c5cce463 --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/loader/ControllerLoader.java @@ -0,0 +1,95 @@ +package io.dataease.plugins.loader; + + +import io.dataease.commons.utils.LogUtil; +import io.dataease.plugins.config.SpringContextUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import java.lang.reflect.Method; +import java.util.List; + +@Component +public class ControllerLoader { + + /** + * 去掉Controller的Mapping + * @param controllerBeanName + */ + private void unregisterController(String controllerBeanName){ + final RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping)SpringContextUtil.getBean("requestMappingHandlerMapping"); + + if(requestMappingHandlerMapping!=null){ + String handler=controllerBeanName; + Object controller= SpringContextUtil.getBean(handler); + if(controller==null){ + return; + } + final Class targetClass=controller.getClass(); + ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass); + try { + Method createMappingMethod = RequestMappingHandlerMapping.class. + getDeclaredMethod("getMappingForMethod", Method.class, Class.class); + createMappingMethod.setAccessible(true); + RequestMappingInfo requestMappingInfo =(RequestMappingInfo) + createMappingMethod.invoke(requestMappingHandlerMapping,specificMethod,targetClass); + if(requestMappingInfo != null) { + requestMappingHandlerMapping.unregisterMapping(requestMappingInfo); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + }, ReflectionUtils.USER_DECLARED_METHODS); + } + } + + /** + * 注册Controller + * @param controllerBeanName + * @throws Exception + */ + private void registerController(String controllerBeanName) throws Exception{ + final RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping) SpringContextUtil.getBean("requestMappingHandlerMapping"); + + if(requestMappingHandlerMapping!=null){ + String handler=controllerBeanName; + Object controller= SpringContextUtil.getBean(handler); + if(controller==null){ + return; + } + unregisterController(controllerBeanName); + //注册Controller + Method method=requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().getDeclaredMethod("detectHandlerMethods",Object.class); + + method.setAccessible(true); + method.invoke(requestMappingHandlerMapping,handler); + } + } + + public void registerController(List beanNames) { + beanNames.forEach(name -> { + try { + registerController(name); + } catch (Exception e) { + // e.printStackTrace(); + LogUtil.error(e); + } + }); + } + + + + + + + + + + + +} diff --git a/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java b/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java index 794c7b49e1..5a357ae773 100644 --- a/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java +++ b/backend/src/main/java/io/dataease/plugins/loader/ModuleClassLoader.java @@ -7,10 +7,14 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.type.TypeAliasRegistry; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.stereotype.Component; +import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -35,6 +39,8 @@ public class ModuleClassLoader extends URLClassLoader { //需要注册的spring bean的name集合 private List registeredBean = new ArrayList<>(); + private List registeredController = new ArrayList<>(); + //构造 public ModuleClassLoader(URL[] urls, ClassLoader parent) { @@ -150,8 +156,12 @@ public class ModuleClassLoader extends URLClassLoader { beanName = StringUtils.uncapitalize(beanName); SpringContextUtil.getBeanFactory().registerBeanDefinition(beanName,beanDefinition); + + if (isHandler(cla)) { + registeredController.add(beanName); + } + registeredBean.add(beanName); -// System.out.println("注册bean:"+beanName); } } @@ -164,6 +174,10 @@ public class ModuleClassLoader extends URLClassLoader { return registeredBean; } + public List getRegisteredController() { + return registeredController; + } + /** * 方法描述 判断class对象是否带有spring的注解 @@ -184,6 +198,9 @@ public class ModuleClassLoader extends URLClassLoader { if( Modifier.isAbstract(cla.getModifiers())){ return false; } + if (isHandler(cla)) { + return true; + } if(cla.getAnnotation(Component.class)!=null){ return true; @@ -194,8 +211,15 @@ public class ModuleClassLoader extends URLClassLoader { if(cla.getAnnotation(Service.class)!=null){ return true; } + if(cla.getAnnotation(Service.class)!=null){ + return true; + } return false; } + protected boolean isHandler(Class beanType) { + return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class); + } + } 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 225542842f..b33e60244c 100644 --- a/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/PluginCommonServer.java @@ -2,6 +2,7 @@ package io.dataease.plugins.server; import io.dataease.commons.utils.ServletUtils; import io.dataease.plugins.common.dto.PluginSysMenu; +import io.dataease.plugins.common.service.PluginComponentService; import io.dataease.plugins.common.service.PluginMenuService; import io.dataease.plugins.config.SpringContextUtil; import org.springframework.web.bind.annotation.GetMapping; @@ -9,7 +10,6 @@ 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; @@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference; public class PluginCommonServer { @GetMapping("/async/{menuId}") - public void componentInfo(@PathVariable Long menuId) { + public void menuInfo(@PathVariable Long menuId) { Map pluginMenuServiceMap = SpringContextUtil.getApplicationContext().getBeansOfType(PluginMenuService.class); pluginMenuServiceMap.values().stream().forEach(service -> { AtomicReference atomicReference = new AtomicReference<>(); @@ -65,4 +65,41 @@ public class PluginCommonServer { return; }); } + + @GetMapping("/component/{componentName}") + public void componentInfo(@PathVariable String componentName) { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(PluginComponentService.class); + beansOfType.values().stream().forEach(service -> { + List components = service.components(); + if (components.contains(componentName)) { + HttpServletResponse response = ServletUtils.response(); + BufferedInputStream bis = null; + InputStream inputStream = null; + OutputStream os = null; //输出流 + try{ + inputStream = service.vueResource(componentName); + byte[] buffer = new byte[1024]; + os = response.getOutputStream(); + bis = new BufferedInputStream(inputStream); + int i = bis.read(buffer); + while(i != -1){ + os.write(buffer, 0, i); + i = bis.read(buffer); + } + os.flush(); + }catch (Exception e) { + e.printStackTrace(); + }finally { + try { + bis.close(); + inputStream.close(); + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return; + } + }); + } } diff --git a/backend/src/main/java/io/dataease/plugins/server/SSOServer.java b/backend/src/main/java/io/dataease/plugins/server/SSOServer.java new file mode 100644 index 0000000000..b50257be85 --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/server/SSOServer.java @@ -0,0 +1,85 @@ +package io.dataease.plugins.server; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; +import io.dataease.auth.entity.SysUserEntity; +import io.dataease.auth.entity.TokenInfo; +import io.dataease.auth.service.AuthUserService; +import io.dataease.auth.util.JWTUtils; +import io.dataease.commons.exception.DEException; +import io.dataease.commons.utils.CodingUtil; +import io.dataease.commons.utils.ServletUtils; +import io.dataease.plugins.config.SpringContextUtil; +import io.dataease.plugins.xpack.display.dto.response.SysSettingDto; +import io.dataease.plugins.xpack.oidc.dto.SSOToken; +import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo; +import io.dataease.plugins.xpack.oidc.service.OidcXpackService; +import io.dataease.service.sys.SysUserService; + +@RequestMapping("/sso") +@Controller +public class SSOServer { + + @Autowired + private AuthUserService authUserService; + + @Autowired + private SysUserService sysUserService; + + @GetMapping("/callBack") + public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((OidcXpackService.class)); + if(beansOfType.keySet().size() == 0) { + DEException.throwException("缺少oidc插件"); + } + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + Boolean suuportOIDC = oidcXpackService.isSuuportOIDC(); + if (!suuportOIDC) { + DEException.throwException("未开启oidc"); + } + Map config = config(oidcXpackService); + SSOToken ssoToken = oidcXpackService.requestSsoToken(config, code, state); + + SSOUserInfo ssoUserInfo = oidcXpackService.requestUserInfo(config, ssoToken.getAccessToken()); + SysUserEntity sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub()); + if(null == sysUserEntity){ + sysUserService.saveOIDCUser(ssoUserInfo); + sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub()); + } + TokenInfo tokenInfo = TokenInfo.builder().userId(sysUserEntity.getUserId()).username(sysUserEntity.getUsername()).build(); + String realPwd = CodingUtil.md5(sysUserService.defaultPWD()); + String token = JWTUtils.sign(tokenInfo, realPwd); + ServletUtils.setToken(token); + HttpServletResponse response = ServletUtils.response(); + + Cookie cookie_token = new Cookie("Authorization", token);cookie_token.setPath("/"); + Cookie cookie_id_token = new Cookie("IdToken", ssoToken.getIdToken());cookie_id_token.setPath("/"); + Cookie cookie_ac_token = new Cookie("AccessToken", ssoToken.getAccessToken());cookie_ac_token.setPath("/"); + + response.addCookie(cookie_token); + response.addCookie(cookie_id_token); + response.addCookie(cookie_ac_token); + ModelAndView modelAndView = new ModelAndView("redirect:/"); + return modelAndView; + } + private Map config(OidcXpackService oidcXpackService) { + List sysSettingDtos = oidcXpackService.oidcSettings(); + Map config = sysSettingDtos.stream().collect(Collectors.toMap(SysSettingDto::getParamKey, SysSettingDto::getParamValue)); + return config; + } + + + + +} diff --git a/backend/src/main/java/io/dataease/plugins/server/XLdapServer.java b/backend/src/main/java/io/dataease/plugins/server/XLdapServer.java new file mode 100644 index 0000000000..f06ab40dfa --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/server/XLdapServer.java @@ -0,0 +1,41 @@ +package io.dataease.plugins.server; + + +import io.dataease.plugins.common.entity.XpackLdapUserEntity; +import io.dataease.plugins.config.SpringContextUtil; +import io.dataease.plugins.xpack.display.dto.response.SysSettingDto; +import io.dataease.plugins.xpack.ldap.dto.response.LdapInfo; +import io.dataease.plugins.xpack.ldap.service.LdapXpackService; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RequestMapping("/plugin/ldap") +@RestController +public class XLdapServer { + + + @GetMapping("/info") + public LdapInfo getLdapInfo() { + LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); + return ldapXpackService.info(); + } + + @PostMapping("/save") + public void save(@RequestBody List settings) { + LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); + ldapXpackService.save(settings); + } + + @PostMapping("/testConn") + public void testConn() { + LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); + ldapXpackService.testConn(); + } + + @PostMapping("/users") + public List users() { + LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); + return ldapXpackService.users(); + } +} diff --git a/backend/src/main/java/io/dataease/plugins/server/XOidcServer.java b/backend/src/main/java/io/dataease/plugins/server/XOidcServer.java new file mode 100644 index 0000000000..debb306ccc --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/server/XOidcServer.java @@ -0,0 +1,59 @@ +package io.dataease.plugins.server; + + +import io.dataease.plugins.config.SpringContextUtil; +import io.dataease.plugins.xpack.display.dto.response.SysSettingDto; +import io.dataease.plugins.xpack.oidc.service.OidcXpackService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RequestMapping("/plugin/oidc") +@RestController +public class XOidcServer { + + + @PostMapping("/info") + public List getOidcInfo() { + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + return oidcXpackService.oidcSettings(); + } + + @PostMapping("/save") + public void save(@RequestBody List settings) { + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + oidcXpackService.save(settings); + } + + @PostMapping(value="/authInfo") + public Map authInfo() { + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + Map result = new HashMap(); + List oidcSettings = oidcXpackService.oidcSettings(); + + Map authParam = new HashMap<>(); + authParam.put("response_type", "code"); + authParam.put("state", "state"); + // authParam.put("redirect_uri", "http://localhost:9528"); + + + oidcSettings.forEach(param -> { + if(StringUtils.isNotBlank(param.getParamKey())) { + if (StringUtils.equals(param.getParamKey(), "oidc.authEndpoint")) { + result.put("authEndpoint", param.getParamValue()); + } + if (StringUtils.equals(param.getParamKey(), "oidc.scope")) { + authParam.put("scope", param.getParamValue()); + } + if (StringUtils.equals(param.getParamKey(), "oidc.clientId")) { + authParam.put("client_id", param.getParamValue()); + } + } + + }); + result.put("authParam", authParam); + return result; + } +} diff --git a/backend/src/main/java/io/dataease/plugins/util/PluginUtils.java b/backend/src/main/java/io/dataease/plugins/util/PluginUtils.java index 52c422b870..57a8cabca5 100644 --- a/backend/src/main/java/io/dataease/plugins/util/PluginUtils.java +++ b/backend/src/main/java/io/dataease/plugins/util/PluginUtils.java @@ -46,6 +46,16 @@ public class PluginUtils { return f2CLicenseResponse; } + public static Boolean licValid() { + try{ + F2CLicenseResponse f2CLicenseResponse = PluginUtils.currentLic(); + if (f2CLicenseResponse.getStatus() != F2CLicenseResponse.Status.valid) return false; + }catch (Exception e) { + return false; + } + return true; + } + diff --git a/backend/src/main/java/io/dataease/provider/QueryProvider.java b/backend/src/main/java/io/dataease/provider/QueryProvider.java index 9caa1ebb68..6894222ce6 100644 --- a/backend/src/main/java/io/dataease/provider/QueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/QueryProvider.java @@ -38,6 +38,10 @@ public abstract class QueryProvider { public abstract String getSQLAsTmp(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList); + public abstract String getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, Datasource ds); + + public abstract String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds); + public abstract String getSQLStack(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extStack, Datasource ds); public abstract String getSQLAsTmpStack(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extStack); @@ -50,6 +54,9 @@ public abstract class QueryProvider { public abstract String getSQLSummary(String table, List yAxis, List customFilter, List extFilterRequestList); + public Integer transFieldSize(String type){ + return 50; + }; /** * 单指标汇总 * diff --git a/backend/src/main/java/io/dataease/provider/ck/CKConstants.java b/backend/src/main/java/io/dataease/provider/ck/CKConstants.java new file mode 100644 index 0000000000..362477e27c --- /dev/null +++ b/backend/src/main/java/io/dataease/provider/ck/CKConstants.java @@ -0,0 +1,41 @@ +package io.dataease.provider.ck; + +import io.dataease.provider.SQLConstants; + +import static io.dataease.datasource.constants.DatasourceTypes.ck; + +/** + * @Author gin + * @Date 2021/7/8 7:22 下午 + */ +public class CKConstants extends SQLConstants { + public static final String KEYWORD_TABLE = ck.getKeywordPrefix() + "%s" + ck.getKeywordSuffix(); + + public static final String KEYWORD_FIX = "%s." + ck.getKeywordPrefix() + "%s" + ck.getKeywordSuffix(); + + public static final String toInt32 = "toInt32(%s)"; + + public static final String toDateTime = "toDateTime(%s)"; + + public static final String toInt64 = "toInt64(%s)"; + + public static final String toFloat64 = "toFloat64(%s)"; + + public static final String formatDateTime = "formatDateTime(%s,'%s')"; + + public static final String toDecimal = "toDecimal64(%s,2)"; + + public static final String DEFAULT_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"; + + 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/ck/CKQueryProvider.java b/backend/src/main/java/io/dataease/provider/ck/CKQueryProvider.java new file mode 100644 index 0000000000..410b05a06e --- /dev/null +++ b/backend/src/main/java/io/dataease/provider/ck/CKQueryProvider.java @@ -0,0 +1,1027 @@ +package io.dataease.provider.ck; + +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; + +/** + * @Author gin + * @Date 2021/5/17 2:43 下午 + */ +@Service("ckQuery") +public class CKQueryProvider extends QueryProvider { + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + @Override + public Integer transFieldType(String field) { + if(field.indexOf("ARRAY") > -1){ + field = "ARRAY"; + } + if(field.indexOf("DATETIME64") > -1){ + field = "DATETIME64"; + } + switch (field) { + case "STRING": + case "VARCHAR": + case "TEXT": + case "TINYTEXT": + case "MEDIUMTEXT": + case "LONGTEXT": + case "ENUM": + return 0;// 文本 + case "DATE": + case "DATETIME": + case "DATETIME64": + case "TIMESTAMP": + return 1;// 时间 + case "INT8": + case "INT16": + case "INT32": + case "INT64": + case "UINT8": + case "UINT16": + case "UINT32": + case "UINT64": + return 2;// 整型 + case "FLOAT32": + case "Float64": + case "DECIMAL": + return 3;// 浮点 + case "BIT": + case "TINYINT": + return 4;// 布尔 + default: + return 0; + } + } + + @Override + public Integer transFieldSize(String field){ + Integer type = transFieldType(field); + switch (type) { + case 0: + return 65533; + case 1: + return 60; + case 2: + return 0; + case 3: + return 0; + case 4: + return 0; + default: + return 65533; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") AS tmp ORDER BY null " + " LIMIT 0,1000"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(CKConstants.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) { + if(f.getType().equalsIgnoreCase("DATE")){ + fieldName = String.format(CKConstants.toInt32, String.format(CKConstants.toDateTime, originField)) + "*1000"; + }else { + fieldName = String.format(CKConstants.toInt32, originField) + "*1000"; + } + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(CKConstants.toInt64, originField); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(CKConstants.toFloat64, originField); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(CKConstants.toDateTime, originField); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + String cast = String.format(CKConstants.toFloat64, originField); + fieldName = String.format(CKConstants.toDateTime, cast); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(CKConstants.toInt64, originField); + } 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 " + (page - 1) * pageSize + "," + realSize; + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds) { + return createQuerySQL(table, fields, isGroup, null) + " LIMIT 0," + limit; + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup) { + return createQuerySQLAsTmp(sql, fields, isGroup) + " LIMIT 0," + limit; + } + + @Override + public String createQuerySQLAsTmpWithPage(String sql, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup) { + return createQuerySQLAsTmp(sql, fields, isGroup) + " LIMIT " + (page - 1) * pageSize + "," + realSize; + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(CKConstants.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(CKConstants.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 getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(CKConstants.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 customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + 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); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + 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("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(CKConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, customFilter, extFilterRequestList, null); + } + + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList, null); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extStack, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(CKConstants.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(CKConstants.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, null); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extBubble, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(CKConstants.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(CKConstants.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, null); + } + + @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(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(CKConstants.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(CKConstants.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, Datasource ds) { + 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()); + } + return stringBuilder.toString(); + }).toArray(String[]::new); + return MessageFormat.format("SELECT {0} FROM {1} ORDER BY null", StringUtils.join(array, ","), table); + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null); + } + + 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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == DeTypeConstants.DE_TIME) { + if (field.getDeExtractType() == DeTypeConstants.DE_STRING || field.getDeExtractType() == 5) { + whereName = String.format(CKConstants.toDateTime, originName); + } + if (field.getDeExtractType() == DeTypeConstants.DE_INT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == 4) { + String cast = String.format(CKConstants.toFloat64, originName); + whereName = String.format(CKConstants.toDateTime, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else { + whereName = originName; + } + if (StringUtils.equalsIgnoreCase(request.getTerm(), "null")) { + whereValue = CKConstants.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(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + + if (field.getDeType() == DeTypeConstants.DE_TIME) { + if (field.getDeExtractType() == DeTypeConstants.DE_STRING || field.getDeExtractType() == 5) { + whereName = String.format(CKConstants.toDateTime, originName); + } + if (field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == 4) { + String cast = String.format(CKConstants.toFloat64, originName); + whereName = String.format(CKConstants.toDateTime, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } 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() == DeTypeConstants.DE_TIME) { + 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(CKConstants.WHERE_BETWEEN, startTime, endTime); + } else { + whereValue = String.format(CKConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(CKConstants.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 = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "%Y-%m-%d %H:%M:%S"; + } + + switch (dateStyle) { + case "y": + return "%Y"; + case "y_M": + return "%Y" + split + "%m"; + case "y_M_d": + return "%Y" + split + "%m" + split + "%d"; + case "H_m_s": + return "%H:%M:%S"; + case "y_M_d_H_m": + return "%Y" + split + "%m" + split + "%d" + " %H:%M"; + case "y_M_d_H_m_s": + return "%Y" + split + "%m" + split + "%d" + " %H:%M:%S"; + default: + return "%Y-%m-%d %H:%M:%S"; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (x.getDeType() == DeTypeConstants.DE_INT || x.getDeType() == DeTypeConstants.DE_FLOAT) { + if(x.getType().equalsIgnoreCase("DATE")){ + fieldName = String.format(CKConstants.toInt32, String.format(CKConstants.toDateTime, originField)) + "*1000"; + }else { + fieldName = String.format(CKConstants.toInt32, originField) + "*1000"; + } + } else if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + fieldName = String.format(CKConstants.formatDateTime, 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(CKConstants.formatDateTime, String.format(CKConstants.toDateTime, originField), format); + } else { + fieldName = String.format(CKConstants.formatDateTime, String.format(CKConstants.toDateTime, String.format(CKConstants.toFloat64, originField)), 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 = CKConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + fieldName = String.format(CKConstants.AGG_FIELD, y.getSummary(), originField); + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = y.getDeType() == 2? String.format(CKConstants.toInt64, originField) : String.format(CKConstants.toFloat64, originField); + String agg = String.format(CKConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(CKConstants.toDecimal, agg); + } else { + String cast = y.getDeType() == 2 ? String.format(CKConstants.toInt64, originField) : String.format(CKConstants.toFloat64, originField); + fieldName = String.format(CKConstants.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 = CKConstants.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(CKConstants.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(CKConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } +} diff --git a/backend/src/main/java/io/dataease/provider/doris/DorisConstants.java b/backend/src/main/java/io/dataease/provider/doris/DorisConstants.java index fda5ea41ef..6f9a65f1c8 100644 --- a/backend/src/main/java/io/dataease/provider/doris/DorisConstants.java +++ b/backend/src/main/java/io/dataease/provider/doris/DorisConstants.java @@ -19,6 +19,8 @@ public class DorisConstants extends SQLConstants { public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')"; + public static final String STR_TO_DATE = "STR_TO_DATE(%s,'%s')"; + public static final String CAST = "CAST(%s AS %s)"; public static final String DEFAULT_DATE_FORMAT = "%Y-%m-%d %H:%i:%S"; @@ -31,6 +33,8 @@ public class DorisConstants extends SQLConstants { public static final String WHERE_VALUE_VALUE = "'%s'"; + public static final String WHERE_NUMBER_VALUE = "%s"; + public static final String AGG_COUNT = "COUNT(*)"; public static final String AGG_FIELD = "%s(%s)"; diff --git a/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java b/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java index 8fe11624f3..ce05913ede 100644 --- a/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java @@ -281,6 +281,83 @@ public class DorisQueryProvider extends QueryProvider { return st.render(); } + @Override + public String getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(DorisConstants.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(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getDataeaseName()); + } else { + originField = String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getDataeaseName()); + } + 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 customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + 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); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + 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("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(DorisConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, customFilter, extFilterRequestList, null); + } + @Override public String getSQLAsTmp(String sql, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { return getSQL("(" + sql + ")", xAxis, yAxis, customFilter, extFilterRequestList, null); @@ -686,9 +763,14 @@ public class DorisQueryProvider extends QueryProvider { originName = String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getDataeaseName()); } - if (field.getDeType() == 1 && field.getDeExtractType() != 1) { - String cast = String.format(DorisConstants.CAST, originName, DorisConstants.DEFAULT_INT_FORMAT) + "/1000"; - whereName = String.format(DorisConstants.FROM_UNIXTIME, cast, DorisConstants.DEFAULT_DATE_FORMAT); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5 || field.getDeExtractType() == 1) { + whereName = String.format(DorisConstants.STR_TO_DATE, originName, DorisConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(DorisConstants.CAST, originName, DorisConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(DorisConstants.FROM_UNIXTIME, cast, DorisConstants.DEFAULT_DATE_FORMAT); + } } else if (field.getDeType() == 0) { whereName = String.format(DorisConstants.CAST, originName, DorisConstants.VARCHAR); } else { @@ -703,7 +785,11 @@ public class DorisQueryProvider extends QueryProvider { } else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) { whereValue = "'%" + value + "%'"; } else { - whereValue = String.format(DorisConstants.WHERE_VALUE_VALUE, value); + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereValue = String.format(DorisConstants.WHERE_NUMBER_VALUE, value); + } else { + whereValue = String.format(DorisConstants.WHERE_VALUE_VALUE, value); + } } list.add(SQLObj.builder() .whereField(whereName) @@ -738,9 +824,14 @@ public class DorisQueryProvider extends QueryProvider { originName = String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getDataeaseName()); } - if (field.getDeType() == 1 && field.getDeExtractType() != 1) { - String cast = String.format(DorisConstants.CAST, originName, DorisConstants.DEFAULT_INT_FORMAT) + "/1000"; - whereName = String.format(DorisConstants.FROM_UNIXTIME, cast, DorisConstants.DEFAULT_DATE_FORMAT); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5 || field.getDeExtractType() == 1) { + whereName = String.format(DorisConstants.STR_TO_DATE, originName, DorisConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(DorisConstants.CAST, originName, DorisConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(DorisConstants.FROM_UNIXTIME, cast, DorisConstants.DEFAULT_DATE_FORMAT); + } } else if (field.getDeType() == 0) { whereName = String.format(DorisConstants.CAST, originName, DorisConstants.VARCHAR); } else { @@ -762,7 +853,11 @@ public class DorisQueryProvider extends QueryProvider { whereValue = String.format(DorisConstants.WHERE_BETWEEN, value.get(0), value.get(1)); } } else { - whereValue = String.format(DorisConstants.WHERE_VALUE_VALUE, value.get(0)); + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereValue = String.format(DorisConstants.WHERE_NUMBER_VALUE, value.get(0)); + } else { + whereValue = String.format(DorisConstants.WHERE_VALUE_VALUE, value.get(0)); + } } list.add(SQLObj.builder() .whereField(whereName) @@ -778,6 +873,12 @@ public class DorisQueryProvider extends QueryProvider { split = "-"; } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "%Y-%m-%d %H:%i:%S"; } switch (dateStyle) { diff --git a/backend/src/main/java/io/dataease/provider/es/EsQueryProvider.java b/backend/src/main/java/io/dataease/provider/es/EsQueryProvider.java new file mode 100644 index 0000000000..9f8924c6eb --- /dev/null +++ b/backend/src/main/java/io/dataease/provider/es/EsQueryProvider.java @@ -0,0 +1,949 @@ +package io.dataease.provider.es; + +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("esQuery") +public class EsQueryProvider extends QueryProvider { + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + @Override + public Integer transFieldType(String field) { + switch (field) { + case "keyword": + case "text": + case "binary": + case "object": + case "nested": + case "null": + case "ip": + case "unsupported": + return DeTypeConstants.DE_STRING; + case "boolean": + case "byte": + case "short": + case "integer": + case "long": + return DeTypeConstants.DE_INT; + case "double": + case "float": + case "half_float": + case "scaled_float": + return DeTypeConstants.DE_FLOAT; + case "datetime": + return DeTypeConstants.DE_TIME; + default: + return 0; + } + } + + public static Integer transFieldTypeSize(String field) { + switch (field) { + case "null": + return 1; + case "boolean": + return 1; + case "byte": + return 3; + case "short": + return 5; + case "integer": + return 10; + case "long": + return 19; + case "double": + case "float": + case "half_float": + case "scaled_float": + return 15; + case "keyword": + case "text": + case "binary": + case "object": + case "nested": + return 65532; + case "datetime": + return 50; + case "ip": + return 50; + case "unsupported": + return 50; + default: + return 0; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") AS tmp ORDER BY null " + " LIMIT 1000"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(EsSqlLConstants.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() == DeTypeConstants.DE_INT) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == DeTypeConstants.DE_TIME) { + originField = String.format(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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(EsSqlLConstants.CAST, originField, "bigint"); + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(EsSqlLConstants.CAST, originField, "bigint"); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(EsSqlLConstants.CAST, originField, "double"); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(EsSqlLConstants.CAST, originField, "timestamp"); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + String cast = String.format(EsSqlLConstants.CAST, originField, "timestamp"); + fieldName = String.format(EsSqlLConstants.DATETIME_FORMAT, cast, EsSqlLConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(EsSqlLConstants.CAST, originField, "timestamp"); + } 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); + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds) { + return createQuerySQL(table, fields, isGroup, null); + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup) { + return createQuerySQLAsTmp(sql, fields, isGroup); + } + + @Override + public String createQuerySQLAsTmpWithPage(String sql, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup) { + return createQuerySQLAsTmp(sql, fields, isGroup); + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(EsSqlLConstants.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() == DeTypeConstants.DE_INT) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == DeTypeConstants.DE_TIME) { + originField = String.format(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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() == DeTypeConstants.DE_INT) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == DeTypeConstants.DE_TIME) { + originField = String.format(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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(EsSqlLConstants.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, null); + } + + @Override + public String getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return null; + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return null; + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extStack, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(EsSqlLConstants.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() == DeTypeConstants.DE_INT) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == DeTypeConstants.DE_TIME) { + originField = String.format(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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() == DeTypeConstants.DE_INT) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == DeTypeConstants.DE_TIME) { + originField = String.format(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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(EsSqlLConstants.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, null); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extBubble, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(EsSqlLConstants.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(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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(EsSqlLConstants.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, null); + } + + @Override + public String searchTable(String table) { + return ""; + } + + @Override + public String getSQLSummary(String table, List yAxis, List customFilter, List extFilterRequestList) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(EsSqlLConstants.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(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(EsSqlLConstants.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(EsSqlLConstants.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, Datasource ds) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName()); + return stringBuilder.toString(); + }).toArray(String[]::new); + return MessageFormat.format("SELECT {0} FROM {1} ORDER BY null", StringUtils.join(array, ","), table); + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null); + } + + 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(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == DeTypeConstants.DE_TIME) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(EsSqlLConstants.CAST, originName, "timestamp"); + } + if (field.getDeExtractType() == DeTypeConstants.DE_INT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == DeTypeConstants.DE_BOOL) { + String cast = String.format(EsSqlLConstants.CAST, originName, "timestamp"); + whereName = String.format(EsSqlLConstants.DATETIME_FORMAT, cast, EsSqlLConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else { + whereName = originName; + } + if (StringUtils.equalsIgnoreCase(request.getTerm(), "null")) { + whereValue = EsSqlLConstants.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(EsSqlLConstants.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(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(EsSqlLConstants.CAST, originName, "timestamp"); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(EsSqlLConstants.CAST, originName, "timestamp"); + whereName = String.format(EsSqlLConstants.DATETIME_FORMAT, cast, EsSqlLConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } 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(EsSqlLConstants.WHERE_BETWEEN, startTime, endTime); + } else { + whereValue = String.format(EsSqlLConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(EsSqlLConstants.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 = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "YYYY-MM-dd HH:mm:ss"; + } + + 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 "HH:mm:ss"; + case "y_M_d_H_m": + return "YYYY" + split + "MM" + split + "dd" + " HH:mm"; + case "y_M_d_H_m_s": + return "YYYY" + split + "MM" + split + "dd" + " HH:mm:ss"; + default: + return "YYYY-MM-dd HH:mm:ss"; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (x.getDeType() == DeTypeConstants.DE_INT || x.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(EsSqlLConstants.CAST, originField, "bigint"); + } else if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + fieldName = String.format(EsSqlLConstants.DATETIME_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) { + String cast = String.format(EsSqlLConstants.CAST, originField, "timestamp"); + fieldName = String.format(EsSqlLConstants.DATETIME_FORMAT, cast, format); + } else { + String cast = String.format(EsSqlLConstants.CAST, originField, "timestamp"); + fieldName = String.format(EsSqlLConstants.DATETIME_FORMAT, cast, 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 = EsSqlLConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + fieldName = String.format(EsSqlLConstants.AGG_FIELD, y.getSummary(), originField); + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format(EsSqlLConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? "bigint" : "double"); + String agg = String.format(EsSqlLConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(EsSqlLConstants.CAST, agg, EsSqlLConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format(EsSqlLConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? "bigint" : "double"); + fieldName = String.format(EsSqlLConstants.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 = EsSqlLConstants.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(EsSqlLConstants.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(EsSqlLConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } +} diff --git a/backend/src/main/java/io/dataease/provider/es/EsSqlLConstants.java b/backend/src/main/java/io/dataease/provider/es/EsSqlLConstants.java new file mode 100644 index 0000000000..042ab0b1a1 --- /dev/null +++ b/backend/src/main/java/io/dataease/provider/es/EsSqlLConstants.java @@ -0,0 +1,39 @@ +package io.dataease.provider.es; + +import io.dataease.provider.SQLConstants; + +import static io.dataease.datasource.constants.DatasourceTypes.es; + +/** + * @Author gin + * @Date 2021/7/8 7:22 下午 + */ +public class EsSqlLConstants extends SQLConstants { + public static final String KEYWORD_TABLE = es.getKeywordPrefix() + "%s" + es.getKeywordSuffix(); + + public static final String KEYWORD_FIX = "%s." + es.getKeywordPrefix() + "%s" + es.getKeywordSuffix(); + + public static final String UNIX_TIMESTAMP = "UNIX_TIMESTAMP(%s)"; + + public static final String DATETIME_FORMAT = "DATETIME_FORMAT(%s,'%s')"; + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String DEFAULT_DATE_FORMAT = "YYYY-MM-dd HH:mm:ss"; + + public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)"; + + public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(20,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/mysql/MySQLConstants.java b/backend/src/main/java/io/dataease/provider/mysql/MySQLConstants.java index bf1c9d950d..8ab8567e2d 100644 --- a/backend/src/main/java/io/dataease/provider/mysql/MySQLConstants.java +++ b/backend/src/main/java/io/dataease/provider/mysql/MySQLConstants.java @@ -19,6 +19,8 @@ public class MySQLConstants extends SQLConstants { public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')"; + public static final String STR_TO_DATE = "STR_TO_DATE(%s,'%s')"; + public static final String CAST = "CAST(%s AS %s)"; public static final String DEFAULT_DATE_FORMAT = "%Y-%m-%d %H:%i:%S"; diff --git a/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java b/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java index 7d95965a19..3e1e8448c8 100644 --- a/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java @@ -270,6 +270,83 @@ public class MysqlQueryProvider extends QueryProvider { return st.render(); } + @Override + public String getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MySQLConstants.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(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(MySQLConstants.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 customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + 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); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + 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("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MySQLConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, customFilter, extFilterRequestList, null); + } + @Override public String getSQLAsTmp(String sql, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { @@ -671,9 +748,17 @@ public class MysqlQueryProvider extends QueryProvider { } else { originName = String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); } - if (field.getDeType() == 1 && field.getDeExtractType() != 1) { - String cast = String.format(MySQLConstants.CAST, originName, MySQLConstants.DEFAULT_INT_FORMAT) + "/1000"; - whereName = String.format(MySQLConstants.FROM_UNIXTIME, cast, MySQLConstants.DEFAULT_DATE_FORMAT); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MySQLConstants.STR_TO_DATE, originName, MySQLConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MySQLConstants.CAST, originName, MySQLConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(MySQLConstants.FROM_UNIXTIME, cast, MySQLConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } @@ -721,9 +806,17 @@ public class MysqlQueryProvider extends QueryProvider { originName = String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); } - if (field.getDeType() == 1 && field.getDeExtractType() != 1) { - String cast = String.format(MySQLConstants.CAST, originName, MySQLConstants.DEFAULT_INT_FORMAT) + "/1000"; - whereName = String.format(MySQLConstants.FROM_UNIXTIME, cast, MySQLConstants.DEFAULT_DATE_FORMAT); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MySQLConstants.STR_TO_DATE, originName, MySQLConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MySQLConstants.CAST, originName, MySQLConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(MySQLConstants.FROM_UNIXTIME, cast, MySQLConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } @@ -766,6 +859,12 @@ public class MysqlQueryProvider extends QueryProvider { split = "-"; } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "%Y-%m-%d %H:%i:%S"; } switch (dateStyle) { diff --git a/backend/src/main/java/io/dataease/provider/oracle/OracleConstants.java b/backend/src/main/java/io/dataease/provider/oracle/OracleConstants.java index 55907606d5..69dcfa32cd 100644 --- a/backend/src/main/java/io/dataease/provider/oracle/OracleConstants.java +++ b/backend/src/main/java/io/dataease/provider/oracle/OracleConstants.java @@ -17,7 +17,7 @@ public class OracleConstants extends SQLConstants { public static final String UNIX_TIMESTAMP = "UNIX_TIMESTAMP(%s)"; - public static final String DATE_FORMAT = "DATE_FORMAT(%s,'%s')"; + public static final String DATE_FORMAT = "to_timestamp(%s,'%s')"; public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')"; diff --git a/backend/src/main/java/io/dataease/provider/oracle/OracleQueryProvider.java b/backend/src/main/java/io/dataease/provider/oracle/OracleQueryProvider.java index 47b7cd6837..a37910e01e 100644 --- a/backend/src/main/java/io/dataease/provider/oracle/OracleQueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/oracle/OracleQueryProvider.java @@ -304,6 +304,83 @@ public class OracleQueryProvider extends QueryProvider { return st.render(); } + @Override + public String getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, 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(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, 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 customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + 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); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + 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("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, customFilter, extFilterRequestList, null); + } + @Override public String getSQLAsTmp(String sql, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList, null); @@ -635,12 +712,17 @@ public class OracleQueryProvider extends QueryProvider { stringBuilder.append(" \"").append(f.getOriginName()).append("\""); return stringBuilder.toString(); }).toArray(String[]::new); - return MessageFormat.format("SELECT {0} FROM {1} ORDER BY null", StringUtils.join(array, ","), table ); + return MessageFormat.format("SELECT {0} FROM {1} ORDER BY null", StringUtils.join(array, ","), "\"" + table + "\""); } @Override public String createRawQuerySQLAsTmp(String sql, List fields) { - return createRawQuerySQL(" (" + sqlFix(sql) + ") DE_TMP ", fields, null); + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(" \"").append(f.getOriginName()).append("\""); + return stringBuilder.toString(); + }).toArray(String[]::new); + return MessageFormat.format("SELECT {0} FROM {1} ORDER BY null", StringUtils.join(array, ","), " (" + sqlFix(sql) + ") DE_TMP "); } public String transMysqlFilterTerm(String term) { @@ -701,9 +783,17 @@ public class OracleQueryProvider extends QueryProvider { originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); } - if (field.getDeType() == 1 && field.getDeExtractType() != 1) { - String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; - whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } @@ -716,7 +806,11 @@ public class OracleQueryProvider extends QueryProvider { } else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) { whereValue = "'%" + value + "%'"; } else { - whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value); + if (field.getDeType() == 1) { + whereValue = String.format(OracleConstants.TO_DATE, "'" + value + "'", OracleConstants.DEFAULT_DATE_FORMAT); + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value); + } } list.add(SQLObj.builder() .whereField(whereName) @@ -751,9 +845,17 @@ public class OracleQueryProvider extends QueryProvider { originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); } - if (field.getDeType() == 1 && field.getDeExtractType() != 1) { - String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; - whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } @@ -767,7 +869,9 @@ public class OracleQueryProvider extends QueryProvider { 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(OracleConstants.WHERE_BETWEEN, startTime, endTime); + String st = String.format(OracleConstants.TO_DATE, "'" + startTime + "'", OracleConstants.DEFAULT_DATE_FORMAT); + String et = String.format(OracleConstants.TO_DATE, "'" + endTime + "'", OracleConstants.DEFAULT_DATE_FORMAT); + whereValue = st + " AND " + et; } else { whereValue = String.format(OracleConstants.WHERE_BETWEEN, value.get(0), value.get(1)); } @@ -795,6 +899,12 @@ public class OracleQueryProvider extends QueryProvider { split = "-"; } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return OracleConstants.DEFAULT_DATE_FORMAT; } switch (dateStyle) { diff --git a/backend/src/main/java/io/dataease/provider/pg/PgConstants.java b/backend/src/main/java/io/dataease/provider/pg/PgConstants.java index e9f9555ae3..1fcf7f0d8e 100644 --- a/backend/src/main/java/io/dataease/provider/pg/PgConstants.java +++ b/backend/src/main/java/io/dataease/provider/pg/PgConstants.java @@ -19,6 +19,8 @@ public class PgConstants extends SQLConstants { public static final String FROM_UNIXTIME = "to_timestamp(%s)"; + public static final String TO_DATE = "to_date(%s,'%s')"; + public static final String CAST = "CAST(%s AS %s)"; public static final String DEFAULT_DATE_FORMAT = "'YYYY-MM-DD HH24:MI:SS'"; diff --git a/backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java b/backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java index 9944e3b1b8..67c89758b9 100644 --- a/backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/pg/PgQueryProvider.java @@ -32,7 +32,6 @@ import java.util.regex.Pattern; import static io.dataease.provider.SQLConstants.TABLE_ALIAS_PREFIX; - @Service("pgQuery") public class PgQueryProvider extends QueryProvider { @Resource @@ -86,7 +85,7 @@ public class PgQueryProvider extends QueryProvider { case "TINYINT": return DeTypeConstants.DE_BOOL;// 布尔 case "bytea": - return DeTypeConstants.DE_Binary;// 二进制 + return DeTypeConstants.DE_BINARY;// 二进制 default: return DeTypeConstants.DE_STRING; } @@ -100,11 +99,11 @@ public class PgQueryProvider extends QueryProvider { @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)) + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PgConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); if (CollectionUtils.isNotEmpty(fields)) { for (int i = 0; i < fields.size(); i++) { @@ -114,35 +113,35 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + 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); + 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); + 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); + fieldName = String.format(PgConstants.CAST, originField, PgConstants.DEFAULT_FLOAT_FORMAT); } else if (f.getDeType() == DeTypeConstants.DE_TIME) { - fieldName = String.format( PgConstants.CAST, originField, "timestamp"); + 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 ); + 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); + fieldName = String.format(PgConstants.CAST, originField, PgConstants.DEFAULT_INT_FORMAT); } else { fieldName = originField; } @@ -190,10 +189,10 @@ public class PgQueryProvider extends QueryProvider { @Override public String getSQL(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, Datasource ds) { SQLObj tableObj = SQLObj.builder() - .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PgConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); List xWheres = new ArrayList<>(); List xOrders = new ArrayList<>(); @@ -205,9 +204,9 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); } String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); // 处理横轴字段 @@ -235,9 +234,9 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); // 处理纵轴字段 @@ -285,7 +284,7 @@ public class PgQueryProvider extends QueryProvider { ST st = stg.getInstanceOf("querySql"); SQLObj tableSQL = SQLObj.builder() - .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableName(String.format(PgConstants.BRACKETS, sql)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) .build(); if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); @@ -294,6 +293,84 @@ public class PgQueryProvider extends QueryProvider { return st.render(); } + @Override + public String getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, 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(); + setSchema(tableObj, ds); + 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 customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + 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); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + 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("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(PgConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, customFilter, extFilterRequestList, null); + } + @Override public String getSQLAsTmp(String sql, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { @@ -303,10 +380,10 @@ public class PgQueryProvider extends QueryProvider { @Override public String getSQLStack(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extStack, Datasource ds) { SQLObj tableObj = SQLObj.builder() - .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PgConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); List xWheres = new ArrayList<>(); List xOrders = new ArrayList<>(); @@ -321,9 +398,9 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); } String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); // 处理横轴字段 @@ -351,9 +428,9 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); // 处理纵轴字段 @@ -401,7 +478,7 @@ public class PgQueryProvider extends QueryProvider { ST st = stg.getInstanceOf("querySql"); SQLObj tableSQL = SQLObj.builder() - .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableName(String.format(PgConstants.BRACKETS, sql)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) .build(); if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); @@ -418,10 +495,10 @@ public class PgQueryProvider extends QueryProvider { @Override public String getSQLScatter(String table, List xAxis, List yAxis, List customFilter, List extFilterRequestList, List extBubble, Datasource ds) { SQLObj tableObj = SQLObj.builder() - .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table)) + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PgConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); List xWheres = new ArrayList<>(); List xOrders = new ArrayList<>(); @@ -433,9 +510,9 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); } String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); // 处理横轴字段 @@ -466,9 +543,9 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); // 处理纵轴字段 @@ -516,7 +593,7 @@ public class PgQueryProvider extends QueryProvider { ST st = stg.getInstanceOf("querySql"); SQLObj tableSQL = SQLObj.builder() - .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableName(String.format(PgConstants.BRACKETS, sql)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) .build(); if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); @@ -539,7 +616,7 @@ public class PgQueryProvider extends QueryProvider { 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)) + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PgConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); List yFields = new ArrayList<>(); @@ -553,9 +630,9 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } else { - originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + originField = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); } String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); // 处理纵轴字段 @@ -598,7 +675,7 @@ public class PgQueryProvider extends QueryProvider { ST st = stg.getInstanceOf("querySql"); SQLObj tableSQL = SQLObj.builder() - .tableName(String.format( PgConstants.BRACKETS, sql)) + .tableName(String.format(PgConstants.BRACKETS, sql)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) .build(); if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); @@ -629,11 +706,11 @@ public class PgQueryProvider extends QueryProvider { stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName()); return stringBuilder.toString(); }).toArray(String[]::new); - if(ds != null){ + if (ds != null) { String schema = new Gson().fromJson(ds.getConfiguration(), JdbcDTO.class).getSchema(); String tableWithSchema = String.format(SqlServerSQLConstants.KEYWORD_TABLE, schema) + "." + String.format(SqlServerSQLConstants.KEYWORD_TABLE, table); return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), tableWithSchema); - }else { + } else { return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table); } } @@ -695,18 +772,26 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originName = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); } else { - originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + 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); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PgConstants.TO_DATE, originName, PgConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(PgConstants.CAST, originName, "bigint"); + whereName = String.format(PgConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } if (StringUtils.equalsIgnoreCase(request.getTerm(), "null")) { - whereValue = PgConstants.WHERE_VALUE_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")) { @@ -714,7 +799,7 @@ public class PgQueryProvider extends QueryProvider { } else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) { whereValue = "'%" + value + "%'"; } else { - whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, value); + whereValue = String.format(PgConstants.WHERE_VALUE_VALUE, value); } list.add(SQLObj.builder() .whereField(whereName) @@ -744,14 +829,22 @@ public class PgQueryProvider extends QueryProvider { // 解析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()); + originName = String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); } else { - originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + 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); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PgConstants.TO_DATE, originName, PgConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(PgConstants.CAST, originName, "bigint"); + whereName = String.format(PgConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } @@ -765,12 +858,12 @@ public class PgQueryProvider extends QueryProvider { 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); + whereValue = String.format(PgConstants.WHERE_BETWEEN, startTime, endTime); } else { - whereValue = String.format( PgConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + whereValue = String.format(PgConstants.WHERE_BETWEEN, value.get(0), value.get(1)); } } else { - whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, value.get(0)); + whereValue = String.format(PgConstants.WHERE_VALUE_VALUE, value.get(0)); } list.add(SQLObj.builder() .whereField(whereName) @@ -793,6 +886,12 @@ public class PgQueryProvider extends QueryProvider { split = "-"; } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "'YYYY-MM-DD HH24:MI:SS'"; } switch (dateStyle) { @@ -817,10 +916,10 @@ public class PgQueryProvider extends QueryProvider { String fieldName = ""; if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { if (x.getDeType() == 2 || x.getDeType() == 3) { - fieldName = String.format( PgConstants.UNIX_TIMESTAMP, originField); + 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); + fieldName = String.format(PgConstants.DATE_FORMAT, originField, format); } else { fieldName = originField; } @@ -828,11 +927,11 @@ public class PgQueryProvider extends QueryProvider { 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); + 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); + 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; @@ -847,17 +946,17 @@ public class PgQueryProvider extends QueryProvider { private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { String fieldName = ""; if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { - fieldName = PgConstants.AGG_COUNT; + fieldName = PgConstants.AGG_COUNT; } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { - fieldName = String.format( PgConstants.AGG_FIELD, y.getSummary(), originField); + 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); + 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); + 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() @@ -874,7 +973,7 @@ public class PgQueryProvider extends QueryProvider { String whereValue = ""; // 原始类型不是时间,在de中被转成时间的字段做处理 if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { - whereValue = PgConstants.WHERE_VALUE_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")) { @@ -882,7 +981,7 @@ public class PgQueryProvider extends QueryProvider { } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { whereValue = "'%" + f.getValue() + "%'"; } else { - whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, f.getValue()); + whereValue = String.format(PgConstants.WHERE_VALUE_VALUE, f.getValue()); } list.add(SQLObj.builder() .whereField(fieldAlias) @@ -913,7 +1012,7 @@ public class PgQueryProvider extends QueryProvider { List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); for (DatasetTableField ele : calcFields) { originField = originField.replaceAll("\\[" + ele.getId() + "]", - String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + String.format(PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); } return originField; } diff --git a/backend/src/main/java/io/dataease/provider/sqlserver/SqlserverQueryProvider.java b/backend/src/main/java/io/dataease/provider/sqlserver/SqlserverQueryProvider.java index a9a07b1ce0..3fcb7b5824 100644 --- a/backend/src/main/java/io/dataease/provider/sqlserver/SqlserverQueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/sqlserver/SqlserverQueryProvider.java @@ -13,6 +13,7 @@ import io.dataease.dto.chart.ChartViewFieldDTO; import io.dataease.dto.sqlObj.SQLObj; import io.dataease.provider.QueryProvider; import io.dataease.provider.SQLConstants; +import io.dataease.provider.oracle.OracleConstants; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -73,7 +74,7 @@ public class SqlserverQueryProvider extends QueryProvider { case "TINYINT": return DeTypeConstants.DE_BOOL;// 布尔 case "TIMESTAMP": - return DeTypeConstants.DE_Binary;// 二进制 + return DeTypeConstants.DE_BINARY;// 二进制 default: return DeTypeConstants.DE_STRING; } @@ -91,7 +92,7 @@ public class SqlserverQueryProvider extends QueryProvider { .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(SqlServerSQLConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); if (CollectionUtils.isNotEmpty(fields)) { @@ -159,12 +160,12 @@ public class SqlserverQueryProvider extends QueryProvider { @Override public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds) { - return createQuerySQL(table, fields, isGroup, ds) + " ORDER BY \"" + fields.get(0).getOriginName() + "\" offset 0 rows fetch next " + limit + " rows only"; + return createQuerySQL(table, fields, isGroup, ds) + " ORDER BY \"" + fields.get(0).getOriginName() + "\" offset 0 rows fetch next " + limit + " rows only"; } @Override public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup) { - return createQuerySQLAsTmp(sql, fields, isGroup) + " ORDER BY \"" + fields.get(0).getOriginName() + "\" offset 0 rows fetch next " + limit + " rows only"; + return createQuerySQLAsTmp(sql, fields, isGroup) + " ORDER BY \"" + fields.get(0).getOriginName() + "\" offset 0 rows fetch next " + limit + " rows only"; } @Override @@ -173,7 +174,7 @@ public class SqlserverQueryProvider extends QueryProvider { .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(SqlServerSQLConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); List xWheres = new ArrayList<>(); List xOrders = new ArrayList<>(); @@ -258,6 +259,76 @@ public class SqlserverQueryProvider extends QueryProvider { return st.render(); } + @Override + public String getSQLTableInfo(String table, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(SqlServerSQLConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + 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 = String.format(SqlServerSQLConstants.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 customWheres = transCustomFilterList(tableObj, customFilter); + // 处理仪表板字段过滤 + List extWheres = transExtFilterList(tableObj, extFilterRequestList); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + 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); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + 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("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(SqlServerSQLConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List customFilter, List extFilterRequestList, Datasource ds) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, customFilter, extFilterRequestList, null); + } + @Override public String getSQLAsTmp(String sql, List xAxis, List yAxis, List customFilter, List extFilterRequestList) { @@ -270,7 +341,7 @@ public class SqlserverQueryProvider extends QueryProvider { .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(SqlServerSQLConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); List xWheres = new ArrayList<>(); List xOrders = new ArrayList<>(); @@ -388,7 +459,7 @@ public class SqlserverQueryProvider extends QueryProvider { .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(SqlServerSQLConstants.KEYWORD_TABLE, table)) .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) .build(); - setSchema(tableObj,ds); + setSchema(tableObj, ds); List xFields = new ArrayList<>(); List xWheres = new ArrayList<>(); List xOrders = new ArrayList<>(); @@ -588,11 +659,11 @@ public class SqlserverQueryProvider extends QueryProvider { stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName()); return stringBuilder.toString(); }).toArray(String[]::new); - if(ds != null){ + if (ds != null) { String schema = new Gson().fromJson(ds.getConfiguration(), JdbcDTO.class).getSchema(); String tableWithSchema = String.format(SqlServerSQLConstants.KEYWORD_TABLE, schema) + "." + String.format(SqlServerSQLConstants.KEYWORD_TABLE, table); return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), tableWithSchema); - }else { + } else { return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table); } } @@ -651,9 +722,18 @@ public class SqlserverQueryProvider extends QueryProvider { String whereTerm = transMysqlFilterTerm(request.getTerm()); String whereValue = ""; String originName = String.format(SqlServerSQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); - if (field.getDeType() == DeTypeConstants.DE_TIME && field.getDeExtractType() != DeTypeConstants.DE_TIME) { - String cast = String.format(SqlServerSQLConstants.LONG_TO_DATE, originName + "/1000"); - whereName = String.format(SqlServerSQLConstants.FROM_UNIXTIME, cast); + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(SqlServerSQLConstants.STRING_TO_DATE, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(SqlServerSQLConstants.LONG_TO_DATE, originName + "/1000"); + whereName = String.format(SqlServerSQLConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } @@ -692,9 +772,17 @@ public class SqlserverQueryProvider extends QueryProvider { String whereValue = ""; String originName = String.format(SqlServerSQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); - if (field.getDeType() == 1 && field.getDeExtractType() != 1) { - String cast = String.format(SqlServerSQLConstants.LONG_TO_DATE, originName + "/1000"); - whereName = String.format(SqlServerSQLConstants.FROM_UNIXTIME, cast); + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(SqlServerSQLConstants.STRING_TO_DATE, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(SqlServerSQLConstants.LONG_TO_DATE, originName + "/1000"); + whereName = String.format(SqlServerSQLConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } } else { whereName = originName; } @@ -738,36 +826,42 @@ public class SqlserverQueryProvider extends QueryProvider { split = "-"; } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "convert(varchar," + originField + ",120)"; } switch (dateStyle) { case "y": return "CONVERT(varchar(100), datepart(yy, " + originField + "))"; case "y_M": - if(split.equalsIgnoreCase("-")){ + if (split.equalsIgnoreCase("-")) { return "substring( convert(varchar," + originField + ",120),1,7)"; - }else { - return "replace("+ "substring( convert(varchar," + originField + ",120),1,7), '-','/')"; + } else { + return "replace(" + "substring( convert(varchar," + originField + ",120),1,7), '-','/')"; } case "y_M_d": - if(split.equalsIgnoreCase("-")){ + if (split.equalsIgnoreCase("-")) { return "CONVERT(varchar(100), " + originField + ", 23)"; - }else { + } else { return "CONVERT(varchar(100), " + originField + ", 111)"; } case "H_m_s": return "CONVERT(varchar(100), " + originField + ", 8)"; case "y_M_d_H_m": - if(split.equalsIgnoreCase("-")){ + if (split.equalsIgnoreCase("-")) { return "substring( convert(varchar," + originField + ",120),1,16)"; - }else { - return "replace("+ "substring( convert(varchar," + originField + ",120),1,16), '-','/')"; + } else { + return "replace(" + "substring( convert(varchar," + originField + ",120),1,16), '-','/')"; } case "y_M_d_H_m_s": - if(split.equalsIgnoreCase("-")){ + if (split.equalsIgnoreCase("-")) { return "convert(varchar," + originField + ",120)"; - }else { - return "replace("+ "convert(varchar," + originField + ",120), '-','/')"; + } else { + return "replace(" + "convert(varchar," + originField + ",120), '-','/')"; } default: return "convert(varchar," + originField + ",120)"; @@ -790,7 +884,7 @@ public class SqlserverQueryProvider extends QueryProvider { String cast = String.format(SqlServerSQLConstants.STRING_TO_DATE, originField); fieldName = transDateFormat(x.getDateStyle(), x.getDatePattern(), cast); } else {// 数值转时间 - String cast = String.format(SqlServerSQLConstants.LONG_TO_DATE, originField+ "/1000"); + String cast = String.format(SqlServerSQLConstants.LONG_TO_DATE, originField + "/1000"); fieldName = transDateFormat(x.getDateStyle(), x.getDatePattern(), cast); } } else { 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 206eaf5eee..92e0f1c6e7 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -184,6 +184,11 @@ public class ChartViewService { }.getType()); List yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken>() { }.getType()); + if (StringUtils.equalsIgnoreCase(view.getType(), "chart-mix")) { + List yAxisExt = new Gson().fromJson(view.getYAxisExt(), new TypeToken>() { + }.getType()); + yAxis.addAll(yAxisExt); + } List extStack = new Gson().fromJson(view.getExtStack(), new TypeToken>() { }.getType()); List extBubble = new Gson().fromJson(view.getExtBubble(), new TypeToken>() { @@ -203,13 +208,22 @@ public class ChartViewService { customFilter.addAll(collect); } - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) + || StringUtils.equalsIgnoreCase("gauge", view.getType()) + || StringUtils.equalsIgnoreCase("liquid", view.getType())) { xAxis = new ArrayList<>(); if (CollectionUtils.isEmpty(yAxis)) { ChartViewDTO dto = new ChartViewDTO(); BeanUtils.copyBean(dto, view); return dto; } + } else if (StringUtils.equalsIgnoreCase("table-info", view.getType())) { + yAxis = new ArrayList<>(); + if (CollectionUtils.isEmpty(xAxis)) { + ChartViewDTO dto = new ChartViewDTO(); + BeanUtils.copyBean(dto, view); + return dto; + } } else { if (CollectionUtils.isEmpty(xAxis) && CollectionUtils.isEmpty(yAxis)) { ChartViewDTO dto = new ChartViewDTO(); @@ -315,22 +329,26 @@ public class ChartViewService { QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); if (StringUtils.equalsIgnoreCase(table.getType(), "db")) { datasourceRequest.setTable(dataTableInfoDTO.getTable()); - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummary(dataTableInfoDTO.getTable(), yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLStack(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, extStack, ds)); } else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) { datasourceRequest.setQuery(qp.getSQLScatter(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, extBubble, ds)); + } else if (StringUtils.equalsIgnoreCase("table-info", view.getType())) { + datasourceRequest.setQuery(qp.getSQLTableInfo(dataTableInfoDTO.getTable(), xAxis, customFilter, extFilterList, ds)); } else { datasourceRequest.setQuery(qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, ds)); } } else if (StringUtils.equalsIgnoreCase(table.getType(), "sql")) { - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(dataTableInfoDTO.getSql(), yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLAsTmpStack(dataTableInfoDTO.getSql(), xAxis, yAxis, customFilter, extFilterList, extStack)); } else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) { datasourceRequest.setQuery(qp.getSQLAsTmpScatter(dataTableInfoDTO.getSql(), xAxis, yAxis, customFilter, extFilterList, extBubble)); + } else if (StringUtils.equalsIgnoreCase("table-info", view.getType())) { + datasourceRequest.setQuery(qp.getSQLAsTmpTableInfo(dataTableInfoDTO.getSql(), xAxis, customFilter, extFilterList, ds)); } else { datasourceRequest.setQuery(qp.getSQLAsTmp(dataTableInfoDTO.getSql(), xAxis, yAxis, customFilter, extFilterList)); } @@ -338,12 +356,14 @@ public class ChartViewService { DataTableInfoDTO dt = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class); List list = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId()); String sql = dataSetTableService.getCustomSQLDatasource(dt, list, ds); - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(sql, yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLAsTmpStack(sql, xAxis, yAxis, customFilter, extFilterList, extStack)); } else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) { datasourceRequest.setQuery(qp.getSQLAsTmpScatter(sql, xAxis, yAxis, customFilter, extFilterList, extBubble)); + } else if (StringUtils.equalsIgnoreCase("table-info", view.getType())) { + datasourceRequest.setQuery(qp.getSQLAsTmpTableInfo(sql, xAxis, customFilter, extFilterList, ds)); } else { datasourceRequest.setQuery(qp.getSQLAsTmp(sql, xAxis, yAxis, customFilter, extFilterList)); } @@ -368,12 +388,14 @@ public class ChartViewService { String tableName = "ds_" + table.getId().replaceAll("-", "_"); datasourceRequest.setTable(tableName); QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); - if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) { + if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummary(tableName, yAxis, customFilter, extFilterList)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { datasourceRequest.setQuery(qp.getSQLStack(tableName, xAxis, yAxis, customFilter, extFilterList, extStack, ds)); } else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) { datasourceRequest.setQuery(qp.getSQLScatter(tableName, xAxis, yAxis, customFilter, extFilterList, extBubble, ds)); + } else if (StringUtils.equalsIgnoreCase("table-info", view.getType())) { + datasourceRequest.setQuery(qp.getSQLTableInfo(tableName, xAxis, customFilter, extFilterList, ds)); } else { datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList, ds)); } @@ -427,6 +449,8 @@ public class ChartViewService { } else if (StringUtils.containsIgnoreCase(view.getType(), "text") || StringUtils.containsIgnoreCase(view.getType(), "gauge")) { mapChart = transNormalChartData(xAxis, yAxis, view, data, isDrill); + } else if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix")) { + mapChart = transMixChartData(xAxis, yAxis, view, data, isDrill); } else { mapChart = transChartData(xAxis, yAxis, view, data, isDrill); } @@ -436,6 +460,9 @@ public class ChartViewService { map.putAll(mapChart); map.putAll(mapTableNormal); + List sourceFields = dataSetTableFieldsService.getFieldsByTableId(view.getTableId()); + map.put("sourceFields",sourceFields); + ChartViewDTO dto = new ChartViewDTO(); BeanUtils.copyBean(dto, view); dto.setData(map); @@ -561,6 +588,67 @@ public class ChartViewService { return map; } + // 组合图形 + private Map transMixChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, boolean isDrill) { + Map map = new HashMap<>(); + + List x = new ArrayList<>(); + List series = new ArrayList<>(); + for (ChartViewFieldDTO y : yAxis) { + Series series1 = new Series(); + series1.setName(y.getName()); + series1.setType(y.getChartType()); + series1.setData(new ArrayList<>()); + series.add(series1); + } + for (int i1 = 0; i1 < data.size(); i1++) { + String[] d = data.get(i1); + + StringBuilder a = new StringBuilder(); + for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) { + List dimensionList = new ArrayList<>(); + List quotaList = new ArrayList<>(); + AxisChartDataDTO axisChartDataDTO = new AxisChartDataDTO(); + + for (int j = 0; j < xAxis.size(); j++) { + ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO(); + chartDimensionDTO.setId(xAxis.get(j).getId()); + chartDimensionDTO.setValue(d[j]); + dimensionList.add(chartDimensionDTO); + } + axisChartDataDTO.setDimensionList(dimensionList); + + int j = i - xAxis.size(); + ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO(); + chartQuotaDTO.setId(yAxis.get(j).getId()); + quotaList.add(chartQuotaDTO); + axisChartDataDTO.setQuotaList(quotaList); + try { + axisChartDataDTO.setValue(new BigDecimal(StringUtils.isEmpty(d[i]) ? "0" : d[i])); + } catch (Exception e) { + axisChartDataDTO.setValue(new BigDecimal(0)); + } + series.get(j).getData().add(axisChartDataDTO); + } + 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()); + } + + map.put("x", x); + map.put("series", series); + return map; + } + // 常规图形 private Map transNormalChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, boolean isDrill) { Map map = new HashMap<>(); 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 93e1158b4a..62ab5a1707 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -1,7 +1,6 @@ package io.dataease.service.dataset; -import com.fit2cloud.quartz.anno.QuartzScheduled; import com.google.gson.Gson; import io.dataease.base.domain.*; import io.dataease.base.mapper.*; @@ -115,9 +114,9 @@ public class DataSetTableService { } } - public void saveExcel(DataSetTableRequest datasetTable)throws Exception { + public void saveExcel(DataSetTableRequest datasetTable) throws Exception { if (StringUtils.isEmpty(datasetTable.getId())) { - if(datasetTable.isMergeSheet()){ + if (datasetTable.isMergeSheet()) { Map> map = datasetTable.getSheets().stream().collect(Collectors.groupingBy(ExcelSheetData::getFieldsMd5)); for (String s : map.keySet()) { DataSetTableRequest sheetTable = new DataSetTableRequest(); @@ -147,7 +146,7 @@ public class DataSetTableService { }); } } - }else { + } else { for (ExcelSheetData sheet : datasetTable.getSheets()) { String[] fieldArray = sheet.getFields().stream().map(TableFiled::getFieldName).toArray(String[]::new); if (checkIsRepeat(fieldArray)) { @@ -183,7 +182,7 @@ public class DataSetTableService { List oldFields = datasetTable.getSheets().get(0).getFields().stream().map(TableFiled::getRemarks).collect(Collectors.toList()); for (ExcelSheetData sheet : datasetTable.getSheets()) { //替换时, - if(datasetTable.getEditType() == 0){ + if (datasetTable.getEditType() == 0) { List newFields = sheet.getFields().stream().map(TableFiled::getRemarks).collect(Collectors.toList()); if (!oldFields.equals(newFields)) { DataEaseException.throwException(Translator.get("i18n_excel_colume_change")); @@ -240,7 +239,7 @@ public class DataSetTableService { if (datasetTable.getIsRename() == null || !datasetTable.getIsRename()) { // 更新数据和字段 if (update == 1) { - if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql") || StringUtils.equalsIgnoreCase(datasetTable.getType(), "custom") ) { + if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql") || StringUtils.equalsIgnoreCase(datasetTable.getType(), "custom")) { // 删除所有字段,重新抽象 dataSetTableFieldsService.deleteByTableId(datasetTable.getId()); saveTableField(datasetTable); @@ -251,7 +250,7 @@ public class DataSetTableService { return datasetTable; } - public void alter(DataSetTableRequest request)throws Exception { + public void alter(DataSetTableRequest request) throws Exception { checkName(request); datasetTableMapper.updateByPrimaryKeySelective(request); } @@ -470,14 +469,23 @@ 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()); + datasourceRequest.setPage(page); + datasourceRequest.setFetchSize(Integer.parseInt(dataSetTableRequest.getRow())); + datasourceRequest.setPageSize(pageSize); + datasourceRequest.setRealSize(realSize); + datasourceRequest.setPreviewData(true); try { + datasourceRequest.setPageable(true); data.addAll(datasourceProvider.getData(datasourceRequest)); } catch (Exception e) { e.printStackTrace(); DEException.throwException(e.getMessage()); } + try { datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false, ds)); + datasourceRequest.setPageable(false); dataSetPreviewPage.setTotal(datasourceProvider.getData(datasourceRequest).size()); } catch (Exception e) { e.printStackTrace(); @@ -496,8 +504,12 @@ 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(jdbcProvider.getData(datasourceRequest)); + for(int i=0;i< data.size(); i++){ + System.out.println(data.get(i)[2]); + } } catch (Exception e) { e.printStackTrace(); DEException.throwException(e.getMessage()); @@ -551,8 +563,12 @@ 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(jdbcProvider.getData(datasourceRequest)); + for(int i=0;i< data.size(); i++){ + System.out.println(data.get(i)[2]); + } } catch (Exception e) { e.printStackTrace(); DEException.throwException(e.getMessage()); @@ -578,8 +594,12 @@ 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(jdbcProvider.getData(datasourceRequest)); + for(int i=0;i< data.size(); i++){ + System.out.println(data.get(i)[2]); + } } catch (Exception e) { e.printStackTrace(); DEException.throwException(e.getMessage()); @@ -798,18 +818,35 @@ public class DataSetTableService { String f = field.substring(0, field.length() - 1); StringBuilder join = new StringBuilder(); + List unions = new ArrayList<>(); for (DataTableInfoCustomUnion dataTableInfoCustomUnion : dataTableInfoDTO.getList()) { for (DataSetTableUnionDTO dto : list) { // 被关联表和自助数据集的表相等 if (StringUtils.equals(dto.getTargetTableId(), dataTableInfoCustomUnion.getTableId())) { - DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId()); - DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId()); + unions.add(dto); + } + } + } + if (CollectionUtils.isNotEmpty(unions)) { + for (int i = 0; i < unions.size(); i++) { + DataSetTableUnionDTO dto = unions.get(i); + DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId()); + DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId()); + if (ObjectUtils.isEmpty(sourceField) || ObjectUtils.isEmpty(targetField)) { + DEException.throwException(Translator.get("i18n_dataset_field_delete")); + } + if (i == 0) { join.append(convertUnionTypeToSQL(dto.getSourceUnionRelation())) .append(DorisTableUtils.dorisName(dto.getTargetTableId())) .append(" ON ") .append(DorisTableUtils.dorisName(dto.getSourceTableId())).append(".").append(sourceField.getDataeaseName()) .append(" = ") .append(DorisTableUtils.dorisName(dto.getTargetTableId())).append(".").append(targetField.getDataeaseName()); + } else { + join.append(" AND ") + .append(DorisTableUtils.dorisName(dto.getSourceTableId())).append(".").append(sourceField.getDataeaseName()) + .append(" = ") + .append(DorisTableUtils.dorisName(dto.getTargetTableId())).append(".").append(targetField.getDataeaseName()); } } } @@ -855,22 +892,39 @@ public class DataSetTableService { String f = field.substring(0, field.length() - 1); StringBuilder join = new StringBuilder(); + List unions = new ArrayList<>(); for (DataTableInfoCustomUnion dataTableInfoCustomUnion : dataTableInfoDTO.getList()) { for (DataSetTableUnionDTO dto : list) { // 被关联表和自助数据集的表相等 if (StringUtils.equals(dto.getTargetTableId(), dataTableInfoCustomUnion.getTableId())) { - DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId()); - DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId()); - DatasetTable sourceTable = datasetTableMapper.selectByPrimaryKey(dto.getSourceTableId()); - String sourceTableName = new Gson().fromJson(sourceTable.getInfo(), DataTableInfoDTO.class).getTable(); - DatasetTable targetTable = datasetTableMapper.selectByPrimaryKey(dto.getTargetTableId()); - String targetTableName = new Gson().fromJson(targetTable.getInfo(), DataTableInfoDTO.class).getTable(); + unions.add(dto); + } + } + } + if (CollectionUtils.isNotEmpty(unions)) { + for (int i = 0; i < unions.size(); i++) { + DataSetTableUnionDTO dto = unions.get(i); + DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId()); + DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId()); + if (ObjectUtils.isEmpty(sourceField) || ObjectUtils.isEmpty(targetField)) { + DEException.throwException(Translator.get("i18n_dataset_field_delete")); + } + DatasetTable sourceTable = datasetTableMapper.selectByPrimaryKey(dto.getSourceTableId()); + String sourceTableName = new Gson().fromJson(sourceTable.getInfo(), DataTableInfoDTO.class).getTable(); + DatasetTable targetTable = datasetTableMapper.selectByPrimaryKey(dto.getTargetTableId()); + String targetTableName = new Gson().fromJson(targetTable.getInfo(), DataTableInfoDTO.class).getTable(); + if (i == 0) { join.append(convertUnionTypeToSQL(dto.getSourceUnionRelation())) .append(String.format(keyword, targetTableName)) .append(" ON ") .append(String.format(keyword, sourceTableName)).append(".").append(String.format(keyword, sourceField.getOriginName())) .append(" = ") .append(String.format(keyword, targetTableName)).append(".").append(String.format(keyword, targetField.getOriginName())); + } else { + join.append(" AND ") + .append(String.format(keyword, sourceTableName)).append(".").append(String.format(keyword, sourceField.getOriginName())) + .append(" = ") + .append(String.format(keyword, targetTableName)).append(".").append(String.format(keyword, targetField.getOriginName())); } } } @@ -901,7 +955,7 @@ public class DataSetTableService { } } - public List saveExcelTableField(String datasetTableId, List fields, boolean insert){ + public List saveExcelTableField(String datasetTableId, List fields, boolean insert) { List datasetTableFields = new ArrayList<>(); if (CollectionUtils.isNotEmpty(fields)) { for (int i = 0; i < fields.size(); i++) { @@ -920,7 +974,7 @@ public class DataSetTableService { datasetTableField.setLastSyncTime(System.currentTimeMillis()); datasetTableField.setExtField(0); datasetTableField.setGroupType(datasetTableField.getDeType() < 2 ? "d" : "q"); - if(insert){ + if (insert) { dataSetTableFieldsService.save(datasetTableField); } datasetTableFields.add(datasetTableField); @@ -1120,11 +1174,11 @@ public class DataSetTableService { .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString()); datasourceRequest.setQuery(qp.wrapSql(sql)); List sqlFileds = new ArrayList<>(); - try{ + try { datasourceProvider.fetchResultField(datasourceRequest).stream().map(TableFiled::getFieldName).forEach(filed -> { sqlFileds.add(filed); }); - }catch (Exception e){ + } catch (Exception e) { DataEaseException.throwException(Translator.get("i18n_check_sql_error") + e.getMessage()); } @@ -1137,11 +1191,11 @@ public class DataSetTableService { .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString()); datasourceRequest.setQuery(qp.wrapSql(sql)); List sqlFileds = new ArrayList<>(); - try{ + try { datasourceProvider.fetchResultField(datasourceRequest).stream().map(TableFiled::getFieldName).forEach(filed -> { sqlFileds.add(filed); }); - }catch (Exception e){ + } catch (Exception e) { DataEaseException.throwException(Translator.get("i18n_check_sql_error") + e.getMessage()); } @@ -1186,7 +1240,7 @@ public class DataSetTableService { List excelSheetDataList = parseExcel2(filename, file.getInputStream(), true); List retrunSheetDataList = new ArrayList<>(); - if (StringUtils.isNotEmpty(tableId) && editType == 1 ) { + if (StringUtils.isNotEmpty(tableId) && editType == 1) { List datasetTableFields = dataSetTableFieldsService.getFieldsByTableId(tableId); datasetTableFields.stream().filter(datasetTableField -> datasetTableField.getExtField() == 0).collect(Collectors.toList()); datasetTableFields.sort((o1, o2) -> { @@ -1210,7 +1264,7 @@ public class DataSetTableService { if (retrunSheetDataList.size() == 0) { DataEaseException.throwException(Translator.get("i18n_excel_colume_change")); } - }else { + } else { retrunSheetDataList = excelSheetDataList; } @@ -1223,12 +1277,12 @@ public class DataSetTableService { excelFileData.setPath(filePath); filename = filename.substring(0, filename.lastIndexOf('.')); - if(retrunSheetDataList.size() == 1){ + if (retrunSheetDataList.size() == 1) { retrunSheetDataList.get(0).setDatasetName(filename); retrunSheetDataList.get(0).setSheetExcelId(excelId); retrunSheetDataList.get(0).setId(UUID.randomUUID().toString()); retrunSheetDataList.get(0).setPath(filePath); - }else { + } else { for (ExcelSheetData excelSheetData : retrunSheetDataList) { excelSheetData.setDatasetName(filename + "-" + excelSheetData.getExcelLable()); excelSheetData.setSheetExcelId(excelId); diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java index 5cffd5e742..96f44d4c22 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java @@ -191,6 +191,11 @@ public class DataSetTableTaskService { if(dataSetTaskDTOS.get(0).getNextExecTime() == null || dataSetTaskDTOS.get(0).getNextExecTime() <= 0){ datasetTableTask.setStatus(TaskStatus.Stopped.name()); update(datasetTableTask); + return; + } + if(dataSetTaskDTOS.get(0).getNextExecTime() > datasetTableTask.getEndTime()){ + datasetTableTask.setStatus(TaskStatus.Stopped.name()); + update(datasetTableTask); } } } 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 df86334a8f..e7dc2cf95c 100644 --- a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java +++ b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java @@ -312,6 +312,7 @@ public class ExtractDataService { msg = true; lastExecStatus = JobStatus.Completed; } catch (Exception e) { + e.printStackTrace(); saveErrorLog(datasetTableId, taskId, e); msg = false; lastExecStatus = JobStatus.Error; @@ -456,7 +457,7 @@ public class ExtractDataService { for (DatasetTableField datasetTableField : datasetTableFields) { Column_Fields = Column_Fields + datasetTableField.getDataeaseName() + "` "; Integer size = datasetTableField.getSize() * 3; - if (datasetTableField.getSize() > 65533 || datasetTableField.getSize() * 3 > 65533) { + if (datasetTableField.getSize() == 0 || datasetTableField.getSize() > 65533 || datasetTableField.getSize() * 3 > 65533) { size = 65533; } switch (datasetTableField.getDeExtractType()) { @@ -468,7 +469,7 @@ public class ExtractDataService { Column_Fields = Column_Fields + "varchar(lenth)".replace("lenth", String.valueOf(size)) + ",`"; break; case 2: - Column_Fields = Column_Fields + "bigint(lenth)".replace("lenth", String.valueOf(size)) + ",`"; + Column_Fields = Column_Fields + "bigint" + ",`"; break; case 3: Column_Fields = Column_Fields + "DOUBLE" + ",`"; @@ -555,7 +556,7 @@ public class ExtractDataService { datasetTableTaskLog.setTaskId(taskId); datasetTableTaskLog.setStatus(JobStatus.Underway.name()); datasetTableTaskLog.setTriggerType(TriggerType.Custom.name()); - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 10; i++) { List datasetTableTaskLogs = dataSetTableTaskLogService.select(datasetTableTaskLog); if (CollectionUtils.isNotEmpty(datasetTableTaskLogs)) { return datasetTableTaskLogs.get(0); @@ -616,7 +617,8 @@ public class ExtractDataService { Thread.sleep(1000); } if (!transStatus.getStatusDescription().equals("Finished")) { - DataEaseException.throwException((transStatus.getLoggingString())); + DataEaseException.throwException(transStatus.getLoggingString()); + return; } executing = true; @@ -637,11 +639,6 @@ public class ExtractDataService { } } - private boolean isExitFile(String fileName) { - File file = new File(root_path + fileName); - return file.exists(); - } - private SlaveServer getSlaveServer() { SlaveServer remoteSlaveServer = new SlaveServer(); remoteSlaveServer.setHostname(carte);// 设置远程IP @@ -768,7 +765,7 @@ public class ExtractDataService { switch (datasourceType) { case mysql: MysqlConfigration mysqlConfigration = new Gson().fromJson(datasource.getConfiguration(), MysqlConfigration.class); - dataMeta = new DatabaseMeta("db", "MYSQL", "Native", mysqlConfigration.getHost(), mysqlConfigration.getDataBase(), mysqlConfigration.getPort().toString(), mysqlConfigration.getUsername(), mysqlConfigration.getPassword()); + dataMeta = new DatabaseMeta("db", "MYSQL", "Native", mysqlConfigration.getHost().trim(), mysqlConfigration.getDataBase().trim(), mysqlConfigration.getPort().toString(), mysqlConfigration.getUsername(), mysqlConfigration.getPassword()); dataMeta.addExtraOption("MYSQL", "characterEncoding", "UTF-8"); transMeta.addDatabase(dataMeta); selectSQL = getSelectSQL(extractType, datasetTable, datasource, datasetTableFields, selectSQL); @@ -777,7 +774,7 @@ public class ExtractDataService { break; case sqlServer: SqlServerConfigration sqlServerConfigration = new Gson().fromJson(datasource.getConfiguration(), SqlServerConfigration.class); - dataMeta = new DatabaseMeta("db", "MSSQLNATIVE", "Native", sqlServerConfigration.getHost(), sqlServerConfigration.getDataBase(), sqlServerConfigration.getPort().toString(), sqlServerConfigration.getUsername(), sqlServerConfigration.getPassword()); + dataMeta = new DatabaseMeta("db", "MSSQLNATIVE", "Native", sqlServerConfigration.getHost().trim(), sqlServerConfigration.getDataBase(), sqlServerConfigration.getPort().toString(), sqlServerConfigration.getUsername(), sqlServerConfigration.getPassword()); transMeta.addDatabase(dataMeta); selectSQL = getSelectSQL(extractType, datasetTable, datasource, datasetTableFields, selectSQL); inputStep = inputStep(transMeta, selectSQL); @@ -785,7 +782,7 @@ public class ExtractDataService { break; case pg: PgConfigration pgConfigration = new Gson().fromJson(datasource.getConfiguration(), PgConfigration.class); - dataMeta = new DatabaseMeta("db", "POSTGRESQL", "Native", pgConfigration.getHost(), pgConfigration.getDataBase(), pgConfigration.getPort().toString(), pgConfigration.getUsername(), pgConfigration.getPassword()); + dataMeta = new DatabaseMeta("db", "POSTGRESQL", "Native", pgConfigration.getHost().trim(), pgConfigration.getDataBase(), pgConfigration.getPort().toString(), pgConfigration.getUsername(), pgConfigration.getPassword()); transMeta.addDatabase(dataMeta); selectSQL = getSelectSQL(extractType, datasetTable, datasource, datasetTableFields, selectSQL); inputStep = inputStep(transMeta, selectSQL); @@ -797,7 +794,7 @@ public class ExtractDataService { String database = "(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = ORACLE_HOSTNAME)(PORT = ORACLE_PORT))(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = ORACLE_SERVICE_NAME )))".replace("ORACLE_HOSTNAME", oracleConfigration.getHost()).replace("ORACLE_PORT", oracleConfigration.getPort().toString()).replace("ORACLE_SERVICE_NAME", oracleConfigration.getDataBase()); dataMeta = new DatabaseMeta("db", "ORACLE", "Native", "", database, "-1", oracleConfigration.getUsername(), oracleConfigration.getPassword()); } else { - dataMeta = new DatabaseMeta("db", "ORACLE", "Native", oracleConfigration.getHost(), oracleConfigration.getDataBase(), oracleConfigration.getPort().toString(), oracleConfigration.getUsername(), oracleConfigration.getPassword()); + dataMeta = new DatabaseMeta("db", "ORACLE", "Native", oracleConfigration.getHost().trim(), oracleConfigration.getDataBase(), oracleConfigration.getPort().toString(), oracleConfigration.getUsername(), oracleConfigration.getPassword()); } transMeta.addDatabase(dataMeta); @@ -805,6 +802,16 @@ public class ExtractDataService { inputStep = inputStep(transMeta, selectSQL); udjcStep = udjc(datasetTableFields, DatasourceTypes.oracle); break; + case ck: + CHConfigration chConfigration = new Gson().fromJson(datasource.getConfiguration(), CHConfigration.class); + dataMeta = new DatabaseMeta("db", "ORACLE", "Native", chConfigration.getHost().trim(), chConfigration.getDataBase().trim(), chConfigration.getPort().toString(), chConfigration.getUsername(), chConfigration.getPassword()); +// dataMeta.addExtraOption("MYSQL", "characterEncoding", "UTF-8"); + dataMeta.setDatabaseType("Clickhouse"); + transMeta.addDatabase(dataMeta); + selectSQL = getSelectSQL(extractType, datasetTable, datasource, datasetTableFields, selectSQL); + inputStep = inputStep(transMeta, selectSQL); + udjcStep = udjc(datasetTableFields, DatasourceTypes.ck); + break; case excel: inputStep = excelInputStep(datasetTable.getInfo(), datasetTableFields); udjcStep = udjc(datasetTableFields, DatasourceTypes.excel); @@ -1001,11 +1008,12 @@ public class ExtractDataService { } private StepMeta udjc(List datasetTableFields, DatasourceTypes datasourceType) { - String needToChangeColumnType = ""; +// String needToChangeColumnType = ""; String handleBinaryTypeCode = ""; + String excelCompletion = ""; for (DatasetTableField datasetTableField : datasetTableFields) { - if(datasetTableField.getDeExtractType() == 5){ + if(datasetTableField.getDeExtractType() == DeTypeConstants.DE_BINARY){ handleBinaryTypeCode = handleBinaryTypeCode + "\n" + this.handleBinaryType.replace("FEILD", datasetTableField.getDataeaseName()); } } @@ -1016,9 +1024,8 @@ public class ExtractDataService { fields.add(fieldInfo); userDefinedJavaClassMeta.setFieldInfo(fields); List definitions = new ArrayList(); - String tmp_code = code.replace("alterColumnTypeCode", needToChangeColumnType); + String tmp_code = code.replace("handleWraps", handleWraps).replace("handleBinaryType", handleBinaryTypeCode); - tmp_code = tmp_code.replace("handleWraps", handleWraps); String Column_Fields = ""; if (datasourceType.equals(DatasourceTypes.oracle)) { Column_Fields = String.join(",", datasetTableFields.stream().map(DatasetTableField::getOriginName).collect(Collectors.toList())); @@ -1027,12 +1034,13 @@ public class ExtractDataService { } if (datasourceType.equals(DatasourceTypes.excel)) { - tmp_code = tmp_code.replace("handleExcelIntColumn", handleExcelIntColumn).replace("Column_Fields", Column_Fields); + tmp_code = tmp_code.replace("handleExcelIntColumn", handleExcelIntColumn).replace("Column_Fields", Column_Fields) + .replace("ExcelCompletion", excelCompletion); } else { - tmp_code = tmp_code.replace("handleExcelIntColumn", "").replace("Column_Fields", Column_Fields); + tmp_code = tmp_code.replace("handleExcelIntColumn", "").replace("Column_Fields", Column_Fields) + .replace("ExcelCompletion", "");; } - tmp_code = tmp_code.replace("handleBinaryType", handleBinaryTypeCode); UserDefinedJavaClassDef userDefinedJavaClassDef = new UserDefinedJavaClassDef(UserDefinedJavaClassDef.ClassType.TRANSFORM_CLASS, "Processor", tmp_code); userDefinedJavaClassDef.setActive(true); @@ -1121,15 +1129,15 @@ public class ExtractDataService { " \t}"; - 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" + - " }else{\n" + - " get(Fields.Out, filed).setValue(r, 0);\n" + - " get(Fields.Out, filed).getValueMeta().setType(2);\n" + - " }\n" + - " }\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" + +// " }else{\n" + +// " get(Fields.Out, filed).setValue(r, 0);\n" + +// " get(Fields.Out, filed).getValueMeta().setType(2);\n" + +// " }\n" + +// " }\n" ; private final static String handleExcelIntColumn = " \t\tif(tmp != null && tmp.endsWith(\".0\")){\n" + " try {\n" + @@ -1144,8 +1152,9 @@ public class ExtractDataService { " tmp = tmp.replaceAll(\"\\r\",\" \");\n" + " tmp = tmp.replaceAll(\"\\n\",\" \");\n" + " get(Fields.Out, filed).setValue(r, tmp);\n" + - " } \n" + - "\t\tif(tmp == null){\n" + + " } \n"; + + private final static String excelCompletion = "\t\tif(tmp == null){\n" + " \t\t\ttmp = \"\";\n" + "\t\t\tget(Fields.Out, filed).setValue(r, tmp);\n" + "\t\t}"; @@ -1180,7 +1189,7 @@ public class ExtractDataService { " for (String filed : fileds) {\n" + " String tmp = get(Fields.In, filed).getString(r);\n" + "handleWraps \n" + - "alterColumnTypeCode \n" + + "ExcelCompletion \n" + "handleBinaryType \n" + "handleExcelIntColumn \n" + " str = str + tmp;\n" + diff --git a/backend/src/main/java/io/dataease/service/message/SysMsgService.java b/backend/src/main/java/io/dataease/service/message/SysMsgService.java index 798e0b42a2..4344b0e247 100644 --- a/backend/src/main/java/io/dataease/service/message/SysMsgService.java +++ b/backend/src/main/java/io/dataease/service/message/SysMsgService.java @@ -312,4 +312,12 @@ public class SysMsgService { return sourceLists; } + public void setAllRead() { + SysMsg record = new SysMsg(); + record.setStatus(true); + SysMsgExample example = new SysMsgExample(); + example.createCriteria().andUserIdEqualTo(AuthUtils.getUser().getUserId()).andStatusEqualTo(false); + sysMsgMapper.updateByExampleSelective(record, example); + } + } diff --git a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java index 00ed8e5e45..c7932b861f 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java @@ -103,7 +103,34 @@ public class PanelGroupService { newDefaultPanel.setCreateBy(AuthUtils.getUser().getUsername()); checkPanelName(newDefaultPanel.getName(), newDefaultPanel.getPid(), PanelConstants.OPT_TYPE_INSERT, newDefaultPanel.getId()); panelGroupMapper.insertSelective(newDefaultPanel); - } else { + } else if ("copy".equals(request.getOptType())) { + panelId = UUID.randomUUID().toString(); + // 复制模板 + PanelGroupWithBLOBs newPanel = panelGroupMapper.selectByPrimaryKey(request.getId()); + // 插入校验 + if (StringUtils.isNotEmpty(request.getName())) { + checkPanelName(request.getName(), newPanel.getPid(), PanelConstants.OPT_TYPE_INSERT, request.getId()); + } + newPanel.setName(request.getName()); + newPanel.setId(panelId); + newPanel.setCreateBy(AuthUtils.getUser().getUsername()); + panelGroupMapper.insertSelective(newPanel); + } else if ("move".equals(request.getOptType())) { + PanelGroupWithBLOBs panelInfo = panelGroupMapper.selectByPrimaryKey(request.getId()); + if(panelInfo.getPid().equalsIgnoreCase(request.getPid())){ + DataEaseException.throwException(Translator.get("i18n_select_diff_folder")); + } + // 移动校验 + if (StringUtils.isNotEmpty(request.getName())) { + checkPanelName(request.getName(), request.getPid(), PanelConstants.OPT_TYPE_INSERT, request.getId()); + } + PanelGroupWithBLOBs record = new PanelGroupWithBLOBs(); + record.setName(request.getName()); + record.setId(request.getId()); + record.setPid(request.getPid()); + panelGroupMapper.updateByPrimaryKeySelective(record); + + }else { // 更新 if (StringUtils.isNotEmpty(request.getName())) { checkPanelName(request.getName(), request.getPid(), PanelConstants.OPT_TYPE_UPDATE, request.getId()); diff --git a/backend/src/main/java/io/dataease/service/panel/PanelPdfTemplateService.java b/backend/src/main/java/io/dataease/service/panel/PanelPdfTemplateService.java new file mode 100644 index 0000000000..ae1ae65e4f --- /dev/null +++ b/backend/src/main/java/io/dataease/service/panel/PanelPdfTemplateService.java @@ -0,0 +1,27 @@ +package io.dataease.service.panel; + +import io.dataease.base.domain.PanelPdfTemplate; +import io.dataease.base.domain.PanelPdfTemplateExample; +import io.dataease.base.mapper.PanelPdfTemplateMapper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * Author: wangjiahao + * Date: 9/1/21 + * Description: + */ +@Service +public class PanelPdfTemplateService { + + @Resource + private PanelPdfTemplateMapper panelPdfTemplateMapper; + + public List queryAll(){ + PanelPdfTemplateExample example = new PanelPdfTemplateExample(); + example.setOrderByClause("sort asc"); + return panelPdfTemplateMapper.selectByExampleWithBLOBs(example); + } +} diff --git a/backend/src/main/java/io/dataease/service/sys/SysUserService.java b/backend/src/main/java/io/dataease/service/sys/SysUserService.java index bfc1871ec8..9c704a4883 100644 --- a/backend/src/main/java/io/dataease/service/sys/SysUserService.java +++ b/backend/src/main/java/io/dataease/service/sys/SysUserService.java @@ -14,12 +14,16 @@ import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.CodingUtil; import io.dataease.controller.sys.base.BaseGridRequest; +import io.dataease.controller.sys.request.LdapAddRequest; 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.SysUserGridResponse; import io.dataease.controller.sys.response.SysUserRole; import io.dataease.i18n.Translator; +import io.dataease.plugins.common.entity.XpackLdapUserEntity; +import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo; + import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -29,6 +33,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; + +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -80,11 +86,13 @@ public class SysUserService { @Transactional public int save(SysUserCreateRequest request) { checkUsername(request); + checkEmail(request); SysUser user = BeanUtils.copyBean(new SysUser(), request); long now = System.currentTimeMillis(); user.setCreateTime(now); user.setUpdateTime(now); user.setIsAdmin(false); + user.setFrom(0); if (ObjectUtils.isEmpty(user.getPassword()) || StringUtils.equals(user.getPassword(), DEFAULT_PWD)) { user.setPassword(CodingUtil.md5(DEFAULT_PWD)); } else { @@ -99,6 +107,70 @@ public class SysUserService { return insert; } + @Transactional + public void saveOIDCUser(SSOUserInfo ssoUserInfo) { + long now = System.currentTimeMillis(); + SysUser sysUser = new SysUser(); + sysUser.setUsername(ssoUserInfo.getUsername()); + sysUser.setNickName(ssoUserInfo.getNickName()); + sysUser.setEmail(ssoUserInfo.getEmail()); + sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setCreateTime(now); + sysUser.setUpdateTime(now); + sysUser.setEnabled(1L); + sysUser.setLanguage("zh_CN"); + sysUser.setFrom(2); + sysUser.setIsAdmin(false); + sysUser.setSub(ssoUserInfo.getSub()); + sysUserMapper.insert(sysUser); + SysUser dbUser = findOne(sysUser); + if (null != dbUser && null != dbUser.getUserId()) { + // oidc默认角色是普通员工 + List roleIds = new ArrayList(); + roleIds.add(2L); + saveUserRoles( dbUser.getUserId(), roleIds); + } + } + + public String defaultPWD() { + return DEFAULT_PWD; + } + + @Transactional + public void saveLdapUsers(LdapAddRequest request) { + long now = System.currentTimeMillis(); + + List users = request.getUsers(); + List sysUsers = users.stream().map(user -> { + SysUser sysUser = BeanUtils.copyBean(new SysUser(), user); + sysUser.setUsername(user.getUserName()); + sysUser.setDeptId(request.getDeptId()); + sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setCreateTime(now); + sysUser.setUpdateTime(now); + sysUser.setEnabled(request.getEnabled()); + sysUser.setLanguage("zh_CN"); + sysUser.setIsAdmin(false); + sysUser.setFrom(1); + return sysUser; + }).collect(Collectors.toList()); + + sysUsers.forEach(sysUser -> { + sysUserMapper.insert(sysUser); + SysUser dbUser = findOne(sysUser); + if (null != dbUser && null != dbUser.getUserId()) { + saveUserRoles( dbUser.getUserId(), request.getRoleIds()); + } + }); + } + + public List ldapUserNames() { + + List usernames = extSysUserMapper.ldapUserNames(1); + return usernames; + + } + /** * 修改用户密码清楚缓存 * @@ -109,6 +181,7 @@ public class SysUserService { @Transactional public int update(SysUserCreateRequest request) { checkUsername(request); + checkEmail(request); if (StringUtils.isEmpty(request.getPassword())) { request.setPassword(null); } @@ -251,4 +324,19 @@ public class SysUserService { throw new RuntimeException(Translator.get("i18n_username_exists")); } } + + private void checkEmail(SysUserCreateRequest request) { + SysUserExample sysUserExample = new SysUserExample(); + SysUserExample.Criteria criteria = sysUserExample.createCriteria(); + if (request.getUserId() != null) { + criteria.andUserIdNotEqualTo(request.getUserId()); + } + criteria.andEmailEqualTo(request.getEmail()); + List sysUsers = sysUserMapper.selectByExample(sysUserExample); + if (CollectionUtils.isNotEmpty(sysUsers)) { + throw new RuntimeException(Translator.get("i18n_email_exists")); + } + } + + } diff --git a/backend/src/main/java/io/dataease/service/system/SystemParameterService.java b/backend/src/main/java/io/dataease/service/system/SystemParameterService.java index fd868cb3c7..aa4c0c41ca 100644 --- a/backend/src/main/java/io/dataease/service/system/SystemParameterService.java +++ b/backend/src/main/java/io/dataease/service/system/SystemParameterService.java @@ -229,9 +229,9 @@ public class SystemParameterService { } - public static void main(String[] args) { + /* public static void main(String[] args) { String info="[{\"paramKey\":\"base.url\",\"paramValue\":null,\"type\":\"text\",\"sort\":1,\"file\":null,\"fileName\":null},{\"paramKey\":\"base.title\",\"paramValue\":\"DataEase Title\",\"type\":\"text\",\"sort\":3,\"file\":null,\"fileName\":null},{\"paramKey\":\"base.logo\",\"paramValue\":\"DataEase\",\"type\":\"text\",\"sort\":4,\"file\":null,\"fileName\":\"favicon.icon.png\"}]"; List temp = JSON.parseArray(info,SystemParameterDTO.class); // System.out.println("===>"); - } + } */ } diff --git a/backend/src/main/resources/db/migration/V25__add_auth.sql b/backend/src/main/resources/db/migration/V25__add_auth.sql index 9fa1d70f01..811a40b967 100644 --- a/backend/src/main/resources/db/migration/V25__add_auth.sql +++ b/backend/src/main/resources/db/migration/V25__add_auth.sql @@ -383,3 +383,72 @@ INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_typ INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('dc1d32ff-064a-11ec-a2b0-0242ac130003', 'd78c6e77-9cc7-44f8-a730-32ca6ca33f60', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1629967913000, NULL); INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('dc1d3358-064a-11ec-a2b0-0242ac130003', 'd78c6e77-9cc7-44f8-a730-32ca6ca33f60', 'i18n_auth_manage', 5, 0, 'manage', '基础权限-管理', 'admin', 1629967913000, NULL); INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('dc1d33a4-064a-11ec-a2b0-0242ac130003', 'd78c6e77-9cc7-44f8-a730-32ca6ca33f60', 'i18n_auth_view', 1, 1, 'view', '基础权限-查看', 'admin', 1629967913000, NULL); + + +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('00590a7c-8e7b-45f4-8428-55532be07602', '10', 'menu', '1', 'role', 1630482462199, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('06ba0edb-143d-4b51-a864-8cfcf2b5d71e', '1', 'menu', '1', 'role', 1630482426344, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('1a18aa12-8daa-4f47-b5eb-999e473273df', '6', 'menu', '1', 'role', 1630482450994, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('1bf39d8d-7fe9-4832-8df3-f74b21a69288', '4', 'menu', '1', 'role', 1630482450458, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('359771bb-95b8-40ad-a6c5-b5c39c93cb10', '24', 'menu', '1', 'role', 1630482459156, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('5960fd93-013c-4636-8f6b-2e6b49b7e869', '5', 'menu', '1', 'role', 1630482450626, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('5e0a9ad5-81ed-4f83-91f6-a74be724bda7', '23', 'menu', '1', 'role', 1630482452131, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('5ec5c9a7-04c0-4655-9b63-9ca5a439e2f3', '18', 'menu', '1', 'role', 1630482451166, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('60b3644b-2493-4805-8204-90880cfac9c6', '8', 'menu', '1', 'role', 1630482460538, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('74ff225f-2a79-4221-9b32-c6eb9bcadd61', '19', 'menu', '1', 'role', 1630482451329, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('7823499e-dbb6-42a9-a28f-22377de18a39', '40', 'menu', '1', 'role', 1630482427369, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('88c778e6-ede3-4397-af4c-375e1feac8ef', '41', 'menu', '1', 'role', 1630482452340, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('998e402b-6f15-48dc-ae4d-2cd04460a3f3', '15', 'menu', '1', 'role', 1630482426695, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('9f01c7ef-753b-4dea-97d4-c199f84c2c74', '17', 'menu', '1', 'role', 1630482427049, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('a6837d68-80a6-4a26-a7c0-e84001dfc817', '34', 'menu', '1', 'role', 1630482458991, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('b319dc39-c499-423b-8e99-22e9a0caba6f', '58', 'menu', '1', 'role', 1630482427545, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('bdd3bed8-35d4-4aa8-84c2-85e2412d6cbb', '2', 'menu', '1', 'role', 1630482426513, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('c18b47e9-aa22-4f17-b12c-a3459ca4dd90', '28', 'menu', '1', 'role', 1630482427208, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('d3d558e5-b0b1-4475-bb69-f20fa5c47f4f', '22', 'menu', '1', 'role', 1630482451962, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('d400c00f-9c18-4eb6-a70f-9c8caf8dddfe', '21', 'menu', '1', 'role', 1630482451749, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('d8d18115-c7b9-4e99-96a8-fd1bbfddf543', '16', 'menu', '1', 'role', 1630482426857, NULL, 'admin', NULL); +INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`) VALUES ('f17dc7f3-c97a-41b4-a2f4-1a04a857ae8a', '20', 'menu', '1', 'role', 1630482451497, NULL, 'admin', NULL); + +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf3c570c-0af8-11ec-a2b0-0242ac130003', '06ba0edb-143d-4b51-a864-8cfcf2b5d71e', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482428000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf3c59d1-0af8-11ec-a2b0-0242ac130003', '06ba0edb-143d-4b51-a864-8cfcf2b5d71e', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482428000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf573296-0af8-11ec-a2b0-0242ac130003', 'bdd3bed8-35d4-4aa8-84c2-85e2412d6cbb', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482428000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf57354a-0af8-11ec-a2b0-0242ac130003', 'bdd3bed8-35d4-4aa8-84c2-85e2412d6cbb', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482428000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf705f77-0af8-11ec-a2b0-0242ac130003', '998e402b-6f15-48dc-ae4d-2cd04460a3f3', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf7061d1-0af8-11ec-a2b0-0242ac130003', '998e402b-6f15-48dc-ae4d-2cd04460a3f3', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf8b490d-0af8-11ec-a2b0-0242ac130003', 'd8d18115-c7b9-4e99-96a8-fd1bbfddf543', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cf8b4b35-0af8-11ec-a2b0-0242ac130003', 'd8d18115-c7b9-4e99-96a8-fd1bbfddf543', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cfa66a8d-0af8-11ec-a2b0-0242ac130003', '9f01c7ef-753b-4dea-97d4-c199f84c2c74', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cfa66ca4-0af8-11ec-a2b0-0242ac130003', '9f01c7ef-753b-4dea-97d4-c199f84c2c74', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cfbf0608-0af8-11ec-a2b0-0242ac130003', 'c18b47e9-aa22-4f17-b12c-a3459ca4dd90', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cfbf0839-0af8-11ec-a2b0-0242ac130003', 'c18b47e9-aa22-4f17-b12c-a3459ca4dd90', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cfd814bc-0af8-11ec-a2b0-0242ac130003', '7823499e-dbb6-42a9-a28f-22377de18a39', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cfd816d7-0af8-11ec-a2b0-0242ac130003', '7823499e-dbb6-42a9-a28f-22377de18a39', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cff28219-0af8-11ec-a2b0-0242ac130003', 'b319dc39-c499-423b-8e99-22e9a0caba6f', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('cff28507-0af8-11ec-a2b0-0242ac130003', 'b319dc39-c499-423b-8e99-22e9a0caba6f', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482429000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('dd9ba5c6-0af8-11ec-a2b0-0242ac130003', '1bf39d8d-7fe9-4832-8df3-f74b21a69288', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482452000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('dd9ba7e8-0af8-11ec-a2b0-0242ac130003', '1bf39d8d-7fe9-4832-8df3-f74b21a69288', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482452000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('ddb3094b-0af8-11ec-a2b0-0242ac130003', '5960fd93-013c-4636-8f6b-2e6b49b7e869', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482452000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('ddb30bd2-0af8-11ec-a2b0-0242ac130003', '5960fd93-013c-4636-8f6b-2e6b49b7e869', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482452000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('ddec6eab-0af8-11ec-a2b0-0242ac130003', '1a18aa12-8daa-4f47-b5eb-999e473273df', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('ddeccfa8-0af8-11ec-a2b0-0242ac130003', '1a18aa12-8daa-4f47-b5eb-999e473273df', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de0719cb-0af8-11ec-a2b0-0242ac130003', '5ec5c9a7-04c0-4655-9b63-9ca5a439e2f3', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de071bd9-0af8-11ec-a2b0-0242ac130003', '5ec5c9a7-04c0-4655-9b63-9ca5a439e2f3', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de202758-0af8-11ec-a2b0-0242ac130003', '74ff225f-2a79-4221-9b32-c6eb9bcadd61', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de202961-0af8-11ec-a2b0-0242ac130003', '74ff225f-2a79-4221-9b32-c6eb9bcadd61', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de42f5ec-0af8-11ec-a2b0-0242ac130003', 'f17dc7f3-c97a-41b4-a2f4-1a04a857ae8a', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de42f8b4-0af8-11ec-a2b0-0242ac130003', 'f17dc7f3-c97a-41b4-a2f4-1a04a857ae8a', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482453000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de65f6d9-0af8-11ec-a2b0-0242ac130003', 'd400c00f-9c18-4eb6-a70f-9c8caf8dddfe', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de65fa72-0af8-11ec-a2b0-0242ac130003', 'd400c00f-9c18-4eb6-a70f-9c8caf8dddfe', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de80ddc9-0af8-11ec-a2b0-0242ac130003', 'd3d558e5-b0b1-4475-bb69-f20fa5c47f4f', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de80e001-0af8-11ec-a2b0-0242ac130003', 'd3d558e5-b0b1-4475-bb69-f20fa5c47f4f', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de9f30cd-0af8-11ec-a2b0-0242ac130003', '5e0a9ad5-81ed-4f83-91f6-a74be724bda7', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('de9f32d3-0af8-11ec-a2b0-0242ac130003', '5e0a9ad5-81ed-4f83-91f6-a74be724bda7', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('dec15e1b-0af8-11ec-a2b0-0242ac130003', '88c778e6-ede3-4397-af4c-375e1feac8ef', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('dec16031-0af8-11ec-a2b0-0242ac130003', '88c778e6-ede3-4397-af4c-375e1feac8ef', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482454000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e2b029b9-0af8-11ec-a2b0-0242ac130003', 'a6837d68-80a6-4a26-a7c0-e84001dfc817', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482461000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e2b02bcb-0af8-11ec-a2b0-0242ac130003', 'a6837d68-80a6-4a26-a7c0-e84001dfc817', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482461000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e2c9aba7-0af8-11ec-a2b0-0242ac130003', '359771bb-95b8-40ad-a6c5-b5c39c93cb10', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482461000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e2c9adc8-0af8-11ec-a2b0-0242ac130003', '359771bb-95b8-40ad-a6c5-b5c39c93cb10', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482461000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e39cb3fe-0af8-11ec-a2b0-0242ac130003', '60b3644b-2493-4805-8204-90880cfac9c6', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482462000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e39cb619-0af8-11ec-a2b0-0242ac130003', '60b3644b-2493-4805-8204-90880cfac9c6', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482462000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e49bef48-0af8-11ec-a2b0-0242ac130003', '00590a7c-8e7b-45f4-8428-55532be07602', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1630482464000, NULL); +INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`) VALUES ('e49bf17e-0af8-11ec-a2b0-0242ac130003', '00590a7c-8e7b-45f4-8428-55532be07602', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1630482464000, NULL); diff --git a/backend/src/main/resources/db/migration/V26__de1.3.sql b/backend/src/main/resources/db/migration/V26__de1.3.sql new file mode 100644 index 0000000000..8e464687b7 --- /dev/null +++ b/backend/src/main/resources/db/migration/V26__de1.3.sql @@ -0,0 +1,51 @@ +-- ---------------------------- +-- Records of sys_msg_type +-- ---------------------------- +BEGIN; +INSERT INTO `sys_msg_type` VALUES (7, 0, 'i18n_msg_type_ds_invalid', 'datasource', 'to-msg-ds'); +INSERT INTO `sys_msg_type` VALUES (8, 7, 'i18n_msg_type_ds_invalid', 'datasource', 'to-msg-ds'); +COMMIT; + + +-- ---------------------------- +-- Table structure for panel_pdf_template +-- ---------------------------- +DROP TABLE IF EXISTS `panel_pdf_template`; +CREATE TABLE `panel_pdf_template` ( + `id` varchar(50) NOT NULL COMMENT 'id', + `name` varchar(255) DEFAULT NULL COMMENT '模板名称', + `create_time` bigint(13) DEFAULT NULL COMMENT '创建时间', + `create_user` varchar(255) DEFAULT NULL COMMENT '创建人', + `template_content` longtext COMMENT '模板内容', + `sort` int(8) DEFAULT NULL COMMENT '排序', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `chart_view` ADD COLUMN `y_axis_ext` LONGTEXT COMMENT '副轴' AFTER `y_axis`; +UPDATE `chart_view` SET `y_axis_ext` = '[]'; + + +ALTER TABLE `sys_user` ADD COLUMN `from` int(4) NOT NULL COMMENT '来源' AFTER `language`; + +INSERT INTO `sys_menu` VALUES (60, 1, 0, 1, '导入LDAP用户', 'system-user-import', 'system/user/imp-ldap', 11, NULL, 'user-ldap', b'0', b'0', b'1', 'user:import', NULL, NULL, NULL, NULL); + +BEGIN; +INSERT INTO `system_parameter` VALUES ('ldap.url', NULL, 'text', 1); +INSERT INTO `system_parameter` VALUES ('ldap.dn', NULL, 'text', 2); +INSERT INTO `system_parameter` VALUES ('ldap.password', NULL, 'password', 3); +INSERT INTO `system_parameter` VALUES ('ldap.ou', NULL, 'text', 4); +INSERT INTO `system_parameter` VALUES ('ldap.mapping', NULL, 'text', 6); +INSERT INTO `system_parameter` VALUES ('ldap.open', NULL, 'text', 7); + +INSERT INTO `system_parameter` VALUES ('oidc.authEndpoint', NULL, 'text', 1); +INSERT INTO `system_parameter` VALUES ('oidc.tokenEndpoint', NULL, 'text', 2); +INSERT INTO `system_parameter` VALUES ('oidc.userinfoEndpoint', NULL, 'text', 3); +INSERT INTO `system_parameter` VALUES ('oidc.logoutEndpoint', NULL, 'text', 4); +INSERT INTO `system_parameter` VALUES ('oidc.clientId', NULL, 'text', 5); +INSERT INTO `system_parameter` VALUES ('oidc.secret', NULL, 'password', 6); +INSERT INTO `system_parameter` VALUES ('oidc.scope', NULL, 'text', 7); +INSERT INTO `system_parameter` VALUES ('oidc.redirectUrl', NULL, 'text', 8); +INSERT INTO `system_parameter` VALUES ('oidc.open', NULL, 'text', 9); +COMMIT; + +ALTER TABLE `sys_user` ADD COLUMN `sub` varchar(255) COMMENT 'oidc用户ID' AFTER `from`; diff --git a/backend/src/main/resources/generatorConfig.xml b/backend/src/main/resources/generatorConfig.xml index 9764b3b112..d33ea84c23 100644 --- a/backend/src/main/resources/generatorConfig.xml +++ b/backend/src/main/resources/generatorConfig.xml @@ -64,7 +64,9 @@ + + diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index c1735c6cb2..443db6a5d3 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -198,6 +198,7 @@ authsource_configuration_is_null=Authentication source configuration cannot be e 删除角色=Delete Role 删除连接=Delete Connection 显示设置=Display +系统参数=System Param 参数管理=Parameter 数据源=Data Source 数据源表单=Data source form @@ -234,6 +235,7 @@ i18n_chart_count=Count* i18n_excel_have_merge_region=Excel has merged region i18n_cron_expression_error=Cron expression error i18n_same_folder_can_not_repeat=Name is already used in the same folder +i18n_select_diff_folder= Select Diff Folder i18n_default_panel=Default Dashboard i18n_panel_list=Dashboard i18n_processing_data=Processing data now, Refresh later @@ -242,6 +244,7 @@ i18n_union_field_exists=The same field can't in two dataset i18n_cron_time_error=Start time can't greater then end time i18n_auth_source_be_canceled=This Auth Resource Already Be Canceled,Please Connect Admin i18n_username_exists=ID is already exists +i18n_email_exists=Email is already exists i18n_ds_name_exists=Datasource name used i18n_sync_job_exists=There is already a synchronization task running, please try again later i18n_datasource_check_fail=Invalid,please check config @@ -280,4 +283,7 @@ i18n_datasource_connect_error=Data source connection exception: i18n_check_sql_error=Check incremental SQL exception, i18n_change_task_status_error=Suspension is not allowed. The task status is: i18n_Stopped=END -i18n_Exec=Running \ No newline at end of file +i18n_Exec=Running +i18n_no_trigger=The current setting does not trigger task generation. +i18n_dataset_field_delete=Union field deleted,please set again and redo. +i18n_es_limit=Elasticsearch version cannot be less than 6.3 \ No newline at end of file diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 9ccd5e60bf..7d9b47b654 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -198,6 +198,7 @@ authsource_configuration_is_null=认证源配置不能为空 删除角色=删除角色 删除连接=删除连接 显示设置=显示设置 +系统参数=系统参数 数据源=数据源 数据源表单=数据源表单 数据集=数据集 @@ -233,6 +234,7 @@ i18n_chart_count=记录数* i18n_excel_have_merge_region=Excel 存在合并单元格 i18n_cron_expression_error=Cron 表达式校验错误 i18n_same_folder_can_not_repeat=同一目录下该名称已被使用 +i18n_select_diff_folder= 请选择不同的目录 i18n_default_panel=默认仪表板 i18n_panel_list=仪表板 i18n_processing_data=正在处理数据,稍后刷新 @@ -241,6 +243,7 @@ i18n_union_field_exists=两个数据集之间关联不能出现多次相同字 i18n_cron_time_error=开始时间不能大于结束时间 i18n_auth_source_be_canceled=本用户当前资源所有授权权限已经被取消,如需再次开通,请联系管理员 i18n_username_exists=用户 ID 已存在 +i18n_email_exists=邮箱已存在 i18n_ds_name_exists=数据源名称已被使用 i18n_sync_job_exists=已经有同步任务在运行,稍后重试 i18n_datasource_check_fail=校验失败,请检查配置信息 @@ -280,4 +283,6 @@ i18n_check_sql_error=校验增量 SQL 异常, i18n_change_task_status_error=不允许暂停,任务状态为: i18n_Stopped=执行结束 i18n_Exec=运行中 - +i18n_no_trigger=当前设置没有触发任务生成 +i18n_dataset_field_delete=该自定义数据集有关联字段被删除,请重新确认关联关系并重做该数据集 +i18n_es_limit=Elasticsearch 版本不能小于6.3 diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index 9e79137c74..cf99c59593 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -200,6 +200,7 @@ authsource_configuration_is_null=認證源配置不能為空 删除角色=刪除角色 刪除连接=刪除鏈接 显示设置=顯示設置 +系统参数=系統參數 参数管理=參數管理 数据源=數據源 数据源表单=數據源表單 @@ -236,6 +237,7 @@ i18n_chart_count=記錄數* i18n_excel_have_merge_region=Excel存在合並單元格 i18n_cron_expression_error=Cron表達式校驗錯誤 i18n_same_folder_can_not_repeat=同一目錄下該名稱已被使用 +i18n_select_diff_folder= 请选择不同的目录 i18n_default_panel=默認儀表板 i18n_panel_list=儀表板 i18n_processing_data=正在處理數據,稍後刷新 @@ -244,6 +246,7 @@ i18n_union_field_exists=兩個數據集之間關聯不能出現多次相同字 i18n_cron_time_error=開始時間不能大於結束時間 i18n_auth_source_be_canceled=本用户当前资源所有授权权限已经被取消,如需再次开通,请联系管理员 i18n_username_exists=用戶ID已存在 +i18n_email_exists=郵箱已存在 i18n_ds_name_exists=數據源名稱已被使用 i18n_sync_job_exists=已經有同步任務在運行,稍後重試 i18n_datasource_check_fail=校驗失敗,請檢查配置信息 @@ -282,4 +285,7 @@ i18n_datasource_connect_error=數據源連接異常: i18n_check_sql_error=校驗增量SQL異常, i18n_change_task_status_error=不允許暫停,任務狀態為: i18n_Stopped=執行結束 -i18n_Exec=運行中 \ No newline at end of file +i18n_Exec=運行中 +i18n_no_trigger=当前设置没有触发任务生成 當前設置沒有觸發任務生成. +i18n_dataset_field_delete=該自定義數據集有關聯字段被刪除,請重新確認關聯關系並重做該數據集 +i18n_es_limit=Elasticsearch 版本不能小於6.3 \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index d33d755db0..42f7c9c21f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" }, "dependencies": { + "@antv/g2plot": "^2.3.32", "@riophae/vue-treeselect": "0.4.0", "@tinymce/tinymce-vue": "^3.2.8", "axios": "^0.21.1", @@ -28,6 +29,7 @@ "html2canvasde": "^v1.1.4-de", "js-cookie": "2.2.0", "jsencrypt": "^3.0.0-rc.1", + "jspdf": "^2.3.1", "lodash": "4.17.21", "normalize.css": "7.0.0", "nprogress": "0.2.0", @@ -41,9 +43,10 @@ "vue-axios": "3.2.4", "vue-clipboard2": "0.3.1", "vue-codemirror": "^4.0.6", - "vue-fullscreen": "^2.5.1", + "vue-fullscreen": "^2.5.2", "vue-i18n": "7.3.2", "vue-router": "3.0.6", + "vue-to-pdf": "^1.0.0", "vue-uuid": "2.0.2", "vuedraggable": "^2.24.3", "vuex": "3.1.0", diff --git a/frontend/pom.xml b/frontend/pom.xml index fdb5d8962b..604c6b2027 100644 --- a/frontend/pom.xml +++ b/frontend/pom.xml @@ -6,7 +6,7 @@ dataease-server io.dataease - 1.2.0 + 1.3.0 4.0.0 diff --git a/frontend/src/api/panel/pdfTemplate.js b/frontend/src/api/panel/pdfTemplate.js new file mode 100644 index 0000000000..afd0efce18 --- /dev/null +++ b/frontend/src/api/panel/pdfTemplate.js @@ -0,0 +1,11 @@ +import request from '@/utils/request' + + +export function queryAll() { + return request({ + url: '/pdf-template/queryAll', + method: 'get', + loading: true, + timeout: 30000 + }) +} diff --git a/frontend/src/api/system/msg.js b/frontend/src/api/system/msg.js index 45ac7c687b..4dc120ae61 100644 --- a/frontend/src/api/system/msg.js +++ b/frontend/src/api/system/msg.js @@ -35,6 +35,14 @@ export function batchRead(data) { }) } +export function allRead() { + return request({ + url: '/api/sys_msg/allRead', + method: 'post', + loading: true + }) +} + export function batchDelete(data) { return request({ url: '/api/sys_msg/batchDelete', diff --git a/frontend/src/api/system/user.js b/frontend/src/api/system/user.js index 47cfc04581..64d7d65f05 100644 --- a/frontend/src/api/system/user.js +++ b/frontend/src/api/system/user.js @@ -98,4 +98,29 @@ export function roleGrid(pageIndex, pageSize, data) { }) } -export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd, allRoles, roleGrid } +export function ldapUsers(data) { + return request({ + url: '/plugin/ldap/users', + method: 'post', + loading: true + }) +} + +export function saveLdapUser(data) { + return request({ + url: '/api/user/sync', + method: 'post', + loading: true, + data + }) +} + +export function existLdapUsers() { + return request({ + url: '/api/user/existLdapUsers', + method: 'post', + loading: false + }) +} + +export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd, allRoles, roleGrid, ldapUsers, saveLdapUser, existLdapUsers } diff --git a/frontend/src/api/user.js b/frontend/src/api/user.js index ee99beb1eb..e9ddcd6ab0 100644 --- a/frontend/src/api/user.js +++ b/frontend/src/api/user.js @@ -50,3 +50,17 @@ export function languageApi(language) { method: 'post' }) } + +export function ldapStatus() { + return request({ + url: '/api/auth/isOpenLdap', + method: 'post' + }) +} + +export function oidcStatus() { + return request({ + url: '/api/auth/isOpenOidc', + method: 'post' + }) +} diff --git a/frontend/src/components/DeDrag/MoveInShadow.vue b/frontend/src/components/DeDrag/MoveInShadow.vue new file mode 100644 index 0000000000..366436c3aa --- /dev/null +++ b/frontend/src/components/DeDrag/MoveInShadow.vue @@ -0,0 +1,69 @@ + + + + diff --git a/frontend/src/components/DeDrag/index.vue b/frontend/src/components/DeDrag/index.vue index eefbe0ffc2..5828cae258 100644 --- a/frontend/src/components/DeDrag/index.vue +++ b/frontend/src/components/DeDrag/index.vue @@ -20,7 +20,8 @@ @mouseenter="enter" @mouseleave="leave" > - + +
- +
+ +
@@ -49,7 +52,7 @@ import EditBar from '@/components/canvas/components/Editor/EditBar' export default { replace: true, - name: 'VueDragResizeRotate', + name: 'Dedrag', components: { EditBar }, props: { className: { @@ -440,6 +443,14 @@ export default { ...(this.dragging && this.disableUserSelect ? userSelectNone : userSelectAuto) } }, + resizeShadowStyle() { + return { + width: this.computedWidth, + height: this.computedHeight, + opacity: 0.4, + background: 'gray' + } + }, // 控制柄显示与否 actualHandles() { if (!this.resizable) return [] @@ -464,9 +475,48 @@ export default { return this.height + 'px' }, + // 根据left right 算出元素的宽度 + computedMainSlotWidth() { + if (this.w === 'auto') { + if (!this.widthTouched) { + return 'auto' + } + } + if (this.canvasStyleData.auxiliaryMatrix) { + const width = Math.round(this.width / this.curCanvasScale.matrixStyleWidth) * this.curCanvasScale.matrixStyleWidth + return width + 'px' + } else { + return this.width + 'px' + } + }, + // 根据top bottom 算出元素的宽度 + computedMainSlotHeight() { + if (this.h === 'auto') { + if (!this.heightTouched) { + return 'auto' + } + } + if (this.canvasStyleData.auxiliaryMatrix) { + const height = Math.round(this.height / this.curCanvasScale.matrixStyleHeight) * this.curCanvasScale.matrixStyleHeight + return height + 'px' + } else { + return this.height + 'px' + } + }, + // private + mainSlotStyle() { + const style = { + width: this.computedMainSlotWidth, + height: this.computedMainSlotHeight + } + // console.log('style=>' + JSON.stringify(style)) + return style + }, + curComponent() { + return this.$store.state.curComponent + }, ...mapState([ - 'curComponent', 'editor', 'curCanvasScale', 'canvasStyleData', @@ -566,6 +616,18 @@ export default { this.beforeDestroyFunction() this.createdFunction() this.mountedFunction() + }, + // private 监控dragging resizing + dragging(val) { + if (this.enabled) { + this.curComponent.optStatus.dragging = val + } + }, + // private 监控dragging resizing + resizing(val) { + if (this.enabled) { + this.curComponent.optStatus.resizing = val + } } }, created: function() { @@ -610,7 +672,7 @@ export default { const rect = this.$el.parentNode.getBoundingClientRect() this.parentX = rect.x this.parentY = rect.y - return [Math.round(parseFloat(style.getPropertyValue('width'), 10)), Math.round(parseFloat(style.getPropertyValue('height'), 10))] + return [Math.round(parseFloat(style.getPropertyValue('width'), 10)), 100000] } if (typeof this.parent === 'string') { const parentNode = document.querySelector(this.parent) @@ -629,7 +691,7 @@ export default { elementMouseDown(e) { // private 设置当前组件数据及状态 this.$store.commit('setClickComponentStatus', true) - if (this.element.component !== 'v-text' && this.element.component !== 'rect-shape' && this.element.component !== 'de-input-search' && this.element.component !== 'de-select-grid' && this.element.component !== 'de-number-range') { + if (this.element.component !== 'v-text' && this.element.component !== 'rect-shape' && this.element.component !== 'de-input-search' && this.element.component !== 'de-select-grid' && this.element.component !== 'de-number-range' && this.element.component !== 'de-date') { e.preventDefault() } // 阻止冒泡事件 @@ -1176,7 +1238,7 @@ export default { if (this.canvasStyleData.auxiliaryMatrix) { this.recordMatrixCurStyle() } - this.hasMove && this.$store.commit('recordSnapshot') + this.hasMove && this.$store.commit('recordSnapshot', 'handleUp') // 记录snapshot后 移动已记录设置为false this.hasMove = false @@ -1490,7 +1552,7 @@ export default { // resize const self = this setTimeout(function() { - self.$emit('resizestop') + self.$emit('resizeView') }, 200) }, mountedFunction() { @@ -1650,6 +1712,10 @@ export default { opacity: 0.5; } +.gap_class{ + padding:5px; +} + /*.mouseOn >>> .icon-shezhi{*/ /* z-index: 2;*/ /* display:block!important;*/ diff --git a/frontend/src/components/DeDrag/shadow.vue b/frontend/src/components/DeDrag/shadow.vue new file mode 100644 index 0000000000..1277038296 --- /dev/null +++ b/frontend/src/components/DeDrag/shadow.vue @@ -0,0 +1,96 @@ + + + + diff --git a/frontend/src/components/LangSelect/index.vue b/frontend/src/components/LangSelect/index.vue index a32137c94d..55b565ecb0 100644 --- a/frontend/src/components/LangSelect/index.vue +++ b/frontend/src/components/LangSelect/index.vue @@ -1,7 +1,7 @@ - - - - diff --git a/frontend/src/components/Settings/index.vue b/frontend/src/components/Settings/index.vue deleted file mode 100644 index 0fb565e14a..0000000000 --- a/frontend/src/components/Settings/index.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - - - diff --git a/frontend/src/components/ThemePicker/index.vue b/frontend/src/components/ThemePicker/index.vue index 2fc497be2f..1bd21b4364 100644 --- a/frontend/src/components/ThemePicker/index.vue +++ b/frontend/src/components/ThemePicker/index.vue @@ -8,9 +8,9 @@ diff --git a/frontend/src/components/TreeSelector/index.vue b/frontend/src/components/TreeSelector/index.vue new file mode 100644 index 0000000000..72ec3b7e72 --- /dev/null +++ b/frontend/src/components/TreeSelector/index.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/frontend/src/components/back-button/index.vue b/frontend/src/components/back-button/index.vue index 6d72ad6009..65f860fd03 100644 --- a/frontend/src/components/back-button/index.vue +++ b/frontend/src/components/back-button/index.vue @@ -31,8 +31,6 @@ export default { \ No newline at end of file diff --git a/frontend/src/icons/svg/chart-mix.svg b/frontend/src/icons/svg/chart-mix.svg new file mode 100644 index 0000000000..b9f42e5e71 --- /dev/null +++ b/frontend/src/icons/svg/chart-mix.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/docs.svg b/frontend/src/icons/svg/docs.svg index 42a1046e3d..f699a5931d 100644 --- a/frontend/src/icons/svg/docs.svg +++ b/frontend/src/icons/svg/docs.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/icons/svg/language.svg b/frontend/src/icons/svg/language.svg index 312f4f3b54..143b3a6d73 100644 --- a/frontend/src/icons/svg/language.svg +++ b/frontend/src/icons/svg/language.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/icons/svg/liquid.svg b/frontend/src/icons/svg/liquid.svg new file mode 100644 index 0000000000..6cdd202223 --- /dev/null +++ b/frontend/src/icons/svg/liquid.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/table-info.svg b/frontend/src/icons/svg/table-info.svg new file mode 100644 index 0000000000..0f69063b44 --- /dev/null +++ b/frontend/src/icons/svg/table-info.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/table-normal.svg b/frontend/src/icons/svg/table-normal.svg index bbe3facfdc..9ca48cc2c7 100644 --- a/frontend/src/icons/svg/table-normal.svg +++ b/frontend/src/icons/svg/table-normal.svg @@ -1 +1 @@ - + diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 3f3ab667a7..17846bd595 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -130,6 +130,8 @@ export default { re_login: 'Login again' }, commons: { + search: 'Search', + folder: 'Folder', no_target_permission: 'No permission', success: 'Success', switch_lang: 'Switch Language Success', @@ -431,6 +433,11 @@ export default { fixedHeader: 'Fixed Header', sidebarLogo: 'Sidebar Logo' }, + sysParams: { + display: 'Display Setting', + ldap: 'LDAP Setting', + oidc: 'OIDC Setting' + }, license: { i18n_no_license_record: 'No License Record', i18n_license_is_empty: 'License is empty.', @@ -498,6 +505,47 @@ export default { change_password: 'Change Password', search_by_name: 'Search by name' }, + ldap: { + url: 'LDAP url', + dn: 'LDAP DN', + password: 'Password', + ou: 'OU', + filter: 'filter', + mapping: 'LDAP mapping', + open: 'Enable LDAP Authentication', + input_url: 'Please key LDAP url', + input_dn: 'Please key DN', + input_password: 'Please key password', + input_ou: 'Please key OU', + input_filter: 'Please key filter', + input_mapping: 'Please key LDAP mapping', + input_username: 'Please key username', + input_url_placeholder: 'Please key url (like ldap://localhost:389)', + input_ou_placeholder: 'Please key OU ', + input_filter_placeholder: 'Please key filter', + input_mapping_placeholder: 'like:{"username":"uid","name":"sn","email":"mail"}', + test_connect: 'Test connect', + edit: 'Edit', + login_success: 'Login success', + url_cannot_be_empty: 'LDAP url can not be empty', + dn_cannot_be_empty: 'LDAP DN can not be empty', + ou_cannot_be_empty: 'LDAP OU can not be empty', + filter_cannot_be_empty: 'LDAP filter can not be empty', + mapping_cannot_be_empty: 'LDAP mapping can not be empty', + password_cannot_be_empty: 'LDAP password can not be empty', + import_ldap: 'Import LDAP User' + }, + oidc: { + auth_endpoint: 'Please key AuthEndpoint', + token_endpoint: 'Please key TokenEndpoint', + userinfo_endpoint: 'Please key UserinfoEndpoint', + logout_endpoint: 'Please key logoutEndpoint', + clientId: 'Please key ClientId', + secret: 'Please key Secret', + scope: 'Please key scope', + redirectUrl: 'Please key redirectUrl', + open: 'Enable OIDC Authentication' + }, role: { menu_authorization: 'Menu Authorization', data_authorization: 'Data Authorization', @@ -746,7 +794,8 @@ export default { filter_condition: 'Filter Condition', filter_field_can_null: 'Filter field must choose', preview_100_data: 'Preview 100 rows', - chart_table_normal: 'Detail Table', + chart_table_normal: 'Summary Table', + chart_table_info: 'Detail Table', chart_card: 'KPI Card', chart_bar: 'Base Bar', chart_bar_stack: 'Stack Bar', @@ -848,7 +897,33 @@ export default { system_case: 'System', custom_case: 'Custom', last_layer: 'This Is The Last Layer', - radar_size: 'Size' + radar_size: 'Size', + chart_mix: 'Mix', + axis_value: 'Axis Value', + axis_value_min: 'Min', + axis_value_max: 'Max', + axis_value_split: 'Split', + axis_auto: 'Auto', + table_info_switch: 'Switch detail table will clear dimensions', + drag_block_value_axis_main: 'Main Axis Value', + drag_block_value_axis_ext: 'Ext Axis Value', + yAxis_main: 'Main Vertical Axis', + yAxis_ext: 'Ext Vertical Axis', + total: 'Total', + items: 'Items', + chart_liquid: 'Liquid', + drag_block_progress: 'Progress', + liquid_max: 'End Value', + liquid_outline_border: 'Border Width', + liquid_outline_distance: 'Border Distance', + liquid_wave_length: 'Wave Length', + liquid_wave_count: 'Wave Count', + liquid_shape: 'Shape', + liquid_shape_circle: 'Circle', + liquid_shape_diamond: 'Diamond', + liquid_shape_triangle: 'Triangle', + liquid_shape_pin: 'Pin', + liquid_shape_rect: 'Rect' }, dataset: { sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default', @@ -1034,10 +1109,13 @@ export default { password: 'Password', host: 'Host name / IP address', port: 'Port', + datasource_url: 'URL address', + please_input_datasource_url: 'Please enter Elasticsearch 地址,e.g: http://es_host:es_port', please_input_data_base: 'Please enter the database name', please_input_user_name: 'Please enter user name', please_input_password: 'Please enter Password', please_input_host: 'Please enter host', + please_input_url: 'Please enter url adress', please_input_port: 'Please enter port', modify: 'Edit data Source', validate_success: 'Verification successful', @@ -1129,6 +1207,7 @@ export default { store: 'Store', save_to_panel: 'Save to template', export_to_panel: 'Export to template', + export_to_pdf: 'Export to PDF', preview: 'Preview', fullscreen_preview: 'Fullscreen Preview', new_tab_preview: 'New Tab Preview', @@ -1350,6 +1429,7 @@ export default { read_time: 'Read Time', type: 'Message Type', mark_readed: 'Mark As Read', + all_mark_readed: 'Mark All As Read', please_select: 'Please select at least one message', mark_success: 'Mark read successfully', receive_manage: 'Receive Manage', @@ -1359,6 +1439,7 @@ export default { i18n_msg_type_dataset_sync_success: 'Dataset synchronization successful', i18n_msg_type_dataset_sync_faild: 'Dataset synchronization failed', i18n_msg_type_all: 'All type', + i18n_msg_type_ds_invalid: 'Datasource invalid', channel_inner_msg: 'On site news' }, denumberrange: { diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 1981b08af8..f41f8df150 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -45,7 +45,7 @@ export default { dashboard: '首頁', documentation: '文檔', guide: '引導頁', - permission: '全縣測試頁', + permission: '權限測試頁', rolePermission: '角色權限', pagePermission: '頁面權限', directivePermission: '指令權限', @@ -91,7 +91,7 @@ export default { errorPages: '錯誤頁面', page401: '401', page404: '404', - errorLog: '錯誤日誌', + errorLog: '錯誤日志', excel: 'Excel', exportExcel: '導出 Excel', selectExcel: '導出 已選擇項', @@ -109,34 +109,36 @@ export default { navbar: { dashboard: '首頁', github: '項目地址', - logOut: '退出登陸', + logOut: '退出登錄', profile: '個人中心', theme: '換膚', - size: '佈局大小' + size: '布局大小' }, login: { - title: '系統登陸', + title: '系統登錄', welcome: '歡迎使用', - logIn: '登陸', - username: '帳號', + logIn: '登錄', + username: '賬號', password: '密碼', - any: '任意字符', - thirdparty: '第三方登陸', + any: '隨便填', + thirdparty: '第三方登錄', thirdpartyTips: '本地不能模擬,請結合自己業務進行模擬!!!', - expires: '登陸信息過期,請重新登陸', - tokenError: '信息錯誤,請重新登陸', + expires: '登錄信息過期,請重新登錄', + tokenError: '登陸信息錯誤,請重新登錄', username_error: '請輸入正確的 ID', - password_error: '密碼不小於 8 位', - re_login: '重新登陸' + password_error: '密碼不小于 8 位', + re_login: '重新登錄' }, commons: { + search: '搜索', + folder: '目錄', no_target_permission: '沒有權限', success: '成功', switch_lang: '切換語言成功', close: '關閉', icon: '圖標', all: '全部', - enable: '啟用', + enable: '啓用', disable: '禁用', yes: '是', no: '否', @@ -153,30 +155,30 @@ export default { not_cover: '不覆蓋', import_mode: '導入模式', import_module: '導入模塊', - please_fill_in_the_template: '請填寫模板內容', - cut_back_old_version: '切匯舊版', - cut_back_new_version: '切匯新版', + please_fill_in_the_template: '請填寫模版內容', + cut_back_old_version: '切回舊版', + cut_back_new_version: '切回新版', comment: '評論', examples: '示例', help_documentation: '幫助文檔', api_help_documentation: 'API文檔', delete_cancelled: '已取消刪除', - workspace: '工作空開你', + workspace: '工作空間', organization: '組織', menu: '菜單', setting: '設置', project: '項目', - about_us: '關於', + about_us: '關于', current_project: '當前項目', name: '名稱', description: '描述', - annotation: '註釋', + annotation: '注釋', clear: '清空', save: '保存', update: '更新', save_success: '保存成功', delete_success: '刪除成功', - copy_success: '複製成功', + copy_success: '複制成功', modify_success: '修改成功', delete_cancel: '已取消刪除', confirm: '確定', @@ -184,8 +186,8 @@ export default { prompt: '提示', operating: '操作', input_limit: '長度在 {0} 到 {1} 個字符', - login: '登陸', - welcome: '一站式開源數據分析平臺', + login: '登錄', + welcome: '一站式開源數據分析平台', username: '姓名', password: '密碼', input_username: '請輸入用戶姓名', @@ -213,11 +215,11 @@ export default { input_content: '請輸入內容', create: '新建', edit: '編輯', - copy: '複製', + copy: '複制', refresh: '刷新', - remark: '備註', + remark: '備注', delete: '刪除', - reduction: '恢復', + reduction: '恢複', not_filled: '未填寫', please_select: '請選擇', search_by_name: '根據名稱搜索', @@ -225,7 +227,7 @@ export default { exit_system: '退出系統', verification: '驗證', title: '標題', - custom: '自動義', + custom: '自定義', select_date: '選擇日期', months_1: '一月', months_2: '二月', @@ -250,13 +252,13 @@ export default { connection_successful: '連接成功', connection_failed: '連接失敗', save_failed: '保存失敗', - host_cannot_be_empty: '主機不能為空', - port_cannot_be_empty: '端口號不能為空', - account_cannot_be_empty: '帳戶不能為空', + host_cannot_be_empty: '主機不能爲空', + port_cannot_be_empty: '端口號不能爲空', + account_cannot_be_empty: '帳戶不能爲空', remove: '移除', remove_cancel: '移除取消', remove_success: '移除成功', - tips: '認證信息已過期,請重新登陸', + tips: '認證信息已過期,請重新登錄', not_performed_yet: '尚未執行', incorrect_input: '輸入內容不正確', delete_confirm: '請輸入以下內容,確認刪除:', @@ -264,13 +266,13 @@ export default { input_login_username: '請輸入用戶 ID 或 郵箱', input_name: '請輸入名稱', please_upload: '請上傳文件', - please_fill_path: '請填寫url 路徑', + please_fill_path: '請填寫ur路徑', formatErr: '格式錯誤', please_save: '請先保存', reference_documentation: '參考文檔', id: 'ID', millisecond: '毫秒', - cannot_be_null: '不能為空', + cannot_be_null: '不能爲空', required: '{0}是必填的', already_exists: '名稱不能重複', modifier: '修改人', @@ -288,7 +290,7 @@ export default { start_date_time: '開始日期時間', end_date_time: '結束日期時間', range_separator: '至', - data_time_error: '開始日期不能大與結束日期' + data_time_error: '開始日期不能大于結束日期' }, adv_search: { title: '高級搜索', @@ -304,14 +306,14 @@ export default { is_not_empty: '非空', like: '包含', not_like: '不包含', - in: '屬與', - not_in: '不屬與', - gt: '大與', - ge: '大與等與', - lt: '小與', - le: '小與等與', - equals: '等與', - not_equals: '不等與', + in: '屬于', + not_in: '不屬于', + gt: '大于', + ge: '大于等于', + lt: '小于', + le: '小于等于', + equals: '等于', + not_equals: '不等于', between: '之間', current_user: '是當前用戶' }, @@ -355,23 +357,23 @@ export default { cancel: '取消' }, guide: { - description: '引導頁對與一些第一次進入項目的人很有用,你可以簡單介紹下項目的功能。本 Demo 是基與', + description: '引導頁對于一些第一次進入項目的人很有用,你可以簡單介紹下項目的功能。本 Demo 是基于', button: '打開引導' }, components: { documentation: '文檔', - tinymceTips: '富文本是管理後臺一個核心的功能,但同時又是一個有很多坑的地方。在選擇富文本的過程中我也走了不少的彎路,市面上常見的富文本都基本用過了,最終權衡了一下選擇了Tinymce。更詳細的富文本比較和介紹見', - dropzoneTips: '由與我司業務有特殊需求,而且要傳七牛 所以沒用第三方,選擇了自己封裝。代碼非常的簡單,具體代碼你可以在這裏看到 @/components/Dropzone', + tinymceTips: '富文本是管理後台一個核心的功能,但同時又是一個有很多坑的地方。在選擇富文本的過程中我也走了不少的彎路,市面上常見的富文本都基本用過了,最終權衡了一下選擇了Tinymce。更詳細的富文本比較和介紹見', + dropzoneTips: '由于我司業務有特殊需求,而且要傳七牛 所以沒用第三方,選擇了自己封裝。代碼非常的簡單,具體代碼你可以在這裏看到 @/components/Dropzone', stickyTips: '當頁面滾動到預設的位置會吸附在頂部', backToTopTips1: '頁面滾動到指定位置會在右下角出現返回頂部按鈕', backToTopTips2: '可自定義按鈕的樣式、show/hide、出現的高度、返回的位置 如需文字提示,可在外部使用Element的el-tooltip元素', - imageUploadTips: '由與我在使用時它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的話,優先還是使用官方版本。' + imageUploadTips: '由于我在使用時它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的話,優先還是使用官方版本。' }, table: { - dynamicTips1: '固定標頭,按照表頭順序排序', - dynamicTips2: '不固定標頭, 按照點擊順序排序', - dragTips1: '默認排序', - dragTips2: '拖拽後排序', + dynamicTips1: '固定表頭, 按照表頭順序排序', + dynamicTips2: '不固定表頭, 按照點擊順序排序', + dragTips1: '默認順序', + dragTips2: '拖拽後順序', title: '標題', importance: '重要性', type: '類型', @@ -390,15 +392,15 @@ export default { publish: '發布', draft: '草稿', delete: '刪除', - cancel: '取消', - confirm: '確定' + cancel: '取 消', + confirm: '確 定' }, example: { - warning: '創建和編輯頁面是不能被 keep-alive 緩存的,因為keep-alive 的 include 目前不支持根據路由來緩存,所以目前都是基與 component name 來進行緩存的。如果你想類似的實現緩存效果,可以使用 localStorage 等瀏覽器緩存方案。或者不要使用 keep-alive 的 include,直接緩存所有頁面。詳情見' + warning: '創建和編輯頁面是不能被 keep-alive 緩存的,因爲keep-alive 的 include 目前不支持根據路由來緩存,所以目前都是基于 component name 來進行緩存的。如果你想類似的實現緩存效果,可以使用 localStorage 等浏覽器緩存方案。或者不要使用 keep-alive 的 include,直接緩存所有頁面。詳情見' }, errorLog: { tips: '請點擊右上角bug小圖標', - description: '現在的管理後臺基本都是spa的形式了,它增強了用戶體驗,但同時也會增加頁面出問題的可能性,可能一個小小的疏忽就導致整個頁面的死鎖。好在 Vue 官網提供了一個方法來捕獲處理異常,你可以在其中進行錯誤處理或者異常上報。', + description: '現在的管理後台基本都是spa的形式了,它增強了用戶體驗,但同時也會增加頁面出問題的可能性,可能一個小小的疏忽就導致整個頁面的死鎖。好在 Vue 官網提供了一個方法來捕獲處理異常,你可以在其中進行錯誤處理或者異常上報。', documentation: '文檔介紹' }, excel: { @@ -411,34 +413,39 @@ export default { placeholder: '請輸入文件名(默認file)' }, pdf: { - tips: '這裏使用 window.print() 來實現下載pdf的功能' + tips: '這裏使用 window.print() 來實現下載pdf的功能' }, theme: { change: '換膚', documentation: '換膚文檔', - tips: 'Tips: 它區別於 navbar 上的 theme-pick, 是兩種不同的換膚方法,各自有不同的應用場景,具體請參考文檔。' + tips: 'Tips: 它區別于 navbar 上的 theme-pick, 是兩種不同的換膚方法,各自有不同的應用場景,具體請參考文檔。' }, tagsView: { refresh: '刷新', close: '關閉', - closeOthers: '關閉其他', + closeOthers: '關閉其它', closeAll: '關閉所有' }, settings: { - title: '系統佈局配置', + title: '系統布局配置', theme: '主題色', - tagsView: '開啟 Tags-View', + tagsView: '開啓 Tags-View', fixedHeader: '固定 Header', sidebarLogo: '側邊欄 Logo' }, + sysParams: { + display: '顯示設置', + ldap: 'LDAP設置', + oidc: 'OIDC設置' + }, license: { - i18n_no_license_record: '沒有 License 紀錄', - i18n_license_is_empty: 'License 為空', + i18n_no_license_record: '沒有 License 記錄', + i18n_license_is_empty: 'License 爲空', title: '授權管理', corporation: '客戶名稱', time: '授權時間', - product: '產品名稱', - edition: '產品版本', + product: '産品名稱', + edition: '産品版本', licenseVersion: '授權版本', count: '授權數量', valid_license: '授權驗證', @@ -469,7 +476,7 @@ export default { repeat_password: '確認密碼', inconsistent_passwords: '兩次輸入的密碼不一致', remove_member: '確定要移除該成員嗎', - org_remove_member: '確定要移除該成員嗎?', + org_remove_member: '將該用戶從組織中移除,將同時移除該組織下所有工作空間的權限,確定要移除該成員嗎?', input_id_or_email: '請輸入用戶 ID, 或者 用戶郵箱', no_such_user: '無此用戶信息, 請輸入正確的用戶 ID 或者 用戶郵箱!' }, @@ -482,6 +489,7 @@ export default { input_password: '請輸入密碼', input_phone: '請輸入電話號碼', input_roles: '請選擇角色', + select_users: '請選擇用戶', special_characters_are_not_supported: '不支持特殊字符', mobile_number_format_is_incorrect: '手機號碼格式不正確', email_format_is_incorrect: '郵箱格式不正確', @@ -496,7 +504,49 @@ export default { new_passwd: '新密碼', confirm_passwd: '確認密碼', change_password: '修改密碼', - search_by_name: '按姓名搜索' + search_by_name: '按姓名搜索', + import_ldap: '導入LDAP用戶' + }, + ldap: { + url: 'LDAP地址', + dn: '綁定DN', + password: '密碼', + ou: '用戶OU', + filter: '用戶過濾器', + mapping: 'LDAP屬性映射', + open: '啓用LDAP認證', + input_url: '請輸入LDAP地址', + input_dn: '請輸入DN', + input_password: '請輸入密碼', + input_ou: '請輸入用戶OU', + input_filter: '請輸入用戶過濾器', + input_mapping: '請輸入LDAP屬性映射', + input_username: '請輸入用戶名', + input_url_placeholder: '請輸入LDAP地址 (如 ldap://localhost:389)', + input_ou_placeholder: '輸入用戶OU (使用|分隔各OU)', + input_filter_placeholder: '輸入過濾器 [可能的選項是cn或uid或sAMAccountName={0}, 如:(uid={0})]', + input_mapping_placeholder: '如:{"username":"uid","name":"sn","email":"mail"}, username映射的選項可能是cn或uid或sAMAccountName', + test_connect: '測試連接', + test_login: '測試登錄', + edit: '編輯', + login_success: '登錄成功', + url_cannot_be_empty: 'LDAP 地址不能爲空', + dn_cannot_be_empty: 'LDAP DN不能爲空', + ou_cannot_be_empty: 'LDAP OU不能爲空', + filter_cannot_be_empty: 'LDAP 用戶過濾器不能爲空', + mapping_cannot_be_empty: 'LDAP 用戶屬性映射不能爲空', + password_cannot_be_empty: 'LDAP 密碼不能爲空' + }, + oidc: { + auth_endpoint: '請輸入AuthEndpoint', + token_endpoint: '請輸入TokenEndpoint', + userinfo_endpoint: '請輸入UserinfoEndpoint', + logout_endpoint: '請輸入logoutEndpoint', + clientId: '請輸入ClientId', + secret: '請輸入Secret', + scope: '請輸入scope', + redirectUrl: '請輸入redirectUrl', + open: '啓用OIDC認證' }, role: { menu_authorization: '菜單授權', @@ -528,7 +578,7 @@ export default { create: '創建菜單', modify: '修改菜單', delete: '刪除菜單', - delete_confirm: '確定刪除菜單嗎?', + delete_confirm: '確定刪除菜單嗎', menu_type: '菜單類型' }, organization: { @@ -551,19 +601,19 @@ export default { }, system_parameter_setting: { mailbox_service_settings: '郵件設置', - test_connection: '測試鏈接', + test_connection: '測試連接', SMTP_host: 'SMTP主機', SMTP_port: 'SMTP端口', - SMTP_account: 'SMTP帳號', + SMTP_account: 'SMTP賬戶', SMTP_password: 'SMTP密碼', - SSL: '開啟SSL(如果SMTP端口是465,通常需要啟用SSL)', - TLS: '開啟TLS(如果SMTP端口是587,通常需要啟用TLS)', + SSL: '開啓SSL(如果SMTP端口是465,通常需要啓用SSL)', + TLS: '開啓TLS(如果SMTP端口是587,通常需要啓用TLS)', SMTP: '是否免密 SMTP', - host: '主機不能為空', - port: '端口號不能為空', - account: '帳戶不能為空', + host: '主機號不能爲空', + port: '端口號不能爲空', + account: '賬戶不能爲空', test_recipients: '測試收件人', - tip: ' 提示: 僅用來作為測試郵件收件人' + tip: '提示:僅用來作爲測試郵件收件人' }, chart: { save_snapshot: '保存縮略圖', @@ -589,14 +639,14 @@ export default { sql_data: 'SQL數據集', excel_data: 'Excel數據集', custom_data: '自定義數據集', - pls_slc_tbl_left: '請從左側選擇視圖', - add_db_table: '添加數據庫表', + pls_slc_tbl_left: '請從左側選視圖', + add_db_table: '添加數據庫數據集', pls_slc_data_source: '請選擇數據源', table: '表', edit: '編輯', - create_view: '創建視圖', + create_view: '創建試圖', data_preview: '數據預覽', - dimension: '緯度', + dimension: '維度', quota: '指標', title: '標題', show: '顯示', @@ -608,22 +658,22 @@ export default { y_axis: '縱軸', chart: '視圖', close: '關閉', - summary: '匯總方式', + summary: '彙總方式', fast_calc: '快速計算', sum: '求和', - count: '記數', + count: '計數', avg: '平均', max: '最大值', min: '最小值', - stddev_pop: '標準差', + stddev_pop: '標准差', var_pop: '方差', quick_calc: '快速計算', show_name_set: '顯示名設置', - color: '顏色', + color: '顔色', color_case: '配色方案', - pls_slc_color_case: '請選餓配色方案', + pls_slc_color_case: '請選擇配色方案', color_default: '默認', - color_retro: '復古', + color_retro: '複古', color_future: '未來', color_gradual: '漸變', color_business: '商務', @@ -640,7 +690,7 @@ export default { line_type: '線型', line_symbol: '折點', line_symbol_size: '折點大小', - line_type_solid: '實現', + line_type_solid: '實線', line_type_dashed: '虛線', line_symbol_circle: '圓形', line_symbol_emptyCircle: '空心圓', @@ -652,13 +702,13 @@ export default { line_symbol_arrow: '箭頭', line_symbol_none: '無', line_area: '面積', - pie_inner_radius: '內經', - pie_outer_radius: '外經', + pie_inner_radius: '內徑', + pie_outer_radius: '外徑', funnel_width: '寬度', line_smooth: '平滑折線', - title_style: '標題格式', + title_style: '標題樣式', text_fontsize: '字體大小', - text_color: '字體顏色', + text_color: '字體顔色', text_h_position: '水平位置', text_v_position: '垂直位置', text_pos_left: '左', @@ -674,23 +724,23 @@ export default { legend: '圖例', shape: '形狀', polygon: '多邊形', - circle: '圖形', - label: '標籤', - label_position: '標籤位置', + circle: '圓形', + label: '標簽', + label_position: '標簽位置', content_formatter: '內容格式', inside: '內', tooltip: '提示', tooltip_item: '數據項', - tooltip_axis: '座標軸', - formatter_plc: '內痛格式為空時,顯示默認格式', - xAxis: '橫洲', + tooltip_axis: '坐標軸', + formatter_plc: '內容格式爲空時,顯示默認格式', + xAxis: '橫軸', yAxis: '縱軸', position: '位置', rotate: '角度', name: '名稱', - icon: '國際', + icon: '圖標', trigger_position: '觸發位置', - asc: '昇序', + asc: '升序', desc: '降序', sort: '排序', filter: '過濾', @@ -701,39 +751,39 @@ export default { border_radius: '邊框半徑', alpha: '透明度', add_filter: '添加過濾', - no_limit: '無顯示', - filter_eq: '等於', - filter_not_eq: '不等於', - filter_lt: '小於', - filter_le: '小於等於', - filter_gt: '大於', - filter_ge: '大於等於', - filter_null: '為空', - filter_not_null: '不為空', + no_limit: '無限制', + filter_eq: '等于', + filter_not_eq: '不等于', + filter_lt: '小于', + filter_le: '小于等于', + filter_gt: '大于', + filter_ge: '大于等于', + filter_null: '爲空', + filter_not_null: '不爲空', filter_include: '包含', filter_not_include: '不包含', rose_type: '玫瑰圖模式', radius_mode: '半徑', area_mode: '面積', - rose_radius: '園角', + rose_radius: '圓角', view_name: '視圖標題', belong_group: '所屬分組', select_group: '選擇分組', - name_can_not_empty: '名稱不能為空', - template_can_not_empty: '請選擇儀表板', + name_can_not_empty: '名稱不能爲空', + template_can_not_empty: '請選擇儀表版', custom_count: '記錄數', table_title_fontsize: '表頭字體大小', table_item_fontsize: '表格字體大小', table_header_bg: '表頭背景', table_item_bg: '表格背景', - table_item_font_color: '字體顏色', + table_item_font_color: '字體顔色', stripe: '斑馬紋', start_angle: '起始角度', end_angle: '結束角度', style_priority: '樣式優先級', dashboard: '儀表板', - dimension_color: '名稱顏色', - quota_color: '值顏色', + dimension_color: '名稱顔色', + quota_color: '值顔色', dimension_font_size: '名稱字體大小', quota_font_size: '值字體大小', space_split: '名稱/值間隔', @@ -741,11 +791,12 @@ export default { only_one_result: '僅顯示第1個計算結果', dimension_show: '名稱顯示', quota_show: '值顯示', - title_limit: '標題不能大於50個字符', + title_limit: '標題不能大于50個字符', filter_condition: '過濾條件', filter_field_can_null: '過濾字段必填', preview_100_data: '預覽前100條記錄', - chart_table_normal: '明細表', + chart_table_normal: '彙總表', + chart_table_info: '明細表', chart_card: '指標卡', chart_bar: '基礎柱狀圖', chart_bar_stack: '堆疊柱狀圖', @@ -772,24 +823,24 @@ export default { chartName: '新建視圖', chart_show_error: '無法正常顯示', chart_error_tips: '如有疑問請聯系管理員', - title_cannot_empty: '標題不能為空', + title_cannot_empty: '標題不能爲空', table_title_height: '表頭行高', table_item_height: '表格行高', axis_show: '軸線顯示', - axis_color: '軸線顏色', + axis_color: '軸線顔色', axis_width: '軸線寬度', axis_type: '軸線類型', axis_type_solid: '實線', axis_type_dashed: '虛線', axis_type_dotted: '點', axis_label_show: '標簽顯示', - axis_label_color: '標簽顏色', + axis_label_color: '標簽顔色', axis_label_fontsize: '標簽大小', text_style: '字體樣式', bolder: '加粗', change_ds: '更換數據集', - change_ds_tip: '提示:更換數據集將導致字段發生變化,需重新製作視圖', - axis_name_color: '名稱顏色', + change_ds_tip: '提示:更換數據集將導致字段發生變化,需重新制作視圖', + axis_name_color: '名稱顔色', axis_name_fontsize: '名稱字體', pie_label_line_show: '引導線', outside: '外', @@ -799,10 +850,10 @@ export default { axis_label: '軸標簽', label_fontsize: '標簽大小', split_line: '分割線', - split_color: '分割顏色', + split_color: '分割顔色', shadow: '陰影', condition: '過濾值', - filter_value_can_null: '過濾值不能為空', + filter_value_can_null: '過濾值不能爲空', filter_like: '包含', filter_not_like: '不包含', color_light: '明亮', @@ -837,7 +888,7 @@ export default { chart_scatter: '散點圖', bubble_size: '氣泡大小', chart_treemap: '矩形樹圖', - drill: '鉆取', + drill: '鑽取', drag_block_treemap_label: '色塊標簽', drag_block_treemap_size: '色塊大小', bubble_symbol: '圖形', @@ -847,10 +898,36 @@ export default { system_case: '系統方案', custom_case: '自定義', last_layer: '當前已經是最後一級', - radar_size: '大小' + radar_size: '大小', + chart_mix: '組合圖', + axis_value: '軸值', + axis_value_min: '最小值', + axis_value_max: '最大值', + axis_value_split: '間隔', + axis_auto: '自動', + table_info_switch: '明細表切換將清空維度', + drag_block_value_axis_main: '主軸值', + drag_block_value_axis_ext: '副軸值', + yAxis_main: '主縱軸', + yAxis_ext: '副縱軸', + total: '共', + items: '條數據', + chart_liquid: '水波圖', + drag_block_progress: '進度指示', + liquid_max: '目標值', + liquid_outline_border: '邊框粗細', + liquid_outline_distance: '邊框間隔', + liquid_wave_length: '水波長度', + liquid_wave_count: '水波數量', + liquid_shape: '形狀', + liquid_shape_circle: '圓形', + liquid_shape_diamond: '菱形', + liquid_shape_triangle: '三角形', + liquid_shape_pin: '氣球', + liquid_shape_rect: '矩形' }, dataset: { - sheet_warn: '有多個sheet頁面,默認抽取第一個', + sheet_warn: '有多個 Sheet 頁,默認抽取第一個', datalist: '數據集', name: '數據集名稱', add_group: '添加分組', @@ -891,7 +968,7 @@ export default { time: '時間', value: '數值', mode: '模式', - direct_connect: '直鏈', + direct_connect: '直連', sync_data: '定時同步', update_setting: '更新設置', sync_now: '立即更新', @@ -910,10 +987,10 @@ export default { add_scope: '增量更新', select_data_time: '選擇日期時間', execute_rate: '執行頻率', - simple_cron: '簡單重複', execute_once: '立即執行', - cron_config: '表達時設定', - no_limit: '無限製', + simple_cron: '簡單重複', + cron_config: '表達式設定', + no_limit: '無限制', set_end_time: '設定結束時間', operate: '操作', save_success: '保存成功', @@ -923,7 +1000,7 @@ export default { add_sql_table: '添加 SQL 數據集', preview: '預覽', pls_input_name: '請輸入名稱', - connect_mode: '鏈接模式', + connect_mode: '連接模式', incremental_update_type: '增量更新方式', incremental_add: '增量添加', incremental_delete: '增量刪除', @@ -932,7 +1009,7 @@ export default { param: '參數', edit_sql: '編輯 SQL 數據集', showRow: '顯示行', - add_excel_table: ' 添加 Excel 數據集', + add_excel_table: '添加Excel數據集', add_custom_table: '添加自定義數據集', upload_file: '上傳文件', detail: '詳情', @@ -954,14 +1031,14 @@ export default { source_field: '關聯字段', target_table: '被關聯表', target_field: '被關聯字段', - union_relation: '關聯關係', - pls_setting_union_success: '請正確設置關聯關係', - invalid_dataset: ' Kettle 未運行,無效數據集', - check_all: '銓選', + union_relation: '關聯關系', + pls_setting_union_success: '請正確設置關聯關系', + invalid_dataset: 'Kettle未運行,無效數據集', + check_all: '全選', can_not_union_self: '被關聯表不能與關聯表相同', float: '小數', - edit_custom_table: '編輯自助數據集', - edit_field: '編輯自斷', + edit_custom_table: '編輯自定義數據集', + edit_field: '編輯字段', preview_100_data: '顯示前100行數據', invalid_table_check: '非直連數據集請先完成數據同步', parse_error: 'Excel解析失敗,請檢查格式、字段等信息。具體參考:https://dataease.io/docs/faq/dataset_faq/', @@ -979,7 +1056,7 @@ export default { sync_latter: '稍後同步', task: { list: '任務列表', - record: '執行紀錄', + record: '執行記錄', create: '新建任務', name: '任務名稱', last_exec_time: '上次執行時間', @@ -1015,10 +1092,10 @@ export default { calc_field: '計算字段', show_sql: '顯示SQL', ple_select_excel: '請選擇要導入的 Excel', - merge: '合併', - no_merge: '不合併', - merge_msg: '數據表中存在自斷一直的情況,是否合併到一個數據集中?', - merge_title: '合併數據', + merge: '合並', + no_merge: '不合並', + merge_msg: '數據表中存在字段一致的情況,是否合並到一個數據集中?', + merge_title: '合並數據', field_name_less_50: '字段名不能超過50個字符' }, datasource: { @@ -1033,16 +1110,20 @@ export default { password: '密碼', host: '主機名/IP地址', port: '端口', + datasource_url: '地址', + please_input_datasource_url: '請輸入 Elasticsearch 地址,如: http://es_host:es_port', please_input_data_base: '請輸入數據庫名稱', + please_select_oracle_type: '選擇連接類型', please_input_user_name: '請輸入用戶名', please_input_password: '請輸入密碼', please_input_host: '請輸入主機', - please_input_port: '請輸入', + please_input_url: '請輸入URL地址', + please_input_port: '請輸入端口', modify: '編輯數據源', validate_success: '校驗成功', validate: '校驗', search_by_name: '根據名稱搜索', - delete_warning: '確認刪除?', + delete_warning: '確定要刪除嗎?', input_name: '請輸入名稱', input_limit_2_25: '2-25字符', input_limit_0_50: '0-50字符', @@ -1052,20 +1133,21 @@ export default { get_schema: '獲取 Schema', schema: '數據庫 Schema', please_choose_schema: '請選擇數據庫 Schema', + edit_datasource_msg: '修改數據源信息,可能會導致改數據源下的數據集不可用,確認修改?', in_valid: '無效數據源', - initial_pool_size: '初始連結數', - min_pool_size: '最小連結數', - max_pool_size: '最大連結數', - max_idle_time: '最大空閒(秒)', + initial_pool_size: '初始連接數', + min_pool_size: '最小連接數', + max_pool_size: '最大連接數', + max_idle_time: '最大空閑(秒)', acquire_increment: '增長數', connect_timeout: '連接超時(秒)', - please_input_initial_pool_size: '請輸入初始連結數', - please_input_min_pool_size: '請輸入最小連結數', - please_input_max_pool_size: '請輸入最大連結數', - please_input_max_idle_time: '請輸入最大空閒(秒)', + please_input_initial_pool_size: '請輸入初始連接數', + please_input_min_pool_size: '請輸入最小連接數', + please_input_max_pool_size: '請輸入最大連接數', + please_input_max_idle_time: '請輸入最大空閑(秒)', please_input_acquire_increment: '請輸入增長數', please_input_connect_timeout: '請輸入連接超時(秒)', - no_less_then_0: '高級設置中的參數不能小於零', + no_less_then_0: '高級設置中的參數不能小于零', priority: '高級設置' }, pblink: { @@ -1080,14 +1162,14 @@ export default { auth_role: '已分享角色', picture_limit: '只能插入圖片', drag_here: '請將左側字段拖至此處', - copy_link_passwd: '複製鏈接及密碼', - copy_link: '複製鏈接', - copy_short_link: '複製短鏈接', - copy_short_link_passwd: '複製短鏈接及密碼', + copy_link_passwd: '複制鏈接及密碼', + copy_link: '複制鏈接', + copy_short_link: '複制短鏈接', + copy_short_link_passwd: '複制短鏈接及密碼', passwd_protect: '密碼保護', link: '鏈接', link_share: '鏈接分享', - link_share_desc: '開啟鏈接後,任何人可通過此鏈接訪問儀表板。', + link_share_desc: '開啓鏈接後,任何人可通過此鏈接訪問儀表板。', share: '分享', datalist: '視圖列表', group: '目錄', @@ -1109,7 +1191,7 @@ export default { view: '視圖', module: '組件', filter_module: '過濾組件', - select_by_module: '安組件選擇', + select_by_module: '按組件選擇', edit: '編輯', sys_template: '系統模板', user_template: '用戶模板', @@ -1123,11 +1205,12 @@ export default { photo: '圖片', default_panel: '默認儀表板', create_public_links: '創建公共鏈接', - to_default: '另存為默認', - to_default_panel: '另存為默認儀表板', + to_default: '另存爲默認', + to_default_panel: '另存爲默認儀表板', store: '收藏', - save_to_panel: '保存為模板', - export_to_panel: '導出為模板', + save_to_panel: '保存爲模板', + export_to_panel: '導出爲模板', + export_to_pdf: '導出爲PDF', preview: '預覽', fullscreen_preview: '全屏預覽', new_tab_preview: '新Tab頁預覽', @@ -1138,21 +1221,21 @@ export default { all_org: '所有組織', custom: '自定義', import_template: '導入模板', - copy_template: '復用模板', + copy_template: '複用模板', upload_template: '上傳模板', belong_to_category: '所屬類別', pls_select_belong_to_category: '請選擇所屬類別', - template_name_cannot_be_empty: '模板名稱不能為空', - select_by_table: '列表選擇', + template_name_cannot_be_empty: '模板名稱不能爲空', + select_by_table: '按表選擇', data_list: '數據列表', component_list: '組件列表', - custom_scope: '自定義控製範圍', + custom_scope: '自定義控制範圍', multiple_choice: '多選', single_choice: '單選', field: '字段', unshared_people: '未分享人員', shared_people: '已分享人員', - error_data: '獲取數據出錯,請聯繫管理員', + error_data: '獲取數據出錯,請聯系管理員', canvas_size: '畫布大小', canvas_scale: '畫布比例', style: '樣式', @@ -1161,7 +1244,7 @@ export default { redo: '重做', undo: '撤銷', panelNull: '這是個空的儀表板,可以通過編輯來豐富內容', - copy: '復製', + copy: '複制', paste: '粘貼', cut: '剪切', lock: '鎖定', @@ -1179,11 +1262,11 @@ export default { top: 'y 坐標', height: '高', width: '寬', - color: '顏色', + color: '顔色', backgroundColor: '背景色', borderStyle: '邊框風格', borderWidth: '邊框寬度', - borderColor: '邊框顏色', + borderColor: '邊框顔色', borderRadius: '邊框半徑', fontSize: '字體大小', fontWeight: '字體粗細', @@ -1236,12 +1319,21 @@ export default { uninstall_cancel: '取消卸載插件' }, display: { - logo: '頭部系統 Logo', - loginLogo: '登陸頁面頭部 Logo', - loginImage: '登陸頁面右側圖片', - loginTitle: '登陸頁面標題', + logo: '頭部系統logo', + loginLogo: '登錄頁面頭部logo', + loginImage: '登錄頁面右側圖片', + loginTitle: '登錄頁面標題', title: '系統名稱', - advice_size: '建議圖片大小' + advice_size: '建議圖片大小', + theme: '主題顔色', + + topMenuColor: '頭部背景', + topMenuActiveColor: '頭部選中背景', + + topMenuTextColor: '頭部字體顔色', + + topMenuTextActiveColor: '頭部字體選中顔色' + }, auth: { authConfig: '權限配置', @@ -1261,6 +1353,7 @@ export default { datasetAuthHead: '所有數據集', chartAuthHead: '所有視圖', panelAuthHead: '所有儀表板', + menuAuthHead: '所有菜單和操作', view: '查看', use: '使用', export: '導出', @@ -1275,13 +1368,13 @@ export default { auth_num: '授權數量', version: '版本', version_num: '版本號', - standard: '標準版', + standard: '標准版', enterprise: '企業版', suport: '獲取技術支持', update_success: '更新成功' }, template: { - exit_same_template_check: '當前存在相同名稱模板,是否覆蓋?', + exit_same_template_check: '當前分類存在相同名稱模板,是否覆蓋?', override: '覆蓋', cancel: '取消', confirm_upload: '上傳確認' @@ -1297,8 +1390,8 @@ export default { month: '月', week: '周', year: '年', - d_w_cant_not_set: '日期與星期不可以同時為“不指定”', - d_w_must_one_set: '日期與星期必須有一個為“不指定”', + d_w_cant_not_set: '日期與星期不可以同時爲“不指定”', + d_w_must_one_set: '日期與星期必須有一個爲“不指定”', every_day: '每日', cycle: '周期', not_set: '不指定', @@ -1326,15 +1419,15 @@ export default { week_end: '至星期', every_year: '每年', week_tips: '說明:1-7 分別對應 周日-周六', - minute_limit: '分鐘不能小於1,大於59', - hour_limit: '小時不能小於1,大於523', - day_limit: '天不能小於1,大於531' + minute_limit: '分鍾不能小于1,大于59', + hour_limit: '小時不能小于1,大于23', + day_limit: '天不能小于1,大于31' }, dept: { can_not_move_change_sort: '不能移動以改變排序', can_not_move_parent_to_children: '父組織不能移動到自己的子節點下', move_success: '移動成功', - name_exist_pre: '下已存在名稱為【', + name_exist_pre: '下已存在名稱爲【', name_exist_suf: '】的組織', root_org: '頂層組織' }, @@ -1349,6 +1442,7 @@ export default { read_time: '查看時間', type: '消息類型', mark_readed: '標記已讀', + all_mark_readed: '全部已讀', please_select: '請至少選擇一條消息', mark_success: '標記已讀成功', receive_manage: '接收管理', @@ -1357,6 +1451,7 @@ export default { i18n_msg_type_dataset_sync: '數據集同步', i18n_msg_type_dataset_sync_success: '數據集同步成功', i18n_msg_type_dataset_sync_faild: '數據集同步失敗', + i18n_msg_type_ds_invalid: '數據源失效', i18n_msg_type_all: '全部類型', channel_inner_msg: '站內消息' }, diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index b8a3385134..d952758531 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -130,6 +130,8 @@ export default { re_login: '重新登录' }, commons: { + search: '搜索', + folder: '目录', no_target_permission: '没有权限', success: '成功', switch_lang: '切换语言成功', @@ -431,6 +433,11 @@ export default { fixedHeader: '固定 Header', sidebarLogo: '侧边栏 Logo' }, + sysParams: { + display: '显示设置', + ldap: 'LDAP设置', + oidc: 'OIDC设置' + }, license: { i18n_no_license_record: '没有 License 记录', i18n_license_is_empty: 'License 为空', @@ -482,6 +489,7 @@ export default { input_password: '请输入密码', input_phone: '请输入电话号码', input_roles: '请选择角色', + select_users: '请选择用户', special_characters_are_not_supported: '不支持特殊字符', mobile_number_format_is_incorrect: '手机号码格式不正确', email_format_is_incorrect: '邮箱格式不正确', @@ -496,7 +504,49 @@ export default { new_passwd: '新密码', confirm_passwd: '确认密码', change_password: '修改密码', - search_by_name: '按姓名搜索' + search_by_name: '按姓名搜索', + import_ldap: '导入LDAP用户' + }, + ldap: { + url: 'LDAP地址', + dn: '绑定DN', + password: '密码', + ou: '用户OU', + filter: '用户过滤器', + mapping: 'LDAP属性映射', + open: '启用LDAP认证', + input_url: '请输入LDAP地址', + input_dn: '请输入DN', + input_password: '请输入密码', + input_ou: '请输入用户OU', + input_filter: '请输入用户过滤器', + input_mapping: '请输入LDAP属性映射', + input_username: '请输入用户名', + input_url_placeholder: '请输入LDAP地址 (如 ldap://localhost:389)', + input_ou_placeholder: '输入用户OU (使用|分隔各OU)', + input_filter_placeholder: '输入过滤器 [可能的选项是cn或uid或sAMAccountName={0}, 如:(uid={0})]', + input_mapping_placeholder: '如:{"username":"uid","name":"sn","email":"mail"}, username映射的选项可能是cn或uid或sAMAccountName', + test_connect: '测试连接', + test_login: '测试登录', + edit: '编辑', + login_success: '登录成功', + url_cannot_be_empty: 'LDAP 地址不能为空', + dn_cannot_be_empty: 'LDAP DN不能为空', + ou_cannot_be_empty: 'LDAP OU不能为空', + filter_cannot_be_empty: 'LDAP 用户过滤器不能为空', + mapping_cannot_be_empty: 'LDAP 用户属性映射不能为空', + password_cannot_be_empty: 'LDAP 密码不能为空' + }, + oidc: { + auth_endpoint: '请输入AuthEndpoint', + token_endpoint: '请输入TokenEndpoint', + userinfo_endpoint: '请输入UserinfoEndpoint', + logout_endpoint: '请输入logoutEndpoint', + clientId: '请输入ClientId', + secret: '请输入Secret', + scope: '请输入scope', + redirectUrl: '请输入redirectUrl', + open: '启用OIDC认证' }, role: { menu_authorization: '菜单授权', @@ -745,7 +795,8 @@ export default { filter_condition: '过滤条件', filter_field_can_null: '过滤字段必填', preview_100_data: '预览前100条记录', - chart_table_normal: '明细表', + chart_table_normal: '汇总表', + chart_table_info: '明细表', chart_card: '指标卡', chart_bar: '基础柱状图', chart_bar_stack: '堆叠柱状图', @@ -847,7 +898,33 @@ export default { system_case: '系统方案', custom_case: '自定义', last_layer: '当前已经是最后一级', - radar_size: '大小' + radar_size: '大小', + chart_mix: '组合图', + axis_value: '轴值', + axis_value_min: '最小值', + axis_value_max: '最大值', + axis_value_split: '间隔', + axis_auto: '自动', + table_info_switch: '明细表切换将清空维度', + drag_block_value_axis_main: '主轴值', + drag_block_value_axis_ext: '副轴值', + yAxis_main: '主纵轴', + yAxis_ext: '副纵轴', + total: '共', + items: '条数据', + chart_liquid: '水波图', + drag_block_progress: '进度指示', + liquid_max: '目标值', + liquid_outline_border: '边框粗细', + liquid_outline_distance: '边框间隔', + liquid_wave_length: '水波长度', + liquid_wave_count: '水波数量', + liquid_shape: '形状', + liquid_shape_circle: '圆形', + liquid_shape_diamond: '菱形', + liquid_shape_triangle: '三角形', + liquid_shape_pin: '气球', + liquid_shape_rect: '矩形' }, dataset: { sheet_warn: '有多个 Sheet 页,默认抽取第一个', @@ -1028,16 +1105,20 @@ export default { create: '新建数据源', type: '类型', please_choose_type: '请选择数据源类型', + please_choose_data_type: '请选择计算模式', data_base: '数据库名称', user_name: '用户名', password: '密码', host: '主机名/IP地址', port: '端口', + datasource_url: '地址', + please_input_datasource_url: '请输入 Elasticsearch 地址,如: http://es_host:es_port', please_input_data_base: '请输入数据库名称', please_select_oracle_type: '选择连接类型', please_input_user_name: '请输入用户名', please_input_password: '请输入密码', please_input_host: '请输入主机', + please_input_url: '请输入URL地址', please_input_port: '请输入端口', modify: '编辑数据源', validate_success: '校验成功', @@ -1068,7 +1149,11 @@ export default { please_input_acquire_increment: '请输入增长数', please_input_connect_timeout: '请输入连接超时(秒)', no_less_then_0: '高级设置中的参数不能小于零', - priority: '高级设置' + priority: '高级设置', + data_mode: '数据模式', + direct: '直连模式', + extract: '抽取模式', + all_compute_mode: '直连、抽取模式' }, pblink: { key_pwd: '请输入密码打开链接', @@ -1130,6 +1215,7 @@ export default { store: '收藏', save_to_panel: '保存为模板', export_to_panel: '导出为模板', + export_to_pdf: '导出为PDF', preview: '预览', fullscreen_preview: '全屏预览', new_tab_preview: '新Tab页预览', @@ -1243,7 +1329,16 @@ export default { loginImage: '登录页面右侧图片', loginTitle: '登录页面标题', title: '系统名称', - advice_size: '建议图片大小' + advice_size: '建议图片大小', + theme: '主题颜色', + + topMenuColor: '头部背景', + topMenuActiveColor: '头部选中背景', + + topMenuTextColor: '头部字体颜色', + + topMenuTextActiveColor: '头部字体选中颜色' + }, auth: { authConfig: '权限配置', @@ -1352,6 +1447,7 @@ export default { read_time: '查看时间', type: '消息类型', mark_readed: '标记已读', + all_mark_readed: '全部已读', please_select: '请至少选择一条消息', mark_success: '标记已读成功', receive_manage: '接收管理', @@ -1360,6 +1456,7 @@ export default { i18n_msg_type_dataset_sync: '数据集同步', i18n_msg_type_dataset_sync_success: '数据集同步成功', i18n_msg_type_dataset_sync_faild: '数据集同步失败', + i18n_msg_type_ds_invalid: '数据源失效', i18n_msg_type_all: '全部类型', channel_inner_msg: '站内消息' }, diff --git a/frontend/src/layout/components/AppMain.vue b/frontend/src/layout/components/AppMain.vue index eaf39b016c..2e72540801 100644 --- a/frontend/src/layout/components/AppMain.vue +++ b/frontend/src/layout/components/AppMain.vue @@ -20,7 +20,6 @@ export default { diff --git a/frontend/src/layout/components/Sidebar/Logo.vue b/frontend/src/layout/components/Sidebar/Logo.vue index 10a077f73f..d48754cfee 100644 --- a/frontend/src/layout/components/Sidebar/Logo.vue +++ b/frontend/src/layout/components/Sidebar/Logo.vue @@ -53,8 +53,7 @@ export default { width: 100%; height: 50px; line-height: 50px; -// background: #2b2f3a; - background-color: $menuBg; + background-color: $topBarBg; text-align: center; overflow: hidden; diff --git a/frontend/src/layout/components/Sidebar/index.vue b/frontend/src/layout/components/Sidebar/index.vue index e2cd53868a..1c8de2b267 100644 --- a/frontend/src/layout/components/Sidebar/index.vue +++ b/frontend/src/layout/components/Sidebar/index.vue @@ -1,13 +1,10 @@ @@ -195,6 +282,13 @@ export default { { name: this.$t('chart.line_symbol_pin'), value: 'pin' }, { name: this.$t('chart.line_symbol_arrow'), value: 'arrow' } ], + liquidShapeOptions: [ + { name: this.$t('chart.liquid_shape_circle'), value: 'circle' }, + { name: this.$t('chart.liquid_shape_diamond'), value: 'diamond' }, + { name: this.$t('chart.liquid_shape_triangle'), value: 'triangle' }, + { name: this.$t('chart.liquid_shape_pin'), value: 'pin' }, + { name: this.$t('chart.liquid_shape_rect'), value: 'rect' } + ], fontSize: [] } }, @@ -224,6 +318,14 @@ export default { this.sizeForm.treemapWidth = this.sizeForm.treemapWidth ? this.sizeForm.treemapWidth : 80 this.sizeForm.treemapHeight = this.sizeForm.treemapHeight ? this.sizeForm.treemapHeight : 80 this.sizeForm.radarSize = this.sizeForm.radarSize ? this.sizeForm.radarSize : 80 + + this.sizeForm.liquidShape = this.sizeForm.liquidShape ? this.sizeForm.liquidShape : DEFAULT_SIZE.liquidShape + this.sizeForm.liquidMax = this.sizeForm.liquidMax ? this.sizeForm.liquidMax : DEFAULT_SIZE.liquidMax + this.sizeForm.liquidSize = this.sizeForm.liquidSize ? this.sizeForm.liquidSize : DEFAULT_SIZE.liquidSize + this.sizeForm.liquidOutlineBorder = this.sizeForm.liquidOutlineBorder ? this.sizeForm.liquidOutlineBorder : DEFAULT_SIZE.liquidOutlineBorder + this.sizeForm.liquidOutlineDistance = (this.sizeForm.liquidOutlineDistance || this.sizeForm.liquidOutlineDistance === 0) ? this.sizeForm.liquidOutlineDistance : DEFAULT_SIZE.liquidOutlineDistance + this.sizeForm.liquidWaveLength = this.sizeForm.liquidWaveLength ? this.sizeForm.liquidWaveLength : DEFAULT_SIZE.liquidWaveLength + this.sizeForm.liquidWaveCount = this.sizeForm.liquidWaveCount ? this.sizeForm.liquidWaveCount : DEFAULT_SIZE.liquidWaveCount } } }, @@ -268,4 +370,13 @@ export default { .el-form-item{ margin-bottom: 6px; } +.el-divider--horizontal { + margin: 10px 0 +} +.divider-style>>>.el-divider__text{ + color: #606266; + font-size: 12px; + font-weight: 400; + padding: 0 10px; +} diff --git a/frontend/src/views/chart/components/table/TableNormal.vue b/frontend/src/views/chart/components/table/TableNormal.vue index e0ff19f7fb..4297eaa7fa 100644 --- a/frontend/src/views/chart/components/table/TableNormal.vue +++ b/frontend/src/views/chart/components/table/TableNormal.vue @@ -1,33 +1,55 @@ @@ -91,7 +113,12 @@ export default { height: '36px' }, title_show: true, - borderRadius: '0px' + borderRadius: '0px', + currentPage: { + page: 1, + pageSize: 10, + show: 0 + } } }, computed: { @@ -137,9 +164,17 @@ export default { if (this.chart.data) { this.fields = JSON.parse(JSON.stringify(this.chart.data.fields)) datas = JSON.parse(JSON.stringify(this.chart.data.tableRow)) + if (this.chart.type === 'table-info') { + // 计算分页 + this.currentPage.show = datas.length + const pageStart = (this.currentPage.page - 1) * this.currentPage.pageSize + const pageEnd = pageStart + this.currentPage.pageSize + datas = datas.slice(pageStart, pageEnd) + } } else { this.fields = [] datas = [] + this.resetPage() } this.$refs.plxTable.reloadData(datas) this.$nextTick(() => { @@ -152,11 +187,19 @@ export default { calcHeightRightNow() { this.$nextTick(() => { if (this.$refs.tableContainer) { + let pageHeight = 0 + if (this.chart.type === 'table-info') { + pageHeight = 36 + } const currentHeight = this.$refs.tableContainer.offsetHeight - const tableMaxHeight = currentHeight - this.$refs.title.offsetHeight - 16 + const tableMaxHeight = currentHeight - this.$refs.title.offsetHeight - 16 - pageHeight let tableHeight if (this.chart.data) { - tableHeight = (this.chart.data.tableRow.length + 2) * 36 + if (this.chart.type === 'table-info') { + tableHeight = (this.currentPage.pageSize + 2) * 36 - pageHeight + } else { + tableHeight = (this.chart.data.tableRow.length + 2) * 36 - pageHeight + } } else { tableHeight = 0 } @@ -279,6 +322,24 @@ export default { resetHeight() { this.height = 100 + }, + + pageChange(val) { + this.currentPage.pageSize = val + this.init() + }, + + pageClick(val) { + this.currentPage.page = val + this.init() + }, + + resetPage() { + this.currentPage = { + page: 1, + pageSize: 10, + show: 0 + } } } } @@ -292,4 +353,25 @@ export default { max-height: none!important; line-height: normal!important; } + .table-page{ + position: absolute; + bottom: 0; + display: flex; + align-items: center; + justify-content: flex-end; + width: 100%; + overflow: hidden; + } + .page-style{ + margin-right: auto; + } + .total-style{ + flex: 1; + font-size: 12px; + color: #606266; + white-space:nowrap; + } + .page-style >>> .el-input__inner{ + height: 24px; + } diff --git a/frontend/src/views/chart/group/Group.vue b/frontend/src/views/chart/group/Group.vue index 8cf053eaf8..e4aead51a2 100644 --- a/frontend/src/views/chart/group/Group.vue +++ b/frontend/src/views/chart/group/Group.vue @@ -327,6 +327,7 @@ import { DEFAULT_TOOLTIP, DEFAULT_XAXIS_STYLE, DEFAULT_YAXIS_STYLE, + DEFAULT_YAXIS_EXT_STYLE, DEFAULT_BACKGROUND_COLOR, DEFAULT_SPLIT } from '../chart/chart' @@ -739,11 +740,13 @@ export default { legend: DEFAULT_LEGEND_STYLE, xAxis: DEFAULT_XAXIS_STYLE, yAxis: DEFAULT_YAXIS_STYLE, + yAxisExt: DEFAULT_YAXIS_EXT_STYLE, background: DEFAULT_BACKGROUND_COLOR, split: DEFAULT_SPLIT }) view.xaxis = JSON.stringify([]) view.yaxis = JSON.stringify([]) + view.yaxisExt = JSON.stringify([]) view.extStack = JSON.stringify([]) view.customFilter = JSON.stringify([]) view.drillFields = JSON.stringify([]) diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index fd511aecd1..37773650d7 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -77,7 +77,7 @@ @add="moveToQuota" > - + @@ -113,12 +113,11 @@ {{ $t('chart.chart_type') }}
-
@@ -126,6 +125,11 @@ + + + + + @@ -141,13 +145,13 @@ +
+
-
-
@@ -168,23 +172,35 @@ +
+
+ + + + + -
-
+ + + + + +
+
@@ -200,18 +216,20 @@ -
-
- - -
+ + + + + + +
@@ -247,10 +265,10 @@ />
- + {{ $t('chart.drag_block_table_data_column') }} - {{ $t('chart.drag_block_type_axis') }} + {{ $t('chart.drag_block_type_axis') }} {{ $t('chart.drag_block_pie_label') }} {{ $t('chart.drag_block_funnel_split') }} {{ $t('chart.drag_block_radar_label') }} @@ -277,7 +295,7 @@ {{ $t('chart.placeholder_field') }} - + {{ $t('chart.drag_block_table_data_column') }} {{ $t('chart.drag_block_value_axis') }} @@ -288,6 +306,8 @@ {{ $t('chart.drag_block_label_value') }} {{ $t('chart.chart_data') }} {{ $t('chart.drag_block_treemap_size') }} + {{ $t('chart.drag_block_value_axis_main') }} + {{ $t('chart.drag_block_progress') }} / {{ $t('chart.quota') }} @@ -302,13 +322,37 @@ @update="save(true)" > - +
{{ $t('chart.placeholder_field') }}
+ + + {{ $t('chart.drag_block_value_axis_ext') }} + / + {{ $t('chart.quota') }} + + + + + + +
+ {{ $t('chart.placeholder_field') }} +
+
{{ $t('chart.stack_item') }} @@ -386,7 +430,7 @@ {{ $t('chart.placeholder_field') }} - + {{ $t('chart.drill') }} / @@ -439,47 +483,36 @@ - + - - - - - - {{ $t('chart.module_style') }} - + - + + + + - + - + - - - - - - - - @@ -489,8 +522,9 @@
- - + + +
@@ -626,7 +660,8 @@ import { DEFAULT_TOOLTIP, DEFAULT_XAXIS_STYLE, DEFAULT_YAXIS_STYLE, - DEFAULT_SPLIT + DEFAULT_SPLIT, + DEFAULT_YAXIS_EXT_STYLE } from '../chart/chart' import ColorSelector from '../components/shape-attr/ColorSelector' import SizeSelector from '../components/shape-attr/SizeSelector' @@ -646,9 +681,15 @@ import LabelNormal from '../components/normal/LabelNormal' import TableSelector from './TableSelector' import FieldEdit from '../../dataset/data/FieldEdit' import { areaMapping } from '@/api/map/map' +import QuotaExtItem from '@/views/chart/components/drag-item/QuotaExtItem' +import YAxisExtSelector from '@/views/chart/components/component-style/YAxisExtSelector' +import ChartComponentG2 from '@/views/chart/components/ChartComponentG2' export default { name: 'ChartEdit', components: { + ChartComponentG2, + YAxisExtSelector, + QuotaExtItem, FilterItem, FieldEdit, SplitSelector, @@ -693,6 +734,7 @@ export default { view: { xaxis: [], yaxis: [], + yaxisExt: [], extStack: [], drillFields: [], extBubble: [], @@ -710,6 +752,7 @@ export default { legend: DEFAULT_LEGEND_STYLE, xAxis: DEFAULT_XAXIS_STYLE, yAxis: DEFAULT_YAXIS_STYLE, + yAxisExt: DEFAULT_YAXIS_EXT_STYLE, background: DEFAULT_BACKGROUND_COLOR, split: DEFAULT_SPLIT }, @@ -826,7 +869,15 @@ export default { this.resetDatasetField() } }, - save(getData, trigger, needRefreshGroup = false) { + save(getData, trigger, needRefreshGroup = false, switchType = false) { + if (switchType && (this.view.type === 'table-info' || this.chart.type === 'table-info') && this.view.xaxis.length > 0) { + this.$message({ + showClose: true, + message: this.$t('chart.table_info_switch'), + type: 'warning' + }) + this.view.xaxis = [] + } const view = JSON.parse(JSON.stringify(this.view)) view.id = this.view.id view.sceneId = this.view.sceneId @@ -860,6 +911,9 @@ export default { view.yaxis = [view.yaxis[0]] } view.yaxis.forEach(function(ele) { + if (!ele.chartType) { + ele.chartType = 'bar' + } if (!ele.summary || ele.summary === '') { if (ele.id === 'count' || ele.deType === 0 || ele.deType === 1) { ele.summary = 'count' @@ -874,7 +928,33 @@ export default { ele.filter = [] } }) + if (view.type === 'chart-mix') { + view.yaxisExt.forEach(function(ele) { + if (!ele.chartType) { + ele.chartType = 'bar' + } + if (!ele.summary || ele.summary === '') { + if (ele.id === 'count' || ele.deType === 0 || ele.deType === 1) { + ele.summary = 'count' + } else { + ele.summary = 'sum' + } + } + if (!ele.sort || ele.sort === '') { + ele.sort = 'none' + } + if (!ele.filter) { + ele.filter = [] + } + }) + } view.extStack.forEach(function(ele) { + if (!ele.dateStyle || ele.dateStyle === '') { + ele.dateStyle = 'y_M_d' + } + if (!ele.datePattern || ele.datePattern === '') { + ele.datePattern = 'date_sub' + } if (!ele.sort || ele.sort === '') { ele.sort = 'none' } @@ -920,6 +1000,7 @@ export default { }) view.xaxis = JSON.stringify(view.xaxis) view.yaxis = JSON.stringify(view.yaxis) + view.yaxisExt = JSON.stringify(view.yaxisExt) view.customAttr = JSON.stringify(view.customAttr) view.customStyle = JSON.stringify(view.customStyle) view.customFilter = JSON.stringify(view.customFilter) @@ -966,6 +1047,7 @@ export default { this.view = JSON.parse(JSON.stringify(response.data)) this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : [] this.view.yaxis = this.view.yaxis ? JSON.parse(this.view.yaxis) : [] + this.view.yaxisExt = this.view.yaxisExt ? JSON.parse(this.view.yaxisExt) : [] this.view.extStack = this.view.extStack ? JSON.parse(this.view.extStack) : [] this.view.drillFields = this.view.drillFields ? JSON.parse(this.view.drillFields) : [] this.view.extBubble = this.view.extBubble ? JSON.parse(this.view.extBubble) : [] @@ -982,6 +1064,8 @@ export default { } if (!response.data.drill) { this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1) + + this.resetDrill() } this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters ? response.data.drillFilters : [])) }).catch(err => { @@ -1005,6 +1089,7 @@ export default { this.view = JSON.parse(JSON.stringify(response.data)) this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : [] this.view.yaxis = this.view.yaxis ? JSON.parse(this.view.yaxis) : [] + this.view.yaxisExt = this.view.yaxisExt ? JSON.parse(this.view.yaxisExt) : [] this.view.extStack = this.view.extStack ? JSON.parse(this.view.extStack) : [] this.view.drillFields = this.view.drillFields ? JSON.parse(this.view.drillFields) : [] this.view.extBubble = this.view.extBubble ? JSON.parse(this.view.extBubble) : [] @@ -1054,7 +1139,11 @@ export default { }, quotaItemRemove(item) { - this.view.yaxis.splice(item.index, 1) + if (item.removeType === 'quota') { + this.view.yaxis.splice(item.index, 1) + } else if (item.removeType === 'quotaExt') { + this.view.yaxisExt.splice(item.index, 1) + } this.save(true) }, @@ -1099,6 +1188,11 @@ export default { this.save() }, + onChangeYAxisExtForm(val) { + this.view.customStyle.yAxisExt = val + this.save() + }, + onChangeBackgroundForm(val) { this.view.customStyle.background = val this.save() @@ -1152,7 +1246,11 @@ export default { return } } - this.view.yaxis[this.quotaItem.index].filter = this.quotaItem.filter + if (this.quotaItem.filterType === 'quota') { + this.view.yaxis[this.quotaItem.index].filter = this.quotaItem.filter + } else if (this.quotaItem.filterType === 'quotaExt') { + this.view.yaxisExt[this.quotaItem.index].filter = this.quotaItem.filter + } this.save(true) this.closeQuotaFilter() }, @@ -1197,6 +1295,8 @@ export default { this.view.yaxis[this.itemForm.index].name = this.itemForm.name } else if (this.itemForm.renameType === 'dimension') { this.view.xaxis[this.itemForm.index].name = this.itemForm.name + } else if (this.itemForm.renameType === 'quotaExt') { + this.view.yaxisExt[this.itemForm.index].name = this.itemForm.name } this.save(true) this.closeRename() @@ -1307,7 +1407,9 @@ export default { if (this.view.type === 'map' && this.view.xaxis.length > 1) { this.view.xaxis = [this.view.xaxis[0]] } - this.dragCheckType(this.view.xaxis, 'd') + if (this.view.type !== 'table-info') { + this.dragCheckType(this.view.xaxis, 'd') + } this.dragMoveDuplicate(this.view.xaxis, e) this.save(true) }, @@ -1319,6 +1421,14 @@ export default { this.dragMoveDuplicate(this.view.yaxis, e) this.save(true) }, + addYaxisExt(e) { + if (this.view.type === 'map' && this.view.yaxisExt.length > 1) { + this.view.yaxisExt = [this.view.yaxisExt[0]] + } + this.dragCheckType(this.view.yaxisExt, 'q') + this.dragMoveDuplicate(this.view.yaxisExt, e) + this.save(true) + }, moveToDimension(e) { this.dragCheckType(this.dimensionData, 'd') this.dragMoveDuplicate(this.dimensionData, e) @@ -1506,6 +1616,14 @@ export default { if (temp) return temp } } + }, + + renderComponent() { + if (this.chart.type === 'liquid') { + return 'g2' + } else { + return 'echarts' + } } } @@ -1644,7 +1762,7 @@ export default { } .chart-type>>>.el-radio__input{ - display: none; + display: none!important; } .el-radio{ @@ -1691,7 +1809,6 @@ export default { } .table-class{ height: calc(100% - 20px); - margin: 10px; } .dialog-css>>>.el-dialog__title { diff --git a/frontend/src/views/dataset/add/AddDB.vue b/frontend/src/views/dataset/add/AddDB.vue index 22dd735f3d..39bcafa005 100644 --- a/frontend/src/views/dataset/add/AddDB.vue +++ b/frontend/src/views/dataset/add/AddDB.vue @@ -29,7 +29,7 @@ - + @@ -86,7 +86,8 @@ export default { mode: '0', syncType: 'sync_now', tableData: [], - kettleRunning: false + kettleRunning: false, + selectedDatasource: {} } }, watch: { @@ -96,6 +97,11 @@ export default { this.tables = response.data this.tableData = JSON.parse(JSON.stringify(this.tables)) }) + for (let i = 0; i < this.options.length; i++) { + if (this.options[i].id === val) { + this.selectedDatasource = this.options[i] + } + } } }, searchTable(val) { diff --git a/frontend/src/views/dataset/add/AddSQL.vue b/frontend/src/views/dataset/add/AddSQL.vue index d6b19279a7..4174ce8a45 100644 --- a/frontend/src/views/dataset/add/AddSQL.vue +++ b/frontend/src/views/dataset/add/AddSQL.vue @@ -18,7 +18,7 @@ - + - + @@ -145,14 +145,15 @@ export default { theme: 'solarized', hintOptions: { // 自定义提示选项 completeSingle: false // 当匹配只有一项的时候是否自动补全 - } + }, }, data: [], fields: [], mode: '0', syncType: 'sync_now', height: 500, - kettleRunning: false + kettleRunning: false, + selectedDatasource: {} } }, computed: { @@ -189,6 +190,13 @@ export default { this.kettleRunning = res.data }) }, + changeDatasource() { + for (let i = 0; i < this.options.length; i++) { + if (this.options[i].id === this.form.dataSource) { + this.selectedDatasource = this.options[i] + } + } + }, calHeight() { const that = this setTimeout(function() { diff --git a/frontend/src/views/dataset/common/DatasetCustomField.vue b/frontend/src/views/dataset/common/DatasetCustomField.vue index 3ec843512f..1de987d639 100644 --- a/frontend/src/views/dataset/common/DatasetCustomField.vue +++ b/frontend/src/views/dataset/common/DatasetCustomField.vue @@ -57,7 +57,7 @@ export default { watch: { 'table': function() { fieldList(this.table.id).then(response => { - this.fields = response.data + this.fields = JSON.parse(JSON.stringify(response.data)).filter(ele => ele.extField === 0) this.checkedFields = [] this.checkedList.forEach(ele => { @@ -78,7 +78,7 @@ export default { initField() { if (this.table.id) { fieldList(this.table.id).then(response => { - this.fields = response.data + this.fields = JSON.parse(JSON.stringify(response.data)).filter(ele => ele.extField === 0) }) } }, diff --git a/frontend/src/views/dataset/data/UnionView.vue b/frontend/src/views/dataset/data/UnionView.vue index 466556fcf3..fcc08d37e2 100644 --- a/frontend/src/views/dataset/data/UnionView.vue +++ b/frontend/src/views/dataset/data/UnionView.vue @@ -222,7 +222,7 @@ export default { // if (response.data) { this.union.sourceTableId = this.table.id fieldList(this.table.id).then(response => { - this.sourceFieldOption = response.data + this.sourceFieldOption = JSON.parse(JSON.stringify(response.data)).filter(ele => ele.extField === 0) }) this.editUnion = true // } else { @@ -320,7 +320,7 @@ export default { this.union.targetTableId = param.id this.union.targetTableFieldId = '' fieldList(param.id).then(response => { - this.targetFieldOption = response.data + this.targetFieldOption = JSON.parse(JSON.stringify(response.data)).filter(ele => ele.extField === 0) }) this.$refs['targetTable'].doClose() } diff --git a/frontend/src/views/login/index.vue b/frontend/src/views/login/index.vue index 47e7186721..552452644a 100644 --- a/frontend/src/views/login/index.vue +++ b/frontend/src/views/login/index.vue @@ -15,6 +15,13 @@ {{ $t('login.welcome') + (uiInfo && uiInfo['ui.title'] && uiInfo['ui.title'].paramValue || ' DataEase') }}
+
+ + diff --git a/frontend/src/views/panel/export/PDFPreExport.vue b/frontend/src/views/panel/export/PDFPreExport.vue new file mode 100644 index 0000000000..af64d5e2bb --- /dev/null +++ b/frontend/src/views/panel/export/PDFPreExport.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/frontend/src/views/panel/export/date.js b/frontend/src/views/panel/export/date.js new file mode 100644 index 0000000000..713cc7a4fe --- /dev/null +++ b/frontend/src/views/panel/export/date.js @@ -0,0 +1,30 @@ +// 对Date的扩展,将 Date 转化为指定格式的String +// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, +// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) +// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 +// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 +Date.prototype.Format = function(fmt) { + var o = { + 'M+': this.getMonth() + 1, // 月份 + 'd+': this.getDate(), // 日 + 'h+': this.getHours(), // 小时 + 'm+': this.getMinutes(), // 分 + 's+': this.getSeconds(), // 秒 + 'q+': Math.floor((this.getMonth() + 3) / 3), // 季度 + 'S': this.getMilliseconds() // 毫秒 + } + if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)) } + for (var k in o) { + if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) } + } + return fmt +} + +export function formatTimeToStr(times, pattern) { + var d = new Date(times).Format('yyyy-MM-dd hh:mm:ss') + if (pattern) { + d = new Date(times).Format(pattern) + } + return d.toLocaleString() +} + diff --git a/frontend/src/views/panel/filter/index.vue b/frontend/src/views/panel/filter/index.vue index 1f602f894b..83e1389500 100644 --- a/frontend/src/views/panel/filter/index.vue +++ b/frontend/src/views/panel/filter/index.vue @@ -1,6 +1,6 @@