Merge pull request #597 from dataease/dev

Dev
This commit is contained in:
fit2cloudrd 2021-08-12 10:24:20 +08:00 committed by GitHub
commit 573b17c86b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
114 changed files with 2976 additions and 1508 deletions

View File

@ -1,6 +1,7 @@
package io.dataease.auth.api.dto;
import io.dataease.auth.entity.SysUserEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -11,7 +12,9 @@ import java.util.List;
@NoArgsConstructor
public class CurrentUserDto extends SysUserEntity implements Serializable {
@ApiModelProperty("角色集合")
private List<CurrentRoleDto> roles;
@ApiModelProperty("权限集合")
private List<String> permissions;
}

View File

@ -2,18 +2,17 @@ package io.dataease.auth.config;
import io.dataease.auth.api.dto.CurrentRoleDto;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.entity.ASKToken;
import io.dataease.auth.entity.JWTToken;
import io.dataease.auth.entity.SysUserEntity;
import io.dataease.auth.entity.TokenInfo;
import io.dataease.auth.handler.ApiKeyHandler;
import io.dataease.auth.service.AuthUserService;
import io.dataease.auth.util.JWTUtils;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.listener.util.CacheUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
@ -37,7 +36,7 @@ public class F2CRealm extends AuthorizingRealm {
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JWTToken;
return token instanceof JWTToken || token instanceof ASKToken;
}
//验证资源权限
@ -56,12 +55,27 @@ public class F2CRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
if (auth instanceof ASKToken) {
Object accessKey = auth.getPrincipal();
Object signature = auth.getCredentials();
Long userId = ApiKeyHandler.getUser(accessKey.toString(), signature.toString());
SysUserEntity userEntity = userWithId(userId);
CurrentUserDto currentUserDto = queryCacheUserDto(userEntity);
return new SimpleAuthenticationInfo(currentUserDto, signature, "f2cReam");
}
try {
CacheUtils.get("lic_info", "lic");
}catch (Exception e) {
LogUtil.error(e);
throw new AuthenticationException("lic error");
}
TokenInfo tokenInfo = null;
String token = null;
try {
@ -78,13 +92,14 @@ public class F2CRealm extends AuthorizingRealm {
throw new AuthenticationException("token invalid");
}
// 使用缓存
SysUserEntity user = authUserService.getUserById(userId);
/*SysUserEntity user = authUserService.getUserById(userId);
if (user == null) {
throw new AuthenticationException("User didn't existed!");
}
if (user.getEnabled()==0) {
throw new AuthenticationException("User is valid!");
}
}*/
SysUserEntity user = userWithId(userId);
String pass = null;
try {
pass = user.getPassword();
@ -94,6 +109,29 @@ public class F2CRealm extends AuthorizingRealm {
if (! JWTUtils.verify(token, tokenInfo, pass)) {
throw new AuthenticationException("Username or password error");
}
/*// 使用缓存
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
// 使用缓存
List<String> permissions = authUserService.permissions(user.getUserId());
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
currentUserDto.setRoles(currentRoleDtos);
currentUserDto.setPermissions(permissions);*/
CurrentUserDto currentUserDto = queryCacheUserDto(user);
return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam");
}
public SysUserEntity userWithId(Long userId) {
SysUserEntity user = authUserService.getUserById(userId);
if (user == null) {
throw new AuthenticationException("User didn't existed!");
}
if (user.getEnabled()==0) {
throw new AuthenticationException("User is valid!");
}
return user;
}
public CurrentUserDto queryCacheUserDto(SysUserEntity user) {
// 使用缓存
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
// 使用缓存
@ -101,6 +139,6 @@ public class F2CRealm extends AuthorizingRealm {
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
currentUserDto.setRoles(currentRoleDtos);
currentUserDto.setPermissions(permissions);
return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam");
return currentUserDto;
}
}

View File

@ -51,6 +51,7 @@ public class ShiroConfig {
filterMap.put("jwt", new JWTFilter());
filterMap.put("logout", new F2CLogoutFilter());
filterMap.put("link", new F2CLinkFilter());
filterMap.put("doc", new F2CDocFilter());
factoryBean.setSecurityManager(securityManager);
factoryBean.setLoginUrl("/login");
factoryBean.setUnauthorizedUrl("/login");

View File

@ -0,0 +1,25 @@
package io.dataease.auth.entity;
import org.apache.shiro.authc.AuthenticationToken;
public class ASKToken implements AuthenticationToken {
private String accessKey;
private String signature;
public ASKToken(String accessKey, String signature) {
this.accessKey = accessKey;
this.signature = signature;
}
@Override
public Object getPrincipal() {
return accessKey;
}
@Override
public Object getCredentials() {
return signature;
}
}

View File

@ -1,6 +1,7 @@
package io.dataease.auth.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -8,23 +9,33 @@ import java.io.Serializable;
public class SysUserEntity implements Serializable {
@ApiModelProperty(hidden = true)
private Long userId;
@ApiModelProperty("账号")
private String username;
@ApiModelProperty("姓名")
private String nickName;
@ApiModelProperty("组织ID")
private Long deptId;
@ApiModelProperty(hidden = true)
private String password;
@ApiModelProperty("状态")
private Integer enabled;
@ApiModelProperty("邮箱")
private String email;
@ApiModelProperty("电话")
private String phone;
@ApiModelProperty(hidden = true)
private String language;
@ApiModelProperty(hidden = true)
private Boolean isAdmin;
}

View File

@ -0,0 +1,26 @@
package io.dataease.auth.filter;
import org.apache.shiro.web.filter.authc.AnonymousFilter;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class F2CDocFilter extends AnonymousFilter {
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
HttpServletRequest req = (HttpServletRequest) request;
String path = "/deApi";
try {
req.getRequestDispatcher(path).forward(req, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}

View File

@ -1,8 +1,10 @@
package io.dataease.auth.filter;
import io.dataease.auth.entity.ASKToken;
import io.dataease.auth.entity.JWTToken;
import io.dataease.auth.entity.SysUserEntity;
import io.dataease.auth.entity.TokenInfo;
import io.dataease.auth.handler.ApiKeyHandler;
import io.dataease.auth.service.AuthUserService;
import io.dataease.auth.util.JWTUtils;
import io.dataease.commons.utils.CommonBeanFactory;
@ -48,6 +50,18 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (ApiKeyHandler.isApiKeyCall(httpServletRequest)) {
// Long userId = ApiKeyHandler.getUser(httpServletRequest);
ASKToken askToken = ApiKeyHandler.buildToken(httpServletRequest);
// UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userId.toString(), ApiKeyHandler.random);
getSubject(request, response).login(askToken);
return true;
}
String authorization = httpServletRequest.getHeader("Authorization");
if (StringUtils.startsWith(authorization, "Basic")) {
return false;
@ -72,7 +86,10 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if (isLoginAttempt(request, response)) {
// 先判断是不是api调用
HttpServletRequest hRequest = (HttpServletRequest) request;
if (isLoginAttempt(request, response) || ApiKeyHandler.isApiKeyCall(hRequest)) {
try {
boolean loginSuccess = executeLogin(request, response);
return loginSuccess;

View File

@ -0,0 +1,88 @@
package io.dataease.auth.handler;
import io.dataease.auth.entity.ASKToken;
import io.dataease.commons.utils.CodingUtil;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.ukey.dto.request.XpackUkeyDto;
import io.dataease.plugins.xpack.ukey.service.UkeyXpackService;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
public class ApiKeyHandler {
public static final String API_ACCESS_KEY = "accessKey";
public static final String API_SIGNATURE = "signature";
public static String random = UUID.randomUUID().toString() + UUID.randomUUID().toString();
public static Long getUser(HttpServletRequest request) {
if (request == null) {
return null;
}
return getUser(request.getHeader(API_ACCESS_KEY), request.getHeader(API_SIGNATURE));
}
public static ASKToken buildToken(HttpServletRequest request) {
if (request == null) {
return null;
}
String accessKey = request.getHeader(API_ACCESS_KEY);
String signature = request.getHeader(API_SIGNATURE);
ASKToken askToken = new ASKToken(accessKey, signature);
return askToken;
}
public static Boolean isApiKeyCall(HttpServletRequest request) {
if (request == null) {
return false;
}
if (StringUtils.isBlank(request.getHeader(API_ACCESS_KEY)) || StringUtils.isBlank(request.getHeader(API_SIGNATURE))) {
return false;
}
return true;
}
public static XpackUkeyDto ukey(String accessKey) {
UkeyXpackService ukeyXpackService = SpringContextUtil.getBean(UkeyXpackService.class);
XpackUkeyDto userKey = ukeyXpackService.getUserKey(accessKey);
return userKey;
}
public static Long getUser(String accessKey, String signature) {
if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(signature)) {
return null;
}
XpackUkeyDto userKey = ukey(accessKey);
if (userKey == null) {
throw new RuntimeException("invalid accessKey");
}
String signatureDecrypt;
try {
signatureDecrypt = CodingUtil.aesDecrypt(signature, userKey.getSecretKey(), accessKey);
} catch (Throwable t) {
throw new RuntimeException("invalid signature");
}
String[] signatureArray = StringUtils.split(StringUtils.trimToNull(signatureDecrypt), "|");
if (signatureArray.length < 2) {
throw new RuntimeException("invalid signature");
}
if (!StringUtils.equals(accessKey, signatureArray[0])) {
throw new RuntimeException("invalid signature");
}
long signatureTime = 0l;
try {
signatureTime = Long.valueOf(signatureArray[signatureArray.length - 1]).longValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
if (Math.abs(System.currentTimeMillis() - signatureTime) > 1800000) {
//签名30分钟超时
throw new RuntimeException("expired signature");
}
return userKey.getUserId();
}
}

View File

@ -43,9 +43,11 @@ public class ExtAuthServiceImpl implements ExtAuthService {
@Override
public AuthURD resourceTarget(String resourceId) {
AuthURD authURD = new AuthURD();
SysAuthExample example = new SysAuthExample();
/*SysAuthExample example = new SysAuthExample();
example.createCriteria().andAuthSourceEqualTo(resourceId);
List<SysAuth> sysAuths = sysAuthMapper.selectByExample(example);
List<SysAuth> sysAuths = sysAuthMapper.selectByExample(example);*/
List<SysAuth> sysAuths = extAuthMapper.queryByResource(resourceId);
Map<String, List<SysAuth>> authMap = sysAuths.stream().collect(Collectors.groupingBy(SysAuth::getAuthTargetType));
if (!CollectionUtils.isEmpty(authMap.get("user"))) {
authURD.setUserIds(authMap.get("user").stream().map(item -> Long.parseLong(item.getAuthTarget())).collect(Collectors.toList()));

View File

@ -20,7 +20,8 @@ public class ShiroServiceImpl implements ShiroService {
// 配置过滤:不会被拦截的链接 -> 放行 start ----------------------------------------------------------
// 放行Swagger2页面需要放行这些
filterChainDefinitionMap.put("/doc.html",ANON);
filterChainDefinitionMap.put("/doc.html**","doc");
filterChainDefinitionMap.put("/deApi**",ANON);
filterChainDefinitionMap.put("/swagger-ui.html",ANON);
filterChainDefinitionMap.put("/swagger-ui/**",ANON);
filterChainDefinitionMap.put("/swagger/**",ANON);

View File

@ -1,12 +1,17 @@
package io.dataease.base.domain;
import java.io.Serializable;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class SysMsgChannel implements Serializable {
@ApiModelProperty("消息渠道ID")
private Long msgChannelId;
@ApiModelProperty("消息渠道名称")
private String channelName;
private static final long serialVersionUID = 1L;

View File

@ -1,18 +1,25 @@
package io.dataease.base.domain;
import java.io.Serializable;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class SysMsgSetting implements Serializable {
@ApiModelProperty(hidden = true)
private Long msgSettingId;
@ApiModelProperty("订阅用户ID")
private Long userId;
@ApiModelProperty("订阅类型ID")
private Long typeId;
@ApiModelProperty("订阅渠道ID")
private Long channelId;
@ApiModelProperty("订阅状态ID")
private Boolean enable;
private static final long serialVersionUID = 1L;

View File

@ -1,18 +1,26 @@
package io.dataease.base.domain;
import java.io.Serializable;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class SysMsgType implements Serializable {
@ApiModelProperty("消息类型ID")
private Long msgTypeId;
@ApiModelProperty("上级类型ID")
private Long pid;
@ApiModelProperty("消息类型名称")
private String typeName;
@ApiModelProperty(hidden = true)
private String router;
@ApiModelProperty(hidden = true)
private String callback;
private static final long serialVersionUID = 1L;

View File

@ -1,40 +1,58 @@
package io.dataease.base.domain;
import java.io.Serializable;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class SysUser implements Serializable {
@ApiModelProperty(value = "用户ID" , allowEmptyValue = false, position = 0)
private Long userId;
@ApiModelProperty(value = "组织ID" , allowEmptyValue = false, position = 7)
private Long deptId;
@ApiModelProperty(value = "账号" , required = true)
private String username;
@ApiModelProperty(value = "姓名" , required = true, position = 2)
private String nickName;
@ApiModelProperty(value = "性别" ,allowableValues = "男,女", allowEmptyValue = true, position = 5)
private String gender;
@ApiModelProperty(value = "电话" , allowEmptyValue = true, position = 1)
private String phone;
@ApiModelProperty(value = "邮箱" , required = true, position = 3)
private String email;
@ApiModelProperty(value = "密码" , required = true, position = 4)
private String password;
@ApiModelProperty(hidden = true)
private Boolean isAdmin;
@ApiModelProperty(value = "状态" , allowableValues = "1,0", required = true, position = 6)
private Long enabled;
@ApiModelProperty(hidden = true)
private String createBy;
@ApiModelProperty(hidden = true)
private String updateBy;
@ApiModelProperty(hidden = true)
private Long pwdResetTime;
@ApiModelProperty(hidden = true)
private Long createTime;
@ApiModelProperty(hidden = true)
private Long updateTime;
@ApiModelProperty(hidden = true)
private String language;
private static final long serialVersionUID = 1L;

View File

@ -1,6 +1,7 @@
package io.dataease.base.mapper.ext;
import io.dataease.base.domain.SysAuth;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -12,6 +13,6 @@ public interface ExtAuthMapper {
List<Long> queryUserIdWithDeptIds(@Param("deptIds") List<Long> deptIds);
List<SysAuth> queryByResource(@Param("resourceId") String resourceId);
// Set<Long> queryUserIdWithRD(@Param("roleIds") List<Long> roleIds, @Param("deptIds") List<Long> deptIds);
}

View File

@ -23,5 +23,12 @@
</select>
<select id="queryByResource" resultMap="io.dataease.base.mapper.SysAuthMapper.BaseResultMap" >
select a.*
from sys_auth a left join sys_auth_detail b on a.id = b.auth_id
where a.auth_source = #{resourceId} and b.privilege_value = 1
</select>
</mapper>

View File

@ -1,15 +1,19 @@
package io.dataease.base.mapper.ext;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.dto.LinkageInfoDTO;
import io.dataease.dto.PanelViewLinkageDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface ExtPanelViewLinkageMapper {
List<PanelViewLinkageDTO> getViewLinkageGather(@Param("panelId") String panelId,@Param("sourceViewId") String sourceViewId,@Param("targetViewIds") List<String> targetViewIds);
List<LinkageInfoDTO> getPanelAllLinkageInfo(@Param("panelId") String panelId);
List<DatasetTableField> queryTableField(@Param("table_id") String tableId);
void deleteViewLinkage(@Param("panelId") String panelId,@Param("sourceViewId") String sourceViewId);

View File

@ -24,6 +24,14 @@
</collection>
</resultMap>
<resultMap id="AllLinkageMap" type="io.dataease.dto.LinkageInfoDTO">
<result column="sourceInfo" jdbcType="VARCHAR" property="sourceInfo"/>
<collection property="targetInfoList" ofType="String">
<result column="targetInfo" jdbcType="VARCHAR"/>
</collection>
</resultMap>
<select id="getViewLinkageGather" resultMap="LinkageGatherMap">
SELECT
chart_view.`name` as 'targetViewName',
@ -78,4 +86,16 @@
(#{menu.menuId},#{menu.title},#{menu.pid},#{menu.subCount},#{menu.permission},#{menu.hidden},ifnull(#{menu.hidden},0))
</foreach>
</insert>
<select id="getPanelAllLinkageInfo" resultMap="AllLinkageMap">
SELECT
distinct
CONCAT( panel_view_linkage.source_view_id, '#', panel_view_linkage_field.source_field ) AS 'sourceInfo',
CONCAT( panel_view_linkage.target_view_id, '#', panel_view_linkage_field.target_field ) AS 'targetInfo'
FROM
panel_view_linkage
LEFT JOIN panel_view_linkage_field ON panel_view_linkage.id = panel_view_linkage_field.linkage_id
WHERE
panel_view_linkage.panel_id = #{panelId}
</select>
</mapper>

View File

@ -0,0 +1,32 @@
package io.dataease.commons.condition;
import io.dataease.commons.license.DefaultLicenseService;
import io.dataease.commons.license.F2CLicenseResponse;
import io.dataease.commons.utils.CommonBeanFactory;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LicStatusCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
// BeanDefinitionRegistry registry = conditionContext.getRegistry();
// DefaultLicenseService defaultLicenseService = conditionContext.getBeanFactory().getBean(DefaultLicenseService.class);
DefaultLicenseService defaultLicenseService = CommonBeanFactory.getBean(DefaultLicenseService.class);
/*if (null == defaultLicenseService) {
registry.registerBeanDefinition();
}*/
if (ObjectUtils.isNotEmpty(defaultLicenseService)) {
F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense();
return F2CLicenseResponse.Status.valid == f2CLicenseResponse.getStatus();
}
return false;
}
}

View File

@ -3,6 +3,7 @@ package io.dataease.commons.license;
import com.google.gson.Gson;
import io.dataease.base.domain.License;
import io.dataease.commons.exception.DEException;
import io.dataease.commons.utils.LogUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@ -31,6 +32,7 @@ public class DefaultLicenseService {
command.add(licenseKey);
try{
execCommand(result, command);
LogUtil.info("read lic content is : " + result.toString());
F2CLicenseResponse f2CLicenseResponse = new Gson().fromJson(result.toString(), F2CLicenseResponse.class);
if(f2CLicenseResponse.getStatus() != F2CLicenseResponse.Status.valid){
return f2CLicenseResponse;
@ -43,6 +45,7 @@ public class DefaultLicenseService {
}
return f2CLicenseResponse;
}catch (Exception e){
e.printStackTrace();
return F2CLicenseResponse.invalid(e.getMessage());
}
}

View File

@ -7,6 +7,7 @@ import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.UUID;
/**
* 加密解密工具
@ -153,6 +154,17 @@ public class CodingUtil {
}
}
/*public static String getSignature(String accessKey, String secretKey) throws Exception {
return aesEncrypt(accessKey + "|" + UUID.randomUUID().toString() + "|" + System.currentTimeMillis(), secretKey, accessKey);
}
public static void main(String[] args) throws Exception{
String accessKey = "gnPFmtAsdLhUEWPA";
String secretKey = "TfK5FGUle0KRfJJJ";
String signature = getSignature(accessKey, secretKey);
System.out.println(signature);
}*/
public static String secretKey() {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");

View File

@ -19,6 +19,8 @@ import org.xml.sax.helpers.XMLReaderFactory;
import java.io.InputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author y
@ -248,6 +250,13 @@ public class ExcelXlsxReader extends DefaultHandler {
String value = this.getDataValue(lastIndex.trim(), "");//根据索引值获取对应的单元格值
if (preRef == null) {
String regEx="[^0-9]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(ref);
if(curCol < Integer.valueOf(m.replaceAll("").trim()) -1 ){
cellList.add(curCol, "");
curCol++;
}
preRef = ref;
}
//补全单元格之间的空单元格
@ -256,12 +265,16 @@ public class ExcelXlsxReader extends DefaultHandler {
}else if (!ref.equals(preRef)) {
int len = countNullCell(ref, preRef);
for (int i = 0; i < len; i++) {
cellList.add(curCol, "");
curCol++;
if(curCol < this.fields.size()){
cellList.add(curCol, "");
curCol++;
}
}
}
cellList.add(curCol, value);
if(curCol < this.fields.size()){
cellList.add(curCol, value);
}
curCol++;
//如果里面某个单元格含有值则标识该行不为空行
if (value != null && !"".equals(value)) {
@ -414,6 +427,9 @@ public class ExcelXlsxReader extends DefaultHandler {
if(CollectionUtils.isEmpty(this.getFields())){
throw new RuntimeException(Translator.get("i18n_excel_header_empty"));
}
if(curCol >= this.fields.size()){
return thisStr;
}
if(curRow==2){
this.getFields().get(curCol).setFieldType(type);
}else {

View File

@ -1,13 +1,10 @@
package io.dataease.config;
import cn.hutool.core.collection.CollectionUtil;
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import io.dataease.commons.condition.LicStatusCondition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.context.annotation.*;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.*;
import springfox.documentation.oas.annotations.EnableOpenApi;
@ -15,6 +12,8 @@ import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@ -29,6 +28,7 @@ public class Knife4jConfiguration {
private String version;
@Autowired
public Knife4jConfiguration(OpenApiExtensionResolver openApiExtensionResolver) {
this.openApiExtensionResolver = openApiExtensionResolver;
@ -64,6 +64,12 @@ public class Knife4jConfiguration {
return defaultApi("系统管理", "io.dataease.controller.sys");
}
/*@Bean(value = "pluginsApi")
@Conditional(LicStatusCondition.class)
public Docket pluginsApi() {
return defaultApi("插件管理", "io.dataease.plugins.server");
}*/
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
@ -77,7 +83,9 @@ public class Knife4jConfiguration {
private Docket defaultApi(String groupName, String packageName) {
List<SecurityScheme> securitySchemes=new ArrayList<>();
securitySchemes.add(apiKey());
securitySchemes.add(accessKey());
securitySchemes.add(signature());
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(securityContext());
@ -100,8 +108,12 @@ public class Knife4jConfiguration {
.build();
}
private ApiKey apiKey() {
return new ApiKey("Authorization", "Authorization", "header");
private ApiKey accessKey() {
return new ApiKey("accessKey", "accessKey", "header");
}
private ApiKey signature() {
return new ApiKey("signature", "signature", "header");
}
@ -109,7 +121,12 @@ public class Knife4jConfiguration {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return CollectionUtil.newArrayList(new SecurityReference("Authorization", authorizationScopes));
List<SecurityReference> results = new ArrayList<>();
results.add(new SecurityReference("accessKey", authorizationScopes));
results.add(new SecurityReference("signature", authorizationScopes));
return results;
}
}

View File

@ -1,13 +1,21 @@
package io.dataease.controller;
import io.dataease.commons.license.DefaultLicenseService;
import io.dataease.commons.license.F2CLicenseResponse;
import io.dataease.exception.DataEaseException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
@Controller
@RequestMapping
public class IndexController {
@Resource
private DefaultLicenseService defaultLicenseService;
@GetMapping(value = "/")
public String index() {
return "index.html";
@ -28,5 +36,18 @@ public class IndexController {
return "test.html";
}
@GetMapping("/deApi")
public String deApi() {
F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense();
switch (f2CLicenseResponse.getStatus()) {
case valid:
return "doc.html";
default:
// DataEaseException.throwException("Invalid License.");
return "nolic.html";
}
// return "index.html";
}
}

View File

@ -9,6 +9,7 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
@ -39,5 +40,10 @@ public class PanelViewLinkageController {
}
@ApiOperation("获取当前仪表板所有联动信息")
@GetMapping("/getPanelAllLinkageInfo/{panelId}")
public Map<String, List<String>> getPanelAllLinkageInfo(@PathVariable String panelId){
return panelViewLinkageService.getPanelAllLinkageInfo(panelId);
}
}

View File

@ -0,0 +1,15 @@
package io.dataease.controller.request.chart;
import io.dataease.dto.chart.ChartDimensionDTO;
import lombok.Data;
import java.util.List;
/**
* @Author gin
* @Date 2021/8/10 12:25 下午
*/
@Data
public class ChartDrillRequest {
private List<ChartDimensionDTO> dimensionList;
}

View File

@ -13,4 +13,8 @@ import java.util.List;
@Setter
public class ChartExtRequest {
private List<ChartExtFilterRequest> filter;
//联动过滤条件
private List<ChartExtFilterRequest> linkageFilters;
private List<ChartDrillRequest> drill;
}

View File

@ -4,14 +4,14 @@ import io.dataease.base.domain.SysDept;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.ResultHolder;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.DeptCreateRequest;
/*import io.dataease.controller.sys.request.DeptCreateRequest;
import io.dataease.controller.sys.request.DeptDeleteRequest;
import io.dataease.controller.sys.request.DeptStatusRequest;
import io.dataease.controller.sys.request.DeptStatusRequest;*/
import io.dataease.controller.sys.response.DeptNodeResponse;
import io.dataease.controller.sys.response.DeptTreeNode;
import io.dataease.service.sys.DeptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/*import io.swagger.annotations.ApiOperation;*/
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -46,7 +46,6 @@ public class SysDeptController extends ResultHolder {
@PostMapping("/search")
public List<DeptNodeResponse> search(@RequestBody BaseGridRequest request){
List<SysDept> nodes = deptService.nodesTreeByCondition(request);
//List<SysDept> nodes = deptService.nodesByPid(pid);
List<DeptNodeResponse> nodeResponses = nodes.stream().map(node -> {
DeptNodeResponse deptNodeResponse = BeanUtils.copyBean(new DeptNodeResponse(), node);
deptNodeResponse.setHasChildren(node.getSubCount() > 0);
@ -57,14 +56,14 @@ public class SysDeptController extends ResultHolder {
return nodeResponses;
}
@ApiOperation("查询部门")
/*@ApiOperation("查询部门")
@PostMapping("/root")
public ResultHolder rootData(){
List<SysDept> root = deptService.nodesByPid(null);
return success(root);
}
}*/
@ApiOperation("新增部门")
/*@ApiOperation("新增部门")
@PostMapping("/create")
public void create(@RequestBody DeptCreateRequest dept){
deptService.add(dept);
@ -84,7 +83,7 @@ public class SysDeptController extends ResultHolder {
@PostMapping("/updateStatus")
public void updateStatus(@RequestBody DeptStatusRequest request){
deptService.updateStatus(request);
}
}*/
@PostMapping("/nodesByDeptId/{deptId}")
public List<DeptTreeNode> nodesByDeptId(@PathVariable("deptId") Long deptId){

View File

@ -1,30 +1,30 @@
package io.dataease.controller.sys;
import com.github.pagehelper.Page;
/*import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.dataease.base.domain.SysRole;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.RoleMenusRequest;
import io.dataease.controller.sys.request.RoleMenusRequest;*/
import io.dataease.controller.sys.response.RoleUserItem;
import io.dataease.service.sys.SysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/*import io.swagger.annotations.ApiOperation;*/
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import java.util.List;
@ApiIgnore
/*@ApiIgnore
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:角色管理")
@RequestMapping("/api/role")
public class SysRoleController {
public class SysRoleController {*/
/*
@Resource
private SysRoleService sysRoleService;
@ -74,4 +74,5 @@ public class SysRoleController {
public List<RoleUserItem> all(){
return sysRoleService.allRoles();
}
}
*/
/*}*/

View File

@ -12,7 +12,9 @@ import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.SysUserCreateRequest;
import io.dataease.controller.sys.request.SysUserPwdRequest;
import io.dataease.controller.sys.request.SysUserStateRequest;
import io.dataease.controller.sys.response.RoleUserItem;
import io.dataease.controller.sys.response.SysUserGridResponse;
import io.dataease.service.sys.SysRoleService;
import io.dataease.service.sys.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -32,6 +34,9 @@ public class SysUserController {
@Resource
private SysUserService sysUserService;
@Resource
private SysRoleService sysRoleService;
@ApiOperation("查询用户")
@PostMapping("/userGrid/{goPage}/{pageSize}")
public Pager<List<SysUserGridResponse>> userGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody BaseGridRequest request) {
@ -68,26 +73,27 @@ public class SysUserController {
sysUserService.updateStatus(request);
}
@ApiOperation("用户更新密码")
@ApiOperation("更新当前用户密码")
@PostMapping("/updatePwd")
public void updatePwd(@RequestBody SysUserPwdRequest request){
sysUserService.updatePwd(request);
}
@ApiOperation("管理员更新密码")
@ApiOperation("更新指定用户密码")
@PostMapping("/adminUpdatePwd")
public void adminUpdatePwd(@RequestBody SysUserPwdRequest request){
sysUserService.adminUpdatePwd(request);
}
@ApiOperation("个人信息")
@ApiOperation("当前用户信息")
@PostMapping("/personInfo")
public CurrentUserDto personInfo() {
CurrentUserDto user = AuthUtils.getUser();
return user;
}
@ApiIgnore
@ApiOperation("更新个人信息")
@PostMapping("/updatePersonInfo")
public void updatePersonInfo(@RequestBody SysUserCreateRequest request){
@ -104,4 +110,10 @@ public class SysUserController {
}
});
}
@ApiOperation("查询所有角色")
@PostMapping("/all")
public List<RoleUserItem> all(){
return sysRoleService.allRoles();
}
}

View File

@ -1,6 +1,7 @@
package io.dataease.controller.sys.base;
import io.dataease.base.mapper.ext.query.GridExample;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.collections.CollectionUtils;
import java.io.Serializable;
@ -9,6 +10,7 @@ import java.util.List;
public class BaseGridRequest implements Serializable {
@ApiModelProperty("查询条件")
private List<ConditionEntity> conditions;
public List<ConditionEntity> getConditions() {
@ -27,6 +29,7 @@ public class BaseGridRequest implements Serializable {
this.orders = orders;
}
@ApiModelProperty("排序描述")
private List<String> orders;
public GridExample convertExample(){

View File

@ -1,5 +1,6 @@
package io.dataease.controller.sys.base;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -7,10 +8,13 @@ import java.io.Serializable;
@Data
public class ConditionEntity implements Serializable {
@ApiModelProperty(value = "字段")
private String field;
@ApiModelProperty(value = "操作符")
private String operator;
@ApiModelProperty(value = "字段值")
private Object value;
}

View File

@ -1,5 +1,6 @@
package io.dataease.controller.sys.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -7,10 +8,10 @@ import java.util.List;
@Data
public class BatchSettingRequest implements Serializable {
@ApiModelProperty("消息类型ID集合")
private List<Long> typeIds;
@ApiModelProperty("消息类型ID")
private Long channelId;
@ApiModelProperty("订阅状态")
private Boolean enable;
}

View File

@ -1,5 +1,6 @@
package io.dataease.controller.sys.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -10,9 +11,12 @@ public class MsgRequest implements Serializable {
private static final long serialVersionUID = 1920091635946508658L;
@ApiModelProperty("消息类型ID")
private Long type;
@ApiModelProperty("是否订阅")
private Boolean status;
@ApiModelProperty("排序描述")
private List<String> orders;
}

View File

@ -1,6 +1,7 @@
package io.dataease.controller.sys.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -8,7 +9,9 @@ import java.io.Serializable;
@Data
public class MsgSettingRequest implements Serializable {
@ApiModelProperty("消息类型ID")
private Long typeId;
@ApiModelProperty("消息渠道ID")
private Long channelId;
}

View File

@ -1,13 +1,16 @@
package io.dataease.controller.sys.request;
import io.dataease.base.domain.SysUser;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class SysUserCreateRequest extends SysUser {
@ApiModelProperty(value = "角色ID集合", required = true, position = 7)
private List<Long> roleIds;
}

View File

@ -1,6 +1,7 @@
package io.dataease.controller.sys.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -8,9 +9,13 @@ import java.io.Serializable;
@Data
public class SysUserPwdRequest implements Serializable {
@ApiModelProperty(value = "用户ID", required = true)
private Long userId;
@ApiModelProperty(value = "旧密码(密文)", required = true)
private String password;
@ApiModelProperty(hidden = true)
private String repeatPassword;
@ApiModelProperty(value = "新密码(明文)", required = true)
private String newPassword;

View File

@ -1,5 +1,6 @@
package io.dataease.controller.sys.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -7,7 +8,9 @@ import java.io.Serializable;
@Data
public class SysUserStateRequest implements Serializable {
@ApiModelProperty(value = "用户ID", required = true)
private Long userId;
@ApiModelProperty(value = "状态", required = true, allowableValues = "1,0")
private Long enabled;
}

View File

@ -1,6 +1,7 @@
package io.dataease.controller.sys.response;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ -11,9 +12,12 @@ public class SettingTreeNode implements Serializable {
private static final long serialVersionUID = -2416283978185545199L;
@ApiModelProperty("消息类型ID")
private Long id;
@ApiModelProperty("消息类型名称")
private String name;
@ApiModelProperty("子节点")
private List<SettingTreeNode> children;
}

View File

@ -3,6 +3,7 @@ package io.dataease.datasource.constants;
public enum DatasourceTypes {
excel("excel", "excel", "", "", "", "", ""),
mysql("mysql", "mysql", "com.mysql.jdbc.Driver", "`", "`", "'", "'"),
pg("pg", "pg", "org.postgresql.Driver", "\"", "\"", "\"", "\""),
sqlServer("sqlServer", "sqlServer", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "\"", "\"", "\"", "\""),
doris("doris", "doris", "com.mysql.jdbc.Driver", "`", "`", "", ""),
oracle("oracle", "oracle", "oracle.jdbc.driver.OracleDriver", "\"", "\"", "\"", "\"");

View File

@ -12,5 +12,6 @@ public class JdbcDTO {
private String username;
private String password;
private String dataBase;
private String schema;
private String dataSourceType = "jdbc";
}

View File

@ -9,7 +9,6 @@ public class OracleConfigration extends JdbcDTO {
private String driver = "oracle.jdbc.driver.OracleDriver";
private String connectionType;
private String schema;
public String getJdbc() {
// 连接参数先写死后边要把编码时区等参数放到数据源的设置中

View File

@ -0,0 +1,19 @@
package io.dataease.datasource.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PgConfigration extends JdbcDTO {
private String driver = "org.postgresql.Driver";
public String getJdbc() {
// 连接参数先写死后边要把编码时区等参数放到数据源的设置中
return "jdbc:postgresql://HOSTNAME:PORT/DATABASE"
.replace("HOSTNAME", getHost())
.replace("PORT", getPort().toString())
.replace("DATABASE", getDataBase());
}
}

View File

@ -8,7 +8,6 @@ import lombok.Setter;
@Setter
public class SqlServerConfigration extends JdbcDTO {
private String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private String schema;
public String getJdbc(){
return "jdbc:sqlserver://HOSTNAME:PORT;DatabaseName=DATABASE".replace("HOSTNAME", getHost()).replace("PORT", getPort().toString()).replace("DATABASE", getDataBase());

View File

@ -3,10 +3,7 @@ package io.dataease.datasource.provider;
import com.google.gson.Gson;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import io.dataease.datasource.constants.DatasourceTypes;
import io.dataease.datasource.dto.MysqlConfigration;
import io.dataease.datasource.dto.OracleConfigration;
import io.dataease.datasource.dto.SqlServerConfigration;
import io.dataease.datasource.dto.TableFiled;
import io.dataease.datasource.dto.*;
import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.exception.DataEaseException;
import io.dataease.i18n.Translator;
@ -309,7 +306,7 @@ public class JdbcProvider extends DatasourceProvider {
resultSet.close();
ps.close();
} catch (Exception e) {
DataEaseException.throwException(Translator.get("i18n_datasource_connect_error") + e.getMessage());
DataEaseException.throwException(e.getMessage());
} finally {
if(con != null){con.close();}
}
@ -433,6 +430,12 @@ public class JdbcProvider extends DatasourceProvider {
props.put( "oracle.net.CONNECT_TIMEOUT" , "5000") ;
// props.put( "oracle.jdbc.ReadTimeout" , "5000" ) ;
break;
case pg:
PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class);
username = pgConfigration.getUsername();
password = pgConfigration.getPassword();
driver = pgConfigration.getDriver();
jdbcurl = pgConfigration.getJdbc();
default:
break;
}
@ -477,6 +480,13 @@ public class JdbcProvider extends DatasourceProvider {
dataSource.setPassword(oracleConfigration.getPassword());
dataSource.setJdbcUrl(oracleConfigration.getJdbc());
break;
case pg:
PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class);
dataSource.setUser(pgConfigration.getUsername());
dataSource.setDriverClass(pgConfigration.getDriver());
dataSource.setPassword(pgConfigration.getPassword());
dataSource.setJdbcUrl(pgConfigration.getJdbc());
break;
default:
break;
}
@ -494,6 +504,9 @@ public class JdbcProvider extends DatasourceProvider {
case sqlServer:
SqlServerConfigration sqlServerConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), SqlServerConfigration.class);
return sqlServerConfigration.getDataBase();
case pg:
PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class);
return pgConfigration.getDataBase();
default:
return null;
}
@ -517,6 +530,12 @@ public class JdbcProvider extends DatasourceProvider {
throw new Exception(Translator.get("i18n_schema_is_empty"));
}
return "select table_name, owner from all_tables where owner='" + oracleConfigration.getSchema() + "'";
case pg:
PgConfigration pgConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfigration.class);
if(StringUtils.isEmpty(pgConfigration.getSchema())){
throw new Exception(Translator.get("i18n_schema_is_empty"));
}
return "SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg%' AND tablename NOT LIKE 'sql_%' AND schemaname='SCHEMA' ;".replace("SCHEMA", pgConfigration.getSchema());
default:
return "show tables;";
}
@ -529,6 +548,8 @@ public class JdbcProvider extends DatasourceProvider {
return "select * from all_users";
case sqlServer:
return "select name from sys.schemas;";
case pg:
return "SELECT nspname FROM pg_namespace;";
default:
return "show tables;";
}

View File

@ -28,6 +28,8 @@ public class ProviderFactory implements ApplicationContextAware {
return context.getBean("jdbc", DatasourceProvider.class);
case sqlServer:
return context.getBean("jdbc", DatasourceProvider.class);
case pg:
return context.getBean("jdbc", DatasourceProvider.class);
default:
return context.getBean("jdbc", DatasourceProvider.class);
}
@ -42,6 +44,8 @@ public class ProviderFactory implements ApplicationContextAware {
return context.getBean("dorisQuery", QueryProvider.class);
case sqlServer:
return context.getBean("sqlserverQuery", QueryProvider.class);
case pg:
return context.getBean("pgQuery", QueryProvider.class);
case oracle:
return context.getBean("oracleQuery", QueryProvider.class);
default:

View File

@ -0,0 +1,31 @@
package io.dataease.dto;
import java.util.List;
/**
* Author: wangjiahao
* Date: 8/10/21
* Description:
*/
public class LinkageInfoDTO {
private String sourceInfo;
private List<String> targetInfoList;
public String getSourceInfo() {
return sourceInfo;
}
public void setSourceInfo(String sourceInfo) {
this.sourceInfo = sourceInfo;
}
public List<String> getTargetInfoList() {
return targetInfoList;
}
public void setTargetInfoList(List<String> targetInfoList) {
this.targetInfoList = targetInfoList;
}
}

View File

@ -1,9 +1,11 @@
package io.dataease.dto.chart;
import io.dataease.base.domain.ChartViewWithBLOBs;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
/**
@ -20,4 +22,8 @@ public class ChartViewDTO extends ChartViewWithBLOBs {
private Boolean isLeaf;
private String pid;
private String sql;
private boolean drill;
private List<ChartExtFilterRequest> drillFilters;
}

View File

@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
@ -17,6 +19,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@ApiIgnore
@RestController
@RequestMapping("/api/pluginCommon")
public class PluginCommonServer {

View File

@ -11,14 +11,19 @@ import io.dataease.plugins.xpack.dept.dto.request.XpackMoveDept;
import io.dataease.plugins.xpack.dept.dto.response.XpackDeptTreeNode;
import io.dataease.plugins.xpack.dept.dto.response.XpackSysDept;
import io.dataease.plugins.xpack.dept.service.DeptXpackService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.List;
import java.util.stream.Collectors;
@Api(tags = "xpack部门管理")
@RequestMapping("/plugin/dept")
@RestController
public class XDeptServer {
@ApiOperation("查询子节点")
@PostMapping("/childNodes/{pid}")
public List<DeptNodeResponse> childNodes(@PathVariable("pid") Long pid){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
@ -33,6 +38,7 @@ public class XDeptServer {
return nodeResponses;
}
@ApiOperation("搜索组织树")
@PostMapping("/search")
public List<DeptNodeResponse> search(@RequestBody XpackGridRequest request){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
@ -47,6 +53,7 @@ public class XDeptServer {
return nodeResponses;
}
@ApiIgnore
@PostMapping("/root")
public List<XpackSysDept> rootData(){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
@ -54,18 +61,21 @@ public class XDeptServer {
return nodes;
}
@ApiOperation("创建")
@PostMapping("/create")
public int create(@RequestBody XpackCreateDept dept){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
return deptService.add(dept);
}
@ApiOperation("删除")
@PostMapping("/delete")
public void delete(@RequestBody List<XpackDeleteDept> requests){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
deptService.batchDelete(requests);
}
@ApiOperation("更新")
@PostMapping("/update")
public int update(@RequestBody XpackCreateDept dept){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
@ -73,12 +83,15 @@ public class XDeptServer {
}
@ApiIgnore
@ApiOperation("删除")
@PostMapping("/nodesByDeptId/{deptId}")
public List<XpackDeptTreeNode> nodesByDeptId(@PathVariable("deptId") Long deptId){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
return deptService.searchTree(deptId);
}
@ApiOperation("移动")
@PostMapping("/move")
public void move(@RequestBody XpackMoveDept xpackMoveDept){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);

View File

@ -10,14 +10,19 @@ import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.role.dto.response.XpackRoleDto;
import io.dataease.plugins.xpack.role.dto.response.XpackRoleItemDto;
import io.dataease.plugins.xpack.role.service.RoleXpackService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.List;
@Api(tags = "xpack角色管理")
@RequestMapping("/plugin/role")
@RestController
public class XRoleServer {
@ApiOperation("新增角色")
@PostMapping("/create")
public void create(@RequestBody XpackRoleDto role){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
@ -25,6 +30,7 @@ public class XRoleServer {
}
@ApiOperation("删除角色")
@PostMapping("/delete/{roleId}")
public void delete(@PathVariable("roleId") Long roleId){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
@ -32,12 +38,14 @@ public class XRoleServer {
}
@ApiOperation("更新角色")
@PostMapping("/update")
public void update(@RequestBody XpackRoleDto role){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
roleXpackService.update(role);
}
@ApiOperation("分页查询")
@PostMapping("/roleGrid/{goPage}/{pageSize}")
public Pager<List<XpackRoleDto>> roleGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody XpackGridRequest request) {
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
@ -46,6 +54,7 @@ public class XRoleServer {
return listPager;
}
@ApiIgnore
@PostMapping("/all")
public List<XpackRoleItemDto> all() {
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);

View File

@ -1,10 +1,15 @@
package io.dataease.provider;
import com.google.gson.Gson;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.base.domain.Datasource;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.datasource.dto.JdbcDTO;
import io.dataease.datasource.dto.SqlServerConfigration;
import io.dataease.dto.chart.ChartCustomFilterDTO;
import io.dataease.dto.chart.ChartViewFieldDTO;
import io.dataease.dto.sqlObj.SQLObj;
import io.dataease.provider.pg.PgConstants;
import java.util.List;
@ -30,15 +35,15 @@ public abstract class QueryProvider {
public abstract String createQuerySQLAsTmpWithPage(String sql, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup);
public abstract String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList);
public abstract String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, Datasource ds);
public abstract String getSQLAsTmp(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList);
public abstract String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack);
public abstract String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack, Datasource ds);
public abstract String getSQLAsTmpStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack);
public abstract String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble);
public abstract String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble, Datasource ds);
public abstract String getSQLAsTmpScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble);
@ -59,7 +64,15 @@ public abstract class QueryProvider {
public abstract String wrapSql(String sql);
public abstract String createRawQuerySQL(String table, List<DatasetTableField> fields);
public abstract String createRawQuerySQL(String table, List<DatasetTableField> fields, Datasource ds);
public abstract String createRawQuerySQLAsTmp(String sql, List<DatasetTableField> fields);
public void setSchema(SQLObj tableObj, Datasource ds){
if(ds != null){
String schema = new Gson().fromJson(ds.getConfiguration(), JdbcDTO.class).getSchema();
schema = String.format( PgConstants.KEYWORD_TABLE, schema);
tableObj.setTableName(schema + "." + tableObj.getTableName());
}
}
}

View File

@ -174,7 +174,7 @@ public class DorisQueryProvider extends QueryProvider {
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> 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))
@ -281,11 +281,11 @@ public class DorisQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL("(" + sql + ")", xAxis, yAxis, customFilter, extFilterRequestList);
return getSQL("(" + sql + ")", xAxis, yAxis, customFilter, extFilterRequestList, null);
}
@Override
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack, 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))
@ -395,11 +395,11 @@ public class DorisQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
return getSQLStack("(" + table + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack);
return getSQLStack("(" + table + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack, null);
}
@Override
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble, 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))
@ -509,7 +509,7 @@ public class DorisQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
return getSQLScatter("(" + table + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble);
return getSQLScatter("(" + table + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble, null);
}
@Override
@ -605,7 +605,7 @@ public class DorisQueryProvider extends QueryProvider {
}
@Override
public String createRawQuerySQL(String table, List<DatasetTableField> fields) {
public String createRawQuerySQL(String table, List<DatasetTableField> fields, Datasource ds) {
String[] array = fields.stream().map(f -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("`").append(f.getDataeaseName()).append("` AS ").append(f.getDataeaseName());
@ -616,7 +616,7 @@ public class DorisQueryProvider extends QueryProvider {
@Override
public String createRawQuerySQLAsTmp(String sql, List<DatasetTableField> fields) {
return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields);
return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null);
}
private String sqlFix(String sql) {

View File

@ -165,7 +165,7 @@ public class MysqlQueryProvider extends QueryProvider {
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> 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))
@ -273,11 +273,11 @@ public class MysqlQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList);
return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList, null);
}
@Override
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack, 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))
@ -387,11 +387,11 @@ public class MysqlQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack);
return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack, null);
}
@Override
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble, 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))
@ -501,7 +501,7 @@ public class MysqlQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble);
return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble, null);
}
@Override
@ -597,7 +597,7 @@ public class MysqlQueryProvider extends QueryProvider {
}
@Override
public String createRawQuerySQL(String table, List<DatasetTableField> fields) {
public String createRawQuerySQL(String table, List<DatasetTableField> fields, Datasource ds) {
String[] array = fields.stream().map(f -> {
StringBuilder stringBuilder = new StringBuilder();
if (f.getDeExtractType() == 4) { // 处理 tinyint
@ -612,7 +612,7 @@ public class MysqlQueryProvider extends QueryProvider {
@Override
public String createRawQuerySQLAsTmp(String sql, List<DatasetTableField> fields) {
return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields);
return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null);
}
public String transMysqlFilterTerm(String term) {

View File

@ -199,7 +199,7 @@ public class OracleQueryProvider extends QueryProvider {
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> 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)))
@ -306,11 +306,11 @@ public class OracleQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList);
return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList, null);
}
@Override
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack, 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)))
@ -420,11 +420,11 @@ public class OracleQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack);
return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack, null);
}
@Override
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble, 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)))
@ -534,7 +534,7 @@ public class OracleQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble);
return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble, null);
}
@Override
@ -629,7 +629,7 @@ public class OracleQueryProvider extends QueryProvider {
}
@Override
public String createRawQuerySQL(String table, List<DatasetTableField> fields) {
public String createRawQuerySQL(String table, List<DatasetTableField> fields, Datasource ds) {
String[] array = fields.stream().map(f -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" \"").append(f.getOriginName()).append("\"");
@ -640,7 +640,7 @@ public class OracleQueryProvider extends QueryProvider {
@Override
public String createRawQuerySQLAsTmp(String sql, List<DatasetTableField> fields) {
return createRawQuerySQL(" (" + sqlFix(sql) + ") DE_TMP ", fields);
return createRawQuerySQL(" (" + sqlFix(sql) + ") DE_TMP ", fields, null);
}
public String transMysqlFilterTerm(String term) {

View File

@ -0,0 +1,43 @@
package io.dataease.provider.pg;
import io.dataease.provider.SQLConstants;
import static io.dataease.datasource.constants.DatasourceTypes.pg;
/**
* @Author gin
* @Date 2021/7/8 7:22 下午
*/
public class PgConstants extends SQLConstants {
public static final String KEYWORD_TABLE = pg.getKeywordPrefix() + "%s" + pg.getKeywordSuffix();
public static final String KEYWORD_FIX = "%s." + pg.getKeywordPrefix() + "%s" + pg.getKeywordSuffix();
public static final String UNIX_TIMESTAMP = "floor(extract(epoch from(( %s - timestamp '1970-01-01 00:00:00')*1000))) ";
public static final String DATE_FORMAT = "to_char(%s, %s)";
public static final String FROM_UNIXTIME = "to_timestamp(%s)";
public static final String CAST = "CAST(%s AS %s)";
public static final String DEFAULT_DATE_FORMAT = "'YYYY-MM-DD HH24:MI:SS'";
public static final String DEFAULT_INT_FORMAT = "numeric(18,0)";
public static final String DEFAULT_FLOAT_FORMAT = "numeric(18,2)";
public static final String WHERE_VALUE_NULL = "(NULL,'')";
public static final String WHERE_VALUE_VALUE = "'%s'";
public static final String AGG_COUNT = "COUNT(*)";
public static final String AGG_FIELD = "%s(%s)";
public static final String WHERE_BETWEEN = "'%s' AND '%s'";
public static final String BRACKETS = "(%s)";
}

View File

@ -0,0 +1,922 @@
package io.dataease.provider.pg;
import com.google.gson.Gson;
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.datasource.dto.JdbcDTO;
import io.dataease.datasource.dto.PgConfigration;
import io.dataease.datasource.dto.SqlServerConfigration;
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 io.dataease.provider.sqlserver.SqlServerSQLConstants;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static io.dataease.provider.SQLConstants.TABLE_ALIAS_PREFIX;
@Service("pgQuery")
public class PgQueryProvider extends QueryProvider {
@Resource
private DatasetTableFieldMapper datasetTableFieldMapper;
@Override
public Integer transFieldType(String field) {
field = field.toLowerCase();
switch (field) {
case "bpchar":
case "varchar":
case "text":
case "tsquery":
case "tsvector":
case "uuid":
case "xml":
case "json":
case "bit":
case "jsonb":
case "cidr":
case "inet":
case "macaddr":
case "txid_snapshot":
case "box":
case "circle":
case "line":
case "lseg":
case "path":
case "point":
case "polygon":
case "bool":
case "interval":
return DeTypeConstants.DE_STRING;// 文本
case "date":
case "time":
case "timestamp":
case "timestamptz":
return DeTypeConstants.DE_TIME;// 时间
case "int2":
case "int4":
case "int8":
case "INTEGER":
case "BIGINT":
return DeTypeConstants.DE_INT;// 整型
case "numeric":
case "float4":
case "float8":
case "money":
return DeTypeConstants.DE_FLOAT;// 浮点
// case "bool":
case "TINYINT":
return DeTypeConstants.DE_BOOL;// 布尔
case "bytea":
return DeTypeConstants.DE_Binary;// 二进制
default:
return DeTypeConstants.DE_STRING;
}
}
@Override
public String createSQLPreview(String sql, String orderBy) {
return "SELECT * FROM (" + sqlFix(sql) + ") AS tmp " + " LIMIT 1000 offset 0";
}
@Override
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup, Datasource ds) {
SQLObj tableObj = SQLObj.builder()
.tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 0))
.build();
setSchema(tableObj,ds);
List<SQLObj> xFields = new ArrayList<>();
if (CollectionUtils.isNotEmpty(fields)) {
for (int i = 0; i < fields.size(); i++) {
DatasetTableField f = fields.get(i);
String originField;
if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originField = calcFieldRegex(f.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName());
} else {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
String fieldName = "";
// 处理横轴字段
if (f.getDeExtractType() == DeTypeConstants.DE_TIME) {
if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) {
fieldName = String.format( PgConstants.UNIX_TIMESTAMP, originField);
} else {
fieldName = originField;
}
} else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) {
if (f.getDeType() == DeTypeConstants.DE_INT) {
fieldName = String.format( PgConstants.CAST, originField, PgConstants.DEFAULT_INT_FORMAT);
} else if (f.getDeType() == DeTypeConstants.DE_FLOAT) {
fieldName = String.format( PgConstants.CAST, originField, PgConstants.DEFAULT_FLOAT_FORMAT);
} else if (f.getDeType() == DeTypeConstants.DE_TIME) {
fieldName = String.format( PgConstants.CAST, originField, "timestamp");
} else {
fieldName = originField;
}
} else {
if (f.getDeType() == DeTypeConstants.DE_TIME) {
String cast = String.format( PgConstants.CAST, originField, "bigint");
fieldName = String.format( PgConstants.FROM_UNIXTIME, cast );
} else if (f.getDeType() == DeTypeConstants.DE_INT) {
fieldName = String.format( PgConstants.CAST, originField, PgConstants.DEFAULT_INT_FORMAT);
} else {
fieldName = originField;
}
}
xFields.add(SQLObj.builder()
.fieldName(fieldName)
.fieldAlias(fieldAlias)
.build());
}
}
STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE);
ST st_sql = stg.getInstanceOf("previewSql");
st_sql.add("isGroup", isGroup);
if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
return st_sql.render();
}
@Override
public String createQuerySQLAsTmp(String sql, List<DatasetTableField> fields, boolean isGroup) {
return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null);
}
@Override
public String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds) {
return createQuerySQL(table, fields, isGroup, null) + " LIMIT " + realSize + " offset " + (page - 1) * pageSize;
}
@Override
public String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup, Datasource ds) {
return createQuerySQL(table, fields, isGroup, null) + " LIMIT " + limit + " offset 0";
}
@Override
public String createQuerySqlWithLimit(String sql, List<DatasetTableField> fields, Integer limit, boolean isGroup) {
return createQuerySQLAsTmp(sql, fields, isGroup) + " LIMIT " + limit + " offset 0";
}
@Override
public String createQuerySQLAsTmpWithPage(String sql, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup) {
return createQuerySQLAsTmp(sql, fields, isGroup) + " LIMIT " + realSize + " offset " + (page - 1) * pageSize;
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> 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<SQLObj> xFields = new ArrayList<>();
List<SQLObj> xWheres = new ArrayList<>();
List<SQLObj> 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<SQLObj> yFields = new ArrayList<>();
List<SQLObj> yWheres = new ArrayList<>();
List<SQLObj> yOrders = new ArrayList<>();
if (CollectionUtils.isNotEmpty(yAxis)) {
for (int i = 0; i < yAxis.size(); i++) {
ChartViewFieldDTO y = yAxis.get(i);
String originField;
if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originField = calcFieldRegex(y.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
} else {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
// 处理纵轴字段
yFields.add(getYFields(y, originField, fieldAlias));
// 处理纵轴过滤
yWheres.addAll(getYWheres(y, originField, fieldAlias));
// 处理纵轴排序
if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) {
yOrders.add(SQLObj.builder()
.orderField(originField)
.orderAlias(fieldAlias)
.orderDirection(y.getSort())
.build());
}
}
}
// 处理视图中字段过滤
List<SQLObj> customWheres = transCustomFilterList(tableObj, customFilter);
// 处理仪表板字段过滤
List<SQLObj> extWheres = transExtFilterList(tableObj, extFilterRequestList);
// 构建sql所有参数
List<SQLObj> fields = new ArrayList<>();
fields.addAll(xFields);
fields.addAll(yFields);
List<SQLObj> wheres = new ArrayList<>();
wheres.addAll(xWheres);
if (customWheres != null) wheres.addAll(customWheres);
if (extWheres != null) wheres.addAll(extWheres);
List<SQLObj> groups = new ArrayList<>();
groups.addAll(xFields);
// 外层再次套sql
List<SQLObj> orders = new ArrayList<>();
orders.addAll(xOrders);
orders.addAll(yOrders);
List<SQLObj> aggWheres = new ArrayList<>();
aggWheres.addAll(yWheres);
STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE);
ST st_sql = stg.getInstanceOf("querySql");
if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields);
if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
String sql = st_sql.render();
ST st = stg.getInstanceOf("querySql");
SQLObj tableSQL = SQLObj.builder()
.tableName(String.format( PgConstants.BRACKETS, sql))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 1))
.build();
if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres);
if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders);
if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL);
return st.render();
}
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList, null);
}
@Override
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack, 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<SQLObj> xFields = new ArrayList<>();
List<SQLObj> xWheres = new ArrayList<>();
List<SQLObj> xOrders = new ArrayList<>();
List<ChartViewFieldDTO> xList = new ArrayList<>();
xList.addAll(xAxis);
xList.addAll(extStack);
if (CollectionUtils.isNotEmpty(xList)) {
for (int i = 0; i < xList.size(); i++) {
ChartViewFieldDTO x = xList.get(i);
String originField;
if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originField = calcFieldRegex(x.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName());
} else {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
// 处理横轴字段
xFields.add(getXFields(x, originField, fieldAlias));
// 处理横轴过滤
// xWheres.addAll(getXWheres(x, originField, fieldAlias));
// 处理横轴排序
if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) {
xOrders.add(SQLObj.builder()
.orderField(originField)
.orderAlias(fieldAlias)
.orderDirection(x.getSort())
.build());
}
}
}
List<SQLObj> yFields = new ArrayList<>();
List<SQLObj> yWheres = new ArrayList<>();
List<SQLObj> yOrders = new ArrayList<>();
if (CollectionUtils.isNotEmpty(yAxis)) {
for (int i = 0; i < yAxis.size(); i++) {
ChartViewFieldDTO y = yAxis.get(i);
String originField;
if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originField = calcFieldRegex(y.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
} else {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
// 处理纵轴字段
yFields.add(getYFields(y, originField, fieldAlias));
// 处理纵轴过滤
yWheres.addAll(getYWheres(y, originField, fieldAlias));
// 处理纵轴排序
if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) {
yOrders.add(SQLObj.builder()
.orderField(originField)
.orderAlias(fieldAlias)
.orderDirection(y.getSort())
.build());
}
}
}
// 处理视图中字段过滤
List<SQLObj> customWheres = transCustomFilterList(tableObj, customFilter);
// 处理仪表板字段过滤
List<SQLObj> extWheres = transExtFilterList(tableObj, extFilterRequestList);
// 构建sql所有参数
List<SQLObj> fields = new ArrayList<>();
fields.addAll(xFields);
fields.addAll(yFields);
List<SQLObj> wheres = new ArrayList<>();
wheres.addAll(xWheres);
if (customWheres != null) wheres.addAll(customWheres);
if (extWheres != null) wheres.addAll(extWheres);
List<SQLObj> groups = new ArrayList<>();
groups.addAll(xFields);
// 外层再次套sql
List<SQLObj> orders = new ArrayList<>();
orders.addAll(xOrders);
orders.addAll(yOrders);
List<SQLObj> aggWheres = new ArrayList<>();
aggWheres.addAll(yWheres);
STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE);
ST st_sql = stg.getInstanceOf("querySql");
if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields);
if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
String sql = st_sql.render();
ST st = stg.getInstanceOf("querySql");
SQLObj tableSQL = SQLObj.builder()
.tableName(String.format( PgConstants.BRACKETS, sql))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 1))
.build();
if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres);
if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders);
if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL);
return st.render();
}
@Override
public String getSQLAsTmpStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack, null);
}
@Override
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble, 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<SQLObj> xFields = new ArrayList<>();
List<SQLObj> xWheres = new ArrayList<>();
List<SQLObj> 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<SQLObj> yFields = new ArrayList<>();
List<SQLObj> yWheres = new ArrayList<>();
List<SQLObj> yOrders = new ArrayList<>();
List<ChartViewFieldDTO> yList = new ArrayList<>();
yList.addAll(yAxis);
yList.addAll(extBubble);
if (CollectionUtils.isNotEmpty(yList)) {
for (int i = 0; i < yList.size(); i++) {
ChartViewFieldDTO y = yList.get(i);
String originField;
if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originField = calcFieldRegex(y.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
} else {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
// 处理纵轴字段
yFields.add(getYFields(y, originField, fieldAlias));
// 处理纵轴过滤
yWheres.addAll(getYWheres(y, originField, fieldAlias));
// 处理纵轴排序
if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) {
yOrders.add(SQLObj.builder()
.orderField(originField)
.orderAlias(fieldAlias)
.orderDirection(y.getSort())
.build());
}
}
}
// 处理视图中字段过滤
List<SQLObj> customWheres = transCustomFilterList(tableObj, customFilter);
// 处理仪表板字段过滤
List<SQLObj> extWheres = transExtFilterList(tableObj, extFilterRequestList);
// 构建sql所有参数
List<SQLObj> fields = new ArrayList<>();
fields.addAll(xFields);
fields.addAll(yFields);
List<SQLObj> wheres = new ArrayList<>();
wheres.addAll(xWheres);
if (customWheres != null) wheres.addAll(customWheres);
if (extWheres != null) wheres.addAll(extWheres);
List<SQLObj> groups = new ArrayList<>();
groups.addAll(xFields);
// 外层再次套sql
List<SQLObj> orders = new ArrayList<>();
orders.addAll(xOrders);
orders.addAll(yOrders);
List<SQLObj> aggWheres = new ArrayList<>();
aggWheres.addAll(yWheres);
STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE);
ST st_sql = stg.getInstanceOf("querySql");
if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields);
if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
String sql = st_sql.render();
ST st = stg.getInstanceOf("querySql");
SQLObj tableSQL = SQLObj.builder()
.tableName(String.format( PgConstants.BRACKETS, sql))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 1))
.build();
if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres);
if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders);
if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL);
return st.render();
}
@Override
public String getSQLAsTmpScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> 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<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
// 字段汇总 排序等
SQLObj tableObj = SQLObj.builder()
.tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format( PgConstants.KEYWORD_TABLE, table))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 0))
.build();
List<SQLObj> yFields = new ArrayList<>();
List<SQLObj> yWheres = new ArrayList<>();
List<SQLObj> yOrders = new ArrayList<>();
if (CollectionUtils.isNotEmpty(yAxis)) {
for (int i = 0; i < yAxis.size(); i++) {
ChartViewFieldDTO y = yAxis.get(i);
String originField;
if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originField = calcFieldRegex(y.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
} else {
originField = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
// 处理纵轴字段
yFields.add(getYFields(y, originField, fieldAlias));
// 处理纵轴过滤
yWheres.addAll(getYWheres(y, originField, fieldAlias));
// 处理纵轴排序
if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) {
yOrders.add(SQLObj.builder()
.orderField(originField)
.orderAlias(fieldAlias)
.orderDirection(y.getSort())
.build());
}
}
}
// 处理视图中字段过滤
List<SQLObj> customWheres = transCustomFilterList(tableObj, customFilter);
// 处理仪表板字段过滤
List<SQLObj> extWheres = transExtFilterList(tableObj, extFilterRequestList);
// 构建sql所有参数
List<SQLObj> fields = new ArrayList<>();
fields.addAll(yFields);
List<SQLObj> wheres = new ArrayList<>();
if (customWheres != null) wheres.addAll(customWheres);
if (extWheres != null) wheres.addAll(extWheres);
List<SQLObj> groups = new ArrayList<>();
// 外层再次套sql
List<SQLObj> orders = new ArrayList<>();
orders.addAll(yOrders);
List<SQLObj> aggWheres = new ArrayList<>();
aggWheres.addAll(yWheres);
STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE);
ST st_sql = stg.getInstanceOf("querySql");
if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields);
if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
String sql = st_sql.render();
ST st = stg.getInstanceOf("querySql");
SQLObj tableSQL = SQLObj.builder()
.tableName(String.format( PgConstants.BRACKETS, sql))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 1))
.build();
if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres);
if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders);
if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL);
return st.render();
}
@Override
public String getSQLSummaryAsTmp(String sql, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> 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<DatasetTableField> 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);
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 {
return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table);
}
}
@Override
public String createRawQuerySQLAsTmp(String sql, List<DatasetTableField> 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<SQLObj> transCustomFilterList(SQLObj tableObj, List<ChartCustomFilterDTO> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return null;
}
List<SQLObj> list = new ArrayList<>();
for (ChartCustomFilterDTO request : requestList) {
DatasetTableField field = request.getField();
if (ObjectUtils.isEmpty(field)) {
continue;
}
String value = request.getValue();
String whereName = "";
String whereTerm = transMysqlFilterTerm(request.getTerm());
String whereValue = "";
String originName;
if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originName = calcFieldRegex(field.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) {
originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName());
} else {
originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName());
}
if (field.getDeType() == 1 && field.getDeExtractType() != 1) {
String cast = String.format( PgConstants.CAST, originName, "bigint");
whereName = String.format( PgConstants.FROM_UNIXTIME, cast);
} else {
whereName = originName;
}
if (StringUtils.equalsIgnoreCase(request.getTerm(), "null")) {
whereValue = PgConstants.WHERE_VALUE_NULL;
} else if (StringUtils.equalsIgnoreCase(request.getTerm(), "not_null")) {
whereTerm = String.format(whereTerm, originName);
} else if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) {
whereValue = "('" + StringUtils.join(value, "','") + "')";
} else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) {
whereValue = "'%" + value + "%'";
} else {
whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, value);
}
list.add(SQLObj.builder()
.whereField(whereName)
.whereTermAndValue(whereTerm + whereValue)
.build());
}
return list;
}
public List<SQLObj> transExtFilterList(SQLObj tableObj, List<ChartExtFilterRequest> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return null;
}
List<SQLObj> list = new ArrayList<>();
for (ChartExtFilterRequest request : requestList) {
List<String> value = request.getValue();
DatasetTableField field = request.getDatasetTableField();
if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) {
continue;
}
String whereName = "";
String whereTerm = transMysqlFilterTerm(request.getOperator());
String whereValue = "";
String originName;
if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) {
// 解析origin name中有关联的字段生成sql表达式
originName = calcFieldRegex(field.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) {
originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName());
} else {
originName = String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName());
}
if (field.getDeType() == 1 && field.getDeExtractType() != 1) {
String cast = String.format( PgConstants.CAST, originName, "bigint");
whereName = String.format( PgConstants.FROM_UNIXTIME, cast);
} else {
whereName = originName;
}
if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) {
whereValue = "('" + StringUtils.join(value, "','") + "')";
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) {
whereValue = "'%" + value.get(0) + "%'";
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) {
if (request.getDatasetTableField().getDeType() == 1) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0))));
String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1))));
whereValue = String.format( PgConstants.WHERE_BETWEEN, startTime, endTime);
} else {
whereValue = String.format( PgConstants.WHERE_BETWEEN, value.get(0), value.get(1));
}
} else {
whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, value.get(0));
}
list.add(SQLObj.builder()
.whereField(whereName)
.whereTermAndValue(whereTerm + whereValue)
.build());
}
return list;
}
private String sqlFix(String sql) {
if (sql.lastIndexOf(";") == (sql.length() - 1)) {
sql = sql.substring(0, sql.length() - 1);
}
return sql;
}
private String transDateFormat(String dateStyle, String datePattern) {
String split = "-";
if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) {
split = "-";
} else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
split = "/";
}
switch (dateStyle) {
case "y":
return "'YYYY'";
case "y_M":
return "'YYYY" + split + "MM'";
case "y_M_d":
return "'YYYY" + split + "MM" + split + "DD'";
case "H_m_s":
return "'HH24:MI:SS'";
case "y_M_d_H_m":
return "'YYYY" + split + "MM" + split + "DD" + " HH24:MI'";
case "y_M_d_H_m_s":
return "'YYYY" + split + "MM" + split + "DD" + " HH24:MI:SS'";
default:
return "'YYYY-MM-DD HH24:MI:SS'";
}
}
private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) {
String fieldName = "";
if (x.getDeExtractType() == DeTypeConstants.DE_TIME) {
if (x.getDeType() == 2 || x.getDeType() == 3) {
fieldName = String.format( PgConstants.UNIX_TIMESTAMP, originField);
} else if (x.getDeType() == DeTypeConstants.DE_TIME) {
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
fieldName = String.format( PgConstants.DATE_FORMAT, originField, format);
} else {
fieldName = originField;
}
} else {
if (x.getDeType() == DeTypeConstants.DE_TIME) {
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
if (x.getDeExtractType() == DeTypeConstants.DE_STRING) {
fieldName = String.format( PgConstants.DATE_FORMAT, originField, format);
} else {
String cast = String.format( PgConstants.CAST, originField, "bigint");
String from_unixtime = String.format( PgConstants.FROM_UNIXTIME, cast);
fieldName = String.format( PgConstants.DATE_FORMAT, from_unixtime, format);
}
} else {
fieldName = originField;
}
}
return SQLObj.builder()
.fieldName(fieldName)
.fieldAlias(fieldAlias)
.build();
}
private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) {
String fieldName = "";
if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) {
fieldName = PgConstants.AGG_COUNT;
} else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) {
fieldName = String.format( PgConstants.AGG_FIELD, y.getSummary(), originField);
} else {
if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) {
String cast = String.format( PgConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? PgConstants.DEFAULT_INT_FORMAT : PgConstants.DEFAULT_FLOAT_FORMAT);
String agg = String.format( PgConstants.AGG_FIELD, y.getSummary(), cast);
fieldName = String.format( PgConstants.CAST, agg, PgConstants.DEFAULT_FLOAT_FORMAT);
} else {
String cast = String.format( PgConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? PgConstants.DEFAULT_INT_FORMAT : PgConstants.DEFAULT_FLOAT_FORMAT);
fieldName = String.format( PgConstants.AGG_FIELD, y.getSummary(), cast);
}
}
return SQLObj.builder()
.fieldName(fieldName)
.fieldAlias(fieldAlias)
.build();
}
private List<SQLObj> getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) {
List<SQLObj> list = new ArrayList<>();
if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) {
y.getFilter().forEach(f -> {
String whereTerm = transMysqlFilterTerm(f.getTerm());
String whereValue = "";
// 原始类型不是时间在de中被转成时间的字段做处理
if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) {
whereValue = PgConstants.WHERE_VALUE_NULL;
} else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) {
whereTerm = String.format(whereTerm, originField);
} else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) {
whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')";
} else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) {
whereValue = "'%" + f.getValue() + "%'";
} else {
whereValue = String.format( PgConstants.WHERE_VALUE_VALUE, f.getValue());
}
list.add(SQLObj.builder()
.whereField(fieldAlias)
.whereAlias(fieldAlias)
.whereTermAndValue(whereTerm + whereValue)
.build());
});
}
return list;
}
private String calcFieldRegex(String originField, SQLObj tableObj) {
originField = originField.replaceAll("[\\t\\n\\r]]", "");
// 正则提取[xxx]
String regex = "\\[(.*?)]";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(originField);
Set<String> 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<DatasetTableField> calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample);
for (DatasetTableField ele : calcFields) {
originField = originField.replaceAll("\\[" + ele.getId() + "]",
String.format( PgConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName()));
}
return originField;
}
}

View File

@ -7,13 +7,13 @@ 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.datasource.dto.JdbcDTO;
import io.dataease.datasource.dto.SqlServerConfigration;
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 io.dataease.provider.mysql.MySQLConstants;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
@ -91,10 +91,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();
if(ds != null){
String schema = new Gson().fromJson(ds.getConfiguration(), SqlServerConfigration.class).getSchema();
tableObj.setTableName(schema + "." + tableObj.getTableName());
}
setSchema(tableObj,ds);
List<SQLObj> xFields = new ArrayList<>();
if (CollectionUtils.isNotEmpty(fields)) {
@ -171,11 +168,12 @@ public class SqlserverQueryProvider extends QueryProvider {
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> 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<SQLObj> xFields = new ArrayList<>();
List<SQLObj> xWheres = new ArrayList<>();
List<SQLObj> xOrders = new ArrayList<>();
@ -263,15 +261,16 @@ public class SqlserverQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList);
return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, customFilter, extFilterRequestList, null);
}
@Override
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
public String getSQLStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack, 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<SQLObj> xFields = new ArrayList<>();
List<SQLObj> xWheres = new ArrayList<>();
List<SQLObj> xOrders = new ArrayList<>();
@ -380,15 +379,16 @@ public class SqlserverQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpStack(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extStack) {
return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack);
return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extStack, null);
}
@Override
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
public String getSQLScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble, Datasource ds) {
SQLObj tableObj = SQLObj.builder()
.tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MySQLConstants.KEYWORD_TABLE, table))
.tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(SqlServerSQLConstants.KEYWORD_TABLE, table))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 0))
.build();
setSchema(tableObj,ds);
List<SQLObj> xFields = new ArrayList<>();
List<SQLObj> xWheres = new ArrayList<>();
List<SQLObj> xOrders = new ArrayList<>();
@ -400,9 +400,9 @@ public class SqlserverQueryProvider extends QueryProvider {
// 解析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());
originField = String.format(SqlServerSQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName());
} else {
originField = String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName());
originField = String.format(SqlServerSQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
// 处理横轴字段
@ -433,9 +433,9 @@ public class SqlserverQueryProvider extends QueryProvider {
// 解析origin name中有关联的字段生成sql表达式
originField = calcFieldRegex(y.getOriginName(), tableObj);
} else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) {
originField = String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
originField = String.format(SqlServerSQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
} else {
originField = String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
originField = String.format(SqlServerSQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName());
}
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
// 处理纵轴字段
@ -483,7 +483,7 @@ public class SqlserverQueryProvider extends QueryProvider {
ST st = stg.getInstanceOf("querySql");
SQLObj tableSQL = SQLObj.builder()
.tableName(String.format(MySQLConstants.BRACKETS, sql))
.tableName(String.format(SqlServerSQLConstants.BRACKETS, sql))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 1))
.build();
if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres);
@ -494,7 +494,7 @@ public class SqlserverQueryProvider extends QueryProvider {
@Override
public String getSQLAsTmpScatter(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList, List<ChartViewFieldDTO> extBubble) {
return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble);
return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, customFilter, extFilterRequestList, extBubble, null);
}
@Override
@ -582,23 +582,24 @@ public class SqlserverQueryProvider extends QueryProvider {
}
@Override
public String createRawQuerySQL(String table, List<DatasetTableField> fields) {
public String createRawQuerySQL(String table, List<DatasetTableField> 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());
// }
stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName());
return stringBuilder.toString();
}).toArray(String[]::new);
return MessageFormat.format("SELECT {0} FROM {1}", StringUtils.join(array, ","), table);
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 {
return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table);
}
}
@Override
public String createRawQuerySQLAsTmp(String sql, List<DatasetTableField> fields) {
return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields);
return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null);
}
public String transMysqlFilterTerm(String term) {
@ -773,47 +774,6 @@ public class SqlserverQueryProvider extends QueryProvider {
}
}
private String transStringToDateFormat(String dateStyle, String datePattern, String originField) {
String split = "-";
if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) {
split = "-";
} else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
split = "/";
}
switch (dateStyle) {
case "y":
return "CONVERT(varchar(100), datepart(yy, " + "SELECT CONVERT(datetime, " + originField + " ,120)" + "))";
case "y_M":
if(split.equalsIgnoreCase("-")){
return "substring( convert(varchar," + "SELECT CONVERT(datetime, " + originField + " ,120)" + ",120),1,7)";
}else {
return "replace("+ "substring( convert(varchar," + "SELECT CONVERT(datetime, " + originField + " ,120)" + ",120),1,7), '-','/')";
}
case "y_M_d":
if(split.equalsIgnoreCase("-")){
return "CONVERT(varchar(100), " + "SELECT CONVERT(datetime, " + originField + " ,120)" + ", 23)";
}else {
return "CONVERT(varchar(100), " + "SELECT CONVERT(datetime, " + originField + " ,120)" + ", 111)";
}
case "H_m_s":
return "CONVERT(varchar(100), " + "SELECT CONVERT(datetime, " + originField + " ,120)" + ", 24)";
case "y_M_d_H_m":
if(split.equalsIgnoreCase("-")){
return "substring( convert(varchar," + "SELECT CONVERT(datetime, " + originField + " ,120)" + ",120),1,16)";
}else {
return "replace("+ "substring( convert(varchar," + "SELECT CONVERT(datetime, " + originField + " ,120)" + ",120),1,16), '-','/')";
}
case "y_M_d_H_m_s":
if(split.equalsIgnoreCase("-")){
return "convert(varchar," + "SELECT CONVERT(datetime, " + originField + " ,120)" + ",120)";
}else {
return "replace("+ "convert(varchar," + "SELECT CONVERT(datetime, " + originField + " ,120)" + ",120), '-','/')";
}
default:
return "convert(varchar," + "SELECT CONVERT(datetime, " + originField + " ,120)" + ",120)";
}
}
private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) {
String fieldName = "";
if (x.getDeExtractType() == DeTypeConstants.DE_TIME) {
@ -912,7 +872,7 @@ public class SqlserverQueryProvider extends QueryProvider {
List<DatasetTableField> calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample);
for (DatasetTableField ele : calcFields) {
originField = originField.replaceAll("\\[" + ele.getId() + "]",
String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName()));
String.format(SqlServerSQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName()));
}
return originField;
}

View File

@ -11,19 +11,12 @@ import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CommonBeanFactory;
import io.dataease.commons.utils.LogUtil;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.controller.request.chart.ChartExtRequest;
import io.dataease.controller.request.chart.ChartGroupRequest;
import io.dataease.controller.request.chart.ChartViewRequest;
import io.dataease.controller.request.dataset.DataSetGroupRequest;
import io.dataease.controller.request.dataset.DataSetTableRequest;
import io.dataease.controller.request.chart.*;
import io.dataease.datasource.provider.DatasourceProvider;
import io.dataease.datasource.provider.ProviderFactory;
import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.datasource.service.DatasourceService;
import io.dataease.dto.chart.*;
import io.dataease.dto.dataset.DataSetGroupDTO;
import io.dataease.dto.dataset.DataSetTableDTO;
import io.dataease.dto.dataset.DataSetTableUnionDTO;
import io.dataease.dto.dataset.DataTableInfoDTO;
import io.dataease.i18n.Translator;
@ -197,6 +190,8 @@ public class ChartViewService {
}.getType());
List<ChartFieldCustomFilterDTO> fieldCustomFilter = new Gson().fromJson(view.getCustomFilter(), new TypeToken<List<ChartFieldCustomFilterDTO>>() {
}.getType());
List<ChartViewFieldDTO> drill = new Gson().fromJson(view.getDrillFields(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
List<ChartCustomFilterDTO> customFilter = new ArrayList<>();
for (ChartFieldCustomFilterDTO ele : fieldCustomFilter) {
List<ChartCustomFilterDTO> collect = ele.getFilter().stream().map(f -> {
@ -225,6 +220,8 @@ public class ChartViewService {
// 过滤来自仪表板的条件
List<ChartExtFilterRequest> extFilterList = new ArrayList<>();
//组件过滤条件
if (ObjectUtils.isNotEmpty(requestList.getFilter())) {
for (ChartExtFilterRequest request : requestList.getFilter()) {
DatasetTableField datasetTableField = dataSetTableFieldsService.get(request.getFieldId());
@ -241,6 +238,64 @@ public class ChartViewService {
}
}
//联动过滤条件联动条件全部加上
if (ObjectUtils.isNotEmpty(requestList.getLinkageFilters())) {
for (ChartExtFilterRequest request : requestList.getLinkageFilters()) {
DatasetTableField datasetTableField = dataSetTableFieldsService.get(request.getFieldId());
request.setDatasetTableField(datasetTableField);
if (StringUtils.equalsIgnoreCase(datasetTableField.getTableId(), view.getTableId())) {
if (CollectionUtils.isNotEmpty(request.getViewIds())) {
if (request.getViewIds().contains(view.getId())) {
extFilterList.add(request);
}
} else {
extFilterList.add(request);
}
}
}
}
// 下钻
List<ChartExtFilterRequest> drillFilters = new ArrayList<>();
boolean isDrill = false;
List<ChartDrillRequest> drillRequest = requestList.getDrill();
if (CollectionUtils.isNotEmpty(drillRequest) && (drill.size() > drillRequest.size())) {
for (int i = 0; i < drillRequest.size(); i++) {
ChartDrillRequest request = drillRequest.get(i);
for (ChartDimensionDTO dto : request.getDimensionList()) {
ChartViewFieldDTO chartViewFieldDTO = drill.get(i);
// 将钻取值作为条件传递将所有钻取字段作为xAxis并加上下一个钻取字段
if (StringUtils.equalsIgnoreCase(dto.getId(), chartViewFieldDTO.getId())) {
isDrill = true;
DatasetTableField datasetTableField = dataSetTableFieldsService.get(dto.getId());
ChartViewFieldDTO d = new ChartViewFieldDTO();
BeanUtils.copyBean(d, datasetTableField);
ChartExtFilterRequest drillFilter = new ChartExtFilterRequest();
drillFilter.setFieldId(dto.getId());
drillFilter.setValue(new ArrayList<String>() {{
add(dto.getValue());
}});
drillFilter.setOperator("in");
drillFilter.setDatasetTableField(datasetTableField);
extFilterList.add(drillFilter);
drillFilters.add(drillFilter);
if (!checkDrillExist(xAxis, extStack, d, view)) {
xAxis.add(d);
}
if (i == drillRequest.size() - 1) {
ChartViewFieldDTO nextDrillField = drill.get(i + 1);
if (!checkDrillExist(xAxis, extStack, nextDrillField, view)) {
xAxis.add(nextDrillField);
}
}
}
}
}
}
// 获取数据集,需校验权限
DatasetTable table = dataSetTableService.get(view.getTableId());
if (ObjectUtils.isEmpty(table)) {
@ -263,11 +318,11 @@ public class ChartViewService {
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", 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));
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));
datasourceRequest.setQuery(qp.getSQLScatter(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, extBubble, ds));
} else {
datasourceRequest.setQuery(qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList));
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())) {
@ -316,11 +371,11 @@ public class ChartViewService {
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", 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));
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));
datasourceRequest.setQuery(qp.getSQLScatter(tableName, xAxis, yAxis, customFilter, extFilterList, extBubble, ds));
} else {
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList));
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList, ds));
}
/*// 定时抽取使用缓存
Object cache;
@ -339,7 +394,9 @@ public class ChartViewService {
data = (List<String[]>) cache;
}*/
// 仪表板有参数不实用缓存
if (CollectionUtils.isNotEmpty(requestList.getFilter())) {
if (CollectionUtils.isNotEmpty(requestList.getFilter())
|| CollectionUtils.isNotEmpty(requestList.getLinkageFilters())
|| CollectionUtils.isNotEmpty(requestList.getDrill())) {
data = datasourceProvider.getData(datasourceRequest);
} else {
try {
@ -362,16 +419,16 @@ public class ChartViewService {
// 图表组件可再扩展
Map<String, Object> mapChart;
if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
mapChart = transStackChartData(xAxis, yAxis, view, data, extStack);
mapChart = transStackChartData(xAxis, yAxis, view, data, extStack, isDrill);
} else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) {
mapChart = transScatterData(xAxis, yAxis, view, data, extBubble);
mapChart = transScatterData(xAxis, yAxis, view, data, extBubble, isDrill);
} else if (StringUtils.containsIgnoreCase(view.getType(), "radar")) {
mapChart = transRadarChartData(xAxis, yAxis, view, data);
mapChart = transRadarChartData(xAxis, yAxis, view, data, isDrill);
} else if (StringUtils.containsIgnoreCase(view.getType(), "text")
|| StringUtils.containsIgnoreCase(view.getType(), "gauge")) {
mapChart = transNormalChartData(xAxis, yAxis, view, data);
mapChart = transNormalChartData(xAxis, yAxis, view, data, isDrill);
} else {
mapChart = transChartData(xAxis, yAxis, view, data);
mapChart = transChartData(xAxis, yAxis, view, data, isDrill);
}
// table组件明细表也用于导出数据
Map<String, Object> mapTableNormal = transTableNormal(xAxis, yAxis, view, data, extStack);
@ -383,9 +440,30 @@ public class ChartViewService {
BeanUtils.copyBean(dto, view);
dto.setData(map);
dto.setSql(datasourceRequest.getQuery());
dto.setDrill(isDrill);
dto.setDrillFilters(drillFilters);
return dto;
}
private boolean checkDrillExist(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> extStack, ChartViewFieldDTO dto, ChartViewWithBLOBs view) {
if (CollectionUtils.isNotEmpty(xAxis)) {
for (ChartViewFieldDTO x : xAxis) {
if (StringUtils.equalsIgnoreCase(x.getId(), dto.getId())) {
return true;
}
}
}
if (StringUtils.containsIgnoreCase(view.getType(), "stack") && CollectionUtils.isNotEmpty(extStack)) {
for (ChartViewFieldDTO x : extStack) {
if (StringUtils.equalsIgnoreCase(x.getId(), dto.getId())) {
return true;
}
}
}
return false;
}
/**
* 避免缓存击穿
* 虽然流量不一定能够达到击穿的水平
@ -423,7 +501,7 @@ public class ChartViewService {
}
// 基础图形
private Map<String, Object> transChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data) {
private Map<String, Object> transChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, boolean isDrill) {
Map<String, Object> map = new HashMap<>();
List<String> x = new ArrayList<>();
@ -464,11 +542,15 @@ public class ChartViewService {
}
series.get(j).getData().add(axisChartDataDTO);
}
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
if (isDrill) {
a.append(d[xAxis.size() - 1]);
} else {
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
}
}
}
x.add(a.toString());
@ -480,7 +562,7 @@ public class ChartViewService {
}
// 常规图形
private Map<String, Object> transNormalChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data) {
private Map<String, Object> transNormalChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, boolean isDrill) {
Map<String, Object> map = new HashMap<>();
List<String> x = new ArrayList<>();
@ -494,11 +576,15 @@ public class ChartViewService {
}
for (String[] d : data) {
StringBuilder a = new StringBuilder();
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
if (isDrill) {
a.append(d[xAxis.size() - 1]);
} else {
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
}
}
}
x.add(a.toString());
@ -518,7 +604,7 @@ public class ChartViewService {
}
// radar图
private Map<String, Object> transRadarChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data) {
private Map<String, Object> transRadarChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, boolean isDrill) {
Map<String, Object> map = new HashMap<>();
List<String> x = new ArrayList<>();
@ -532,11 +618,15 @@ public class ChartViewService {
}
for (String[] d : data) {
StringBuilder a = new StringBuilder();
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
if (isDrill) {
a.append(d[xAxis.size() - 1]);
} else {
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
}
}
}
x.add(a.toString());
@ -556,7 +646,7 @@ public class ChartViewService {
}
// 堆叠图
private Map<String, Object> transStackChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, List<ChartViewFieldDTO> extStack) {
private Map<String, Object> transStackChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, List<ChartViewFieldDTO> extStack, boolean isDrill) {
Map<String, Object> map = new HashMap<>();
List<String> x = new ArrayList<>();
@ -570,11 +660,15 @@ public class ChartViewService {
// 构建横轴
for (String[] d : data) {
StringBuilder a = new StringBuilder();
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
if (isDrill) {
a.append(d[xAxis.size() - 1]);
} else {
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
}
}
}
x.add(a.toString());
@ -681,11 +775,15 @@ public class ChartViewService {
}
series.get(j).getData().add(axisChartDataDTO);
}
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
if (isDrill) {
a.append(d[xAxis.size() - 1]);
} else {
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
}
}
}
x.add(a.toString());
@ -698,7 +796,7 @@ public class ChartViewService {
}
// 散点图
private Map<String, Object> transScatterData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, List<ChartViewFieldDTO> extBubble) {
private Map<String, Object> transScatterData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, List<ChartViewFieldDTO> extBubble, boolean isDrill) {
Map<String, Object> map = new HashMap<>();
List<String> x = new ArrayList<>();
@ -714,11 +812,15 @@ public class ChartViewService {
String[] d = data.get(i1);
StringBuilder a = new StringBuilder();
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
if (isDrill) {
a.append(d[xAxis.size() - 1]);
} else {
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(d[i]);
} else {
a.append(d[i]).append("\n");
}
}
}
x.add(a.toString());

View File

@ -192,7 +192,7 @@ public class ExtractDataService {
dropDorisTable(DorisTableUtils.dorisTmpName(DorisTableUtils.dorisName(datasetTableId)));
} finally {
deleteFile("all_scope", datasetTableId);
deleteFile(new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getData());
// deleteFile(new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getData());
}
break;
@ -437,28 +437,28 @@ public class ExtractDataService {
String Column_Fields = "dataease_uuid varchar(50), `";
for (DatasetTableField datasetTableField : datasetTableFields) {
Column_Fields = Column_Fields + datasetTableField.getDataeaseName() + "` ";
Integer size = datasetTableField.getSize() * 3;
if (datasetTableField.getSize() > 65533 || datasetTableField.getSize() * 3 > 65533) {
size = 65533;
}
switch (datasetTableField.getDeExtractType()) {
case 0:
if (datasetTableField.getSize() > 65533 || datasetTableField.getSize() * 3 > 65533) {
Column_Fields = Column_Fields + "varchar(65533)" + ",`";
} else {
Column_Fields = Column_Fields + "varchar(lenth)".replace("lenth", String.valueOf(datasetTableField.getSize() * 3)) + ",`";
}
Column_Fields = Column_Fields + "varchar(lenth)".replace("lenth", String.valueOf(size)) + ",`";
break;
case 1:
Column_Fields = Column_Fields + "varchar(lenth)".replace("lenth", String.valueOf(datasetTableField.getSize())) + ",`";
Column_Fields = Column_Fields + "varchar(lenth)".replace("lenth", String.valueOf(size)) + ",`";
break;
case 2:
Column_Fields = Column_Fields + "bigint(lenth)".replace("lenth", String.valueOf(datasetTableField.getSize())) + ",`";
Column_Fields = Column_Fields + "bigint(lenth)".replace("lenth", String.valueOf(size)) + ",`";
break;
case 3:
Column_Fields = Column_Fields + "DOUBLE" + ",`";
break;
case 4:
Column_Fields = Column_Fields + "TINYINT(lenth)".replace("lenth", String.valueOf(datasetTableField.getSize())) + ",`";
Column_Fields = Column_Fields + "TINYINT(lenth)".replace("lenth", String.valueOf(size)) + ",`";
break;
default:
Column_Fields = Column_Fields + "varchar(lenth)".replace("lenth", String.valueOf(datasetTableField.getSize())) + ",`";
Column_Fields = Column_Fields + "varchar(lenth)".replace("lenth", String.valueOf(size)) + ",`";
break;
}
}
@ -735,6 +735,14 @@ public class ExtractDataService {
inputStep = inputStep(transMeta, selectSQL);
udjcStep = udjc(datasetTableFields, DatasourceTypes.sqlServer);
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());
transMeta.addDatabase(dataMeta);
selectSQL = getSelectSQL(extractType, datasetTable, datasource, datasetTableFields, selectSQL);
inputStep = inputStep(transMeta, selectSQL);
udjcStep = udjc(datasetTableFields, DatasourceTypes.pg);
break;
case oracle:
OracleConfigration oracleConfigration = new Gson().fromJson(datasource.getConfiguration(), OracleConfigration.class);
if (oracleConfigration.getConnectionType().equalsIgnoreCase("serviceName")) {
@ -795,7 +803,7 @@ public class ExtractDataService {
if (extractType.equalsIgnoreCase("all_scope") && datasetTable.getType().equalsIgnoreCase("db")) {
String tableName = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getTable();
QueryProvider qp = ProviderFactory.getQueryProvider(datasource.getType());
selectSQL = qp.createRawQuerySQL(tableName, datasetTableFields);
selectSQL = qp.createRawQuerySQL(tableName, datasetTableFields, datasource);
}
if (extractType.equalsIgnoreCase("all_scope") && datasetTable.getType().equalsIgnoreCase("sql")) {
@ -879,12 +887,18 @@ public class ExtractDataService {
outputFields[datasetTableFields.size()] = textFileField;
textFileOutputMeta.setOutputFields(outputFields);
}else if (datasource.getType().equalsIgnoreCase(DatasourceTypes.sqlServer.name())){
}else if (datasource.getType().equalsIgnoreCase(DatasourceTypes.sqlServer.name()) || datasource.getType().equalsIgnoreCase(DatasourceTypes.pg.name())){
TextFileField[] outputFields = new TextFileField[datasetTableFields.size() + 1];
for(int i=0;i< datasetTableFields.size();i++){
TextFileField textFileField = new TextFileField();
textFileField.setName(datasetTableFields.get(i).getDataeaseName());
textFileField.setType("String");
if (datasetTableFields.get(i).getDeExtractType() == 1) {
textFileField.setType("String");
textFileField.setFormat("yyyy-MM-dd HH:mm:ss");
} else {
textFileField.setType("String");
}
outputFields[i] = textFileField;
}
TextFileField textFileField = new TextFileField();
@ -936,7 +950,6 @@ public class ExtractDataService {
}
tmp_code = tmp_code.replace("handleBinaryType", handleBinaryTypeCode);
UserDefinedJavaClassDef userDefinedJavaClassDef = new UserDefinedJavaClassDef(UserDefinedJavaClassDef.ClassType.TRANSFORM_CLASS, "Processor", tmp_code);
userDefinedJavaClassDef.setActive(true);
@ -1019,13 +1032,13 @@ public class ExtractDataService {
}
}
private static String handleBinaryType = " \t\tif(\"FEILD\".equalsIgnoreCase(filed)){\n" +
private final static String handleBinaryType = " \t\tif(\"FEILD\".equalsIgnoreCase(filed)){\n" +
" get(Fields.Out, filed).setValue(r, \"\");\n" +
" get(Fields.Out, filed).getValueMeta().setType(2);\n" +
" \t}";
private static String alterColumnTypeCode = " if(\"FILED\".equalsIgnoreCase(filed)){\n" +
private final static String alterColumnTypeCode = " if(\"FILED\".equalsIgnoreCase(filed)){\n" +
"\t if(tmp != null && tmp.equalsIgnoreCase(\"Y\")){\n" +
" get(Fields.Out, filed).setValue(r, 1);\n" +
" get(Fields.Out, filed).getValueMeta().setType(2);\n" +
@ -1035,7 +1048,7 @@ public class ExtractDataService {
" }\n" +
" }\n";
private static String handleExcelIntColumn = " \t\tif(tmp != null && tmp.endsWith(\".0\")){\n" +
private final static String handleExcelIntColumn = " \t\tif(tmp != null && tmp.endsWith(\".0\")){\n" +
" try {\n" +
" Long.valueOf(tmp.substring(0, tmp.length()-2));\n" +
" get(Fields.Out, filed).setValue(r, tmp.substring(0, tmp.length()-2));\n" +
@ -1043,14 +1056,14 @@ public class ExtractDataService {
" }catch (Exception e){}\n" +
" }";
private static String handleWraps = " if(tmp != null && ( tmp.contains(\"\\r\") || tmp.contains(\"\\n\"))){\n" +
private final static String handleWraps = " if(tmp != null && ( tmp.contains(\"\\r\") || tmp.contains(\"\\n\"))){\n" +
"\t\t\ttmp = tmp.trim();\n" +
" tmp = tmp.replaceAll(\"\\r\",\" \");\n" +
" tmp = tmp.replaceAll(\"\\n\",\" \");\n" +
" get(Fields.Out, filed).setValue(r, tmp);\n" +
" } ";
private static String code = "import org.pentaho.di.core.row.ValueMetaInterface;\n" +
private final static String code = "import org.pentaho.di.core.row.ValueMetaInterface;\n" +
"import java.util.List;\n" +
"import java.io.File;\n" +
"import java.security.MessageDigest;\n" +

View File

@ -8,6 +8,7 @@ import io.dataease.base.mapper.PanelViewLinkageMapper;
import io.dataease.base.mapper.ext.ExtPanelViewLinkageMapper;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.controller.request.panel.PanelLinkageRequest;
import io.dataease.dto.LinkageInfoDTO;
import io.dataease.dto.PanelViewLinkageDTO;
import io.dataease.dto.PanelViewLinkageFieldDTO;
import org.apache.commons.collections4.CollectionUtils;
@ -89,19 +90,12 @@ public class PanelViewLinkageService {
});
}
}
}
public Map<String, List<String>> getPanelAllLinkageInfo(String panelId) {
List<LinkageInfoDTO> info = extPanelViewLinkageMapper.getPanelAllLinkageInfo(panelId);
return Optional.ofNullable(info).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(LinkageInfoDTO::getSourceInfo,LinkageInfoDTO::getTargetInfoList));
}
}

View File

@ -1,38 +1,38 @@
package io.dataease.service.sys;
import io.dataease.base.domain.SysRole;
/*import io.dataease.base.domain.SysRole;
import io.dataease.base.domain.SysUsersRolesExample;
import io.dataease.base.mapper.SysRoleMapper;
import io.dataease.base.mapper.SysUsersRolesMapper;
import io.dataease.base.mapper.SysUsersRolesMapper;*/
import io.dataease.base.mapper.ext.ExtSysRoleMapper;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.RoleMenusRequest;
/*import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.RoleMenusRequest;*/
import io.dataease.controller.sys.response.RoleUserItem;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/*import org.springframework.transaction.annotation.Transactional;*/
import javax.annotation.Resource;
import java.util.HashMap;
/*import java.util.HashMap;*/
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/*import java.util.Map;
import java.util.stream.Collectors;*/
@Service
public class SysRoleService {
@Resource
private SysRoleMapper mapper;
/*@Resource
private SysRoleMapper mapper;*/
@Resource
private ExtSysRoleMapper extSysRoleMapper;
@Resource
private SysUsersRolesMapper sysUsersRolesMapper;
/*@Resource
private SysUsersRolesMapper sysUsersRolesMapper;*/
public int add(SysRole role){
/*public int add(SysRole role){
Long now = System.currentTimeMillis();
role.setCreateTime(now);
role.setUpdateTime(now);
@ -77,7 +77,7 @@ public class SysRoleService {
return map;
}).collect(Collectors.toList());
return extSysRoleMapper.batchInsertRoleMenu(maps);
}
}*/
public List<RoleUserItem> allRoles(){
return extSysRoleMapper.queryAll();

View File

@ -28,7 +28,7 @@ knife4j.enable=true
knife4j.setting.enableFooter=false
knife4j.setting.enableFooterCustom=false
knife4j.setting.footerCustomContent=fit2cloud 1.0-b9
knife4j.setting.enableSwaggerModels=false
#knife4j.setting.enableSwaggerModels=false
knife4j.setting.enableDocumentManage=false
knife4j.setting.enableSearch=false
knife4j.setting.enableOpenApi=false

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
<title>DataEase</title>
</head>
<body style="height: 100%;">
<div id="nolic"></div>
</body>
</html>

View File

@ -18,3 +18,9 @@ export function saveLinkage(requestInfo) {
})
}
export function getPanelAllLinkageInfo(panelId) {
return request({
url: '/linkage/getPanelAllLinkageInfo/' + panelId,
method: 'get'
})
}

View File

@ -17,29 +17,29 @@ export function loadTable(data) {
})
}
export function addDept(data) {
return request({
url: '/api/dept/create',
method: 'post',
data
})
}
// export function addDept(data) {
// return request({
// url: '/api/dept/create',
// method: 'post',
// data
// })
// }
export function delDept(ids) {
return request({
url: '/api/dept/delete',
method: 'post',
data: ids
})
}
// export function delDept(ids) {
// return request({
// url: '/api/dept/delete',
// method: 'post',
// data: ids
// })
// }
export function editDept(data) {
return request({
url: '/api/dept/update',
method: 'post',
data
})
}
// export function editDept(data) {
// return request({
// url: '/api/dept/update',
// method: 'post',
// data
// })
// }
export function treeByDeptId(deptId) {
return request({
@ -48,4 +48,4 @@ export function treeByDeptId(deptId) {
})
}
export default { addDept, delDept, editDept, getDeptTree, loadTable, treeByDeptId }
// export default { addDept, delDept, editDept, getDeptTree, loadTable, treeByDeptId }

View File

@ -1,57 +1,57 @@
import request from '@/utils/request'
// import request from '@/utils/request'
export function allRoles() {
return request({
url: '/api/role/all',
method: 'post',
loading: true
})
}
// export function allRoles() {
// return request({
// url: '/api/user/all',
// method: 'post',
// loading: true
// })
// }
export function roleGrid(pageIndex, pageSize, data) {
return request({
url: '/api/role/roleGrid/' + pageIndex + '/' + pageSize,
method: 'post',
data,
loading: true
})
}
// export function roleGrid(pageIndex, pageSize, data) {
// return request({
// url: '/api/role/roleGrid/' + pageIndex + '/' + pageSize,
// method: 'post',
// data,
// loading: true
// })
// }
export function delRole(pid) {
return request({
url: '/api/role/delete/' + pid,
method: 'post'
})
}
// export function delRole(pid) {
// return request({
// url: '/api/role/delete/' + pid,
// method: 'post'
// })
// }
export function addRole(data) {
return request({
url: '/api/role/create',
method: 'post',
data
})
}
// export function addRole(data) {
// return request({
// url: '/api/role/create',
// method: 'post',
// data
// })
// }
export function editRole(data) {
return request({
url: '/api/role/update',
method: 'post',
data
})
}
// export function editRole(data) {
// return request({
// url: '/api/role/update',
// method: 'post',
// data
// })
// }
export function addRoleMenus(data) {
return request({
url: '/api/role/saveRolesMenus',
method: 'post',
data
})
}
// export function addRoleMenus(data) {
// return request({
// url: '/api/role/saveRolesMenus',
// method: 'post',
// data
// })
// }
export function menuIds(roleId) {
return request({
url: '/api/role/menuIds/' + roleId,
method: 'post'
})
}
export default { addRole, editRole, delRole, roleGrid, allRoles, addRoleMenus, menuIds }
// export function menuIds(roleId) {
// return request({
// url: '/api/role/menuIds/' + roleId,
// method: 'post'
// })
// }
// export default { addRole, editRole, delRole, roleGrid, allRoles, addRoleMenus, menuIds }

View File

@ -81,4 +81,12 @@ export const updatePersonPwd = (data) => {
})
}
export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd }
export const allRoles = () => {
return request({
url: '/api/user/all',
method: 'post',
loading: true
})
}
export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd, allRoles }

View File

@ -0,0 +1,49 @@
<template>
<div v-show="existLinkage" class="bar-main">
<div>
<el-button size="mini" type="info" @click="clearAllLinkage">清除所有联动</el-button>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
existLinkage() {
let linkageFiltersCount = 0
this.componentData.forEach(item => {
if (item.linkageFilters && item.linkageFilters.length > 0) {
linkageFiltersCount++
}
})
return linkageFiltersCount
},
...mapState([
'componentData'
])
},
methods: {
clearAllLinkage() {
this.$store.commit('clearPanelLinkageInfo')
}
}
}
</script>
<style lang="scss" scoped>
.bar-main{
position: absolute;
right: 0px;
z-index: 10;
height: 20px;
border-radius:2px;
padding-left: 5px;
padding-right: 2px;
cursor:pointer!important;
opacity: 0.8;
/*background-color: #0a7be0;*/
}
</style>

View File

@ -102,7 +102,6 @@ export default {
})
},
elementMouseDown(e) {
debugger
// private
this.$store.commit('setClickComponentStatus', true)
if (this.config.component !== 'v-text' && this.config.component !== 'rect-shape' && this.config.component !== 'de-input-search' && this.config.component !== 'de-number-range') {

View File

@ -3,6 +3,7 @@
<el-row v-if="componentDataShow.length===0" style="height: 100%;" class="custom-position">
{{ $t('panel.panelNull') }}
</el-row>
<canvas-opt-bar />
<ComponentWrapper
v-for="(item, index) in componentDataInfo"
:key="index"
@ -39,9 +40,10 @@ import { deepCopy } from '@/components/canvas/utils/utils'
import eventBus from '@/components/canvas/utils/eventBus'
import elementResizeDetectorMaker from 'element-resize-detector'
import UserViewDialog from '@/components/canvas/custom-component/UserViewDialog'
import CanvasOptBar from '@/components/canvas/components/Editor/CanvasOptBar'
export default {
components: { ComponentWrapper, UserViewDialog },
components: { ComponentWrapper, UserViewDialog, CanvasOptBar },
model: {
prop: 'show',
event: 'change'
@ -209,7 +211,6 @@ export default {
this.$refs['userViewDialog'].exportExcel()
},
deselectCurComponent(e) {
debugger
if (!this.isClickComponent) {
this.$store.commit('setCurComponent', { component: null, index: null })
}

View File

@ -0,0 +1,181 @@
<template>
<div>
<div style="width: 100%;">
<el-dropdown trigger="click" @mouseup="handleMouseUp">
<el-button ref="trackButton" class="icon iconfont icon-shezhi">TEST</el-button>
<el-dropdown-menu>
<el-dropdown-item icon="el-icon-document-copy" @click.native="copy">{{ $t('panel.copy') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" @click.native="deleteComponent">{{ $t('panel.delete') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-upload2" @click.native="topComponent">{{ $t('panel.topComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-download" @click.native="bottomComponent">{{ $t('panel.bottomComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-arrow-up" @click.native="upComponent">{{ $t('panel.upComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-arrow-down" @click.native="downComponent">{{ $t('panel.downComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-link" @click.native="linkageSetting">联动设置</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import bus from '@/utils/bus'
import { getViewLinkageGather } from '@/api/panel/linkage'
export default {
data() {
return {
copyData: null,
editFilter: [
'view',
'custom'
]
}
},
computed: mapState([
'menuTop',
'menuLeft',
'menuShow',
'curComponent',
'componentData',
'canvasStyleData'
]),
methods: {
trackButtonClick() {
this.$refs.trackButton.click()
this.$refs.trackButton.$el.click()
},
edit() {
//
this.$store.dispatch('panel/setComponentDataTemp', JSON.stringify(this.componentData))
this.$store.dispatch('panel/setCanvasStyleDataTemp', JSON.stringify(this.canvasStyleData))
if (this.curComponent.type === 'view') {
this.$store.dispatch('chart/setViewId', null)
this.$store.dispatch('chart/setViewId', this.curComponent.propValue.viewId)
bus.$emit('PanelSwitchComponent', { name: 'ChartEdit', param: { 'id': this.curComponent.propValue.viewId, 'optType': 'edit' }})
}
if (this.curComponent.type === 'custom') {
bus.$emit('component-dialog-edit')
}
//
if (this.curComponent.type === 'v-text' || this.curComponent.type === 'rect-shape') {
bus.$emit('component-dialog-style')
}
},
lock() {
this.$store.commit('lock')
},
unlock() {
this.$store.commit('unlock')
},
//
handleMouseUp() {
this.$store.commit('setClickComponentStatus', true)
},
cut() {
this.deleteCurCondition()
this.$store.commit('cut')
},
copy() {
this.$store.commit('copy')
this.paste()
},
paste() {
this.$store.commit('paste', true)
this.$store.commit('recordSnapshot')
},
deleteComponent() {
this.deleteCurCondition()
this.$store.commit('deleteComponent')
this.$store.commit('recordSnapshot')
this.$store.commit('setCurComponent', { component: null, index: null })
},
deleteCurCondition() {
if (this.curComponent.type === 'custom') {
this.$store.commit('removeViewFilter', this.curComponent.id)
bus.$emit('delete-condition', { componentId: this.curComponent.id })
}
},
upComponent() {
this.$store.commit('upComponent')
this.$store.commit('recordSnapshot')
},
downComponent() {
this.$store.commit('downComponent')
this.$store.commit('recordSnapshot')
},
topComponent() {
this.$store.commit('topComponent')
this.$store.commit('recordSnapshot')
},
bottomComponent() {
this.$store.commit('bottomComponent')
this.$store.commit('recordSnapshot')
},
linkageSetting() {
debugger
// sourceViewId
const targetViewIds = this.componentData.filter(item => item.type === 'view' && item.propValue && item.propValue.viewId)
.map(item => item.propValue.viewId)
//
const requestInfo = {
'panelId': this.$store.state.panel.panelInfo.id,
'sourceViewId': this.curComponent.propValue.viewId,
'targetViewIds': targetViewIds
}
getViewLinkageGather(requestInfo).then(rsp => {
this.$store.commit('setLinkageInfo', rsp.data)
})
}
}
}
</script>
<style lang="scss" scoped>
.contextmenu {
position: absolute;
z-index: 1000;
ul {
border: 1px solid #e4e7ed;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
box-sizing: border-box;
margin: 5px 0;
padding: 6px 0;
li {
font-size: 14px;
padding: 0 20px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #606266;
height: 34px;
line-height: 34px;
box-sizing: border-box;
cursor: pointer;
&:hover {
background-color: #f5f7fa;
}
}
}
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div>
<el-dropdown trigger="click">
<input id="input" ref="trackButton" type="button" hidden>
<el-dropdown-menu class="track-menu" :append-to-body="false">
<el-dropdown-item v-for="(item, key) in trackMenu" :key="key" @click.native="trackMenuClick(item)"><span class="menu-item">{{ i18n_map[item] }}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
export default {
props: {
trackMenu: {
type: Array,
required: true
}
},
data() {
return {
i18n_map: {
drill: this.$t('panel.drill'),
linkage: this.$t('panel.linkage')
}
}
},
computed: {
},
methods: {
trackButtonClick() {
this.$refs.trackButton.click()
},
trackMenuClick(menu) {
this.$emit('trackClick', menu)
}
}
}
</script>
<style lang="scss" scoped>
.menu-item {
font-size: 12px;
}
::v-deep ul {
width: 80px;
}
.track-menu {
border: #3a8ee6 1px solid;
}
</style>

View File

@ -9,6 +9,9 @@
>
<!-- 网格线 -->
<Grid v-if="canvasStyleData.auxiliaryMatrix&&!linkageSettingStatus" :matrix-style="matrixStyle" />
<!-- 仪表板联动清除按钮-->
<canvas-opt-bar />
<!--页面组件列表展示-->
<de-drag
v-for="(item, index) in componentData"
@ -156,8 +159,10 @@ import { changeStyleWithScale } from '@/components/canvas/utils/translate'
import { deepCopy } from '@/components/canvas/utils/utils'
import UserViewDialog from '@/components/canvas/custom-component/UserViewDialog'
import DeOutWidget from '@/components/dataease/DeOutWidget'
import CanvasOptBar from '@/components/canvas/components/Editor/CanvasOptBar'
export default {
components: { Shape, ContextMenu, MarkLine, Area, Grid, DeDrag, UserViewDialog, DeOutWidget },
components: { Shape, ContextMenu, MarkLine, Area, Grid, DeDrag, UserViewDialog, DeOutWidget, CanvasOptBar },
props: {
isEdit: {
type: Boolean,

View File

@ -101,8 +101,9 @@ import { commonStyle, commonAttr } from '@/components/canvas/custom-component/co
import eventBus from '@/components/canvas/utils/eventBus'
import { deepCopy } from '@/components/canvas/utils/utils'
import { panelSave } from '@/api/panel/panel'
import { saveLinkage } from '@/api/panel/linkage'
import { saveLinkage, getPanelAllLinkageInfo } from '@/api/panel/linkage'
import bus from '@/utils/bus'
import {
DEFAULT_COMMON_CANVAS_STYLE_STRING
} from '@/views/panel/panel'
@ -325,6 +326,10 @@ export default {
linkageInfo: this.targetLinkageInfo
}
saveLinkage(request).then(rsp => {
//
getPanelAllLinkageInfo(this.$store.state.panel.panelInfo.id).then(rsp => {
this.$store.commit('setNowPanelTrackInfo', rsp.data)
})
this.cancelLinkageSettingStatus()
})
},

View File

@ -16,9 +16,12 @@
{{ $t('chart.chart_error_tips') }}
</div>
</div>
<chart-component v-if="requestStatus==='success'&&chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :ref="element.propValue.id" class="chart-class" :chart="chart" />
<chart-component v-if="requestStatus==='success'&&chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :ref="element.propValue.id" class="chart-class" :chart="chart" :track-menu="trackMenu" @onChartClick="chartClick" />
<table-normal v-if="requestStatus==='success'&&chart.type && chart.type.includes('table')" :ref="element.propValue.id" :chart="chart" class="table-class" />
<label-normal v-if="requestStatus==='success'&&chart.type && chart.type.includes('text')" :ref="element.propValue.id" :chart="chart" class="table-class" />
<div style="position: absolute;left: 20px;bottom:14px;">
<drill-path :drill-filters="drillFilters" @onDrillJump="drillJump" />
</div>
</div>
</template>
@ -37,9 +40,11 @@ import { BASE_CHART_STRING } from '@/views/chart/chart/chart'
import eventBus from '@/components/canvas/utils/eventBus'
import { deepCopy } from '@/components/canvas/utils/utils'
import { getToken, getLinkToken } from '@/utils/auth'
import DrillPath from '@/views/chart/view/DrillPath'
export default {
name: 'UserView',
components: { ChartComponent, TableNormal, LabelNormal },
components: { ChartComponent, TableNormal, LabelNormal, DrillPath },
props: {
element: {
type: Object,
@ -77,13 +82,18 @@ export default {
refId: null,
chart: BASE_CHART_STRING,
requestStatus: 'waiting',
message: null
message: null,
drillClickDimensionList: [],
drillFilters: [],
drillFields: []
}
},
computed: {
filter() {
const filter = {}
filter.filter = this.element.filters
filter.linkageFilters = this.element.linkageFilters
filter.drill = this.drillClickDimensionList
return filter
},
filters() {
@ -91,8 +101,30 @@ export default {
if (!this.element.filters) return []
return JSON.parse(JSON.stringify(this.element.filters))
},
linkageFilters() {
// watch oldValuenewValue
if (!this.element.linkageFilters) return []
console.log('linkageFilters:' + JSON.stringify(this.element.linkageFilters))
return JSON.parse(JSON.stringify(this.element.linkageFilters))
},
trackMenu() {
const trackMenuInfo = []
let linkageCount = 0
this.chart.data.fields && this.chart.data.fields.forEach(item => {
const sourceInfo = this.chart.id + '#' + item.id
if (this.nowPanelTrackInfo[sourceInfo]) {
linkageCount++
}
})
linkageCount && trackMenuInfo.push('linkage')
this.drillFields.length && trackMenuInfo.push('drill')
console.log('trackMenuInfo' + JSON.stringify(trackMenuInfo))
return trackMenuInfo
},
...mapState([
'canvasStyleData'
'canvasStyleData',
'nowPanelTrackInfo'
])
},
@ -101,6 +133,13 @@ export default {
// this.getData(this.element.propValue.viewId)
isChange(val1, val2) && this.getData(this.element.propValue.viewId)
},
linkageFilters: {
handler(newVal, oldVal) {
debugger
isChange(newVal, oldVal) && this.getData(this.element.propValue.viewId)
},
deep: true
},
// deeppanel store
canvasStyleData: {
handler(newVal, oldVla) {
@ -176,6 +215,13 @@ export default {
// echart
if (response.success) {
this.chart = response.data
this.chart.drillFields = this.chart.drillFields ? JSON.parse(this.chart.drillFields) : []
debugger
if (!response.data.drill) {
this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1)
}
this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters))
this.drillFields = JSON.parse(JSON.stringify(response.data.drillFields))
this.requestStatus = 'merging'
this.mergeStyle()
this.requestStatus = 'success'
@ -210,6 +256,22 @@ export default {
tableChart.customAttr = JSON.stringify(tableChart.customAttr)
tableChart.customStyle = JSON.stringify(tableChart.customStyle)
eventBus.$emit('openChartDetailsDialog', { chart: this.chart, tableChart: tableChart })
},
chartClick(param) {
debugger
if (this.drillClickDimensionList.length < this.chart.drillFields.length - 1) {
this.drillClickDimensionList.push({ dimensionList: param.data.dimensionList })
this.getData(this.element.propValue.viewId)
}
},
resetDrill() {
this.drillClickDimensionList = []
},
drillJump(index) {
this.drillClickDimensionList = this.drillClickDimensionList.slice(0, index)
this.getData(this.element.propValue.viewId)
}
}
}

View File

@ -41,7 +41,6 @@ export default {
data.id = generateID()
// 如果是用户视图 测先进行底层复制
debugger
if (data.type === 'view') {
chartCopy(data.propValue.viewId).then(res => {
const newView = deepCopy(data)

View File

@ -837,7 +837,10 @@ export default {
drill: 'Drill',
drag_block_treemap_label: 'Color Label',
drag_block_treemap_size: 'Color Size',
bubble_symbol: 'Shape'
bubble_symbol: 'Shape',
gap_width: 'Gap Width',
width: 'Width',
height: 'Height'
},
dataset: {
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
@ -1176,7 +1179,9 @@ export default {
panel_save_tips: 'Do you want to save the changes you made to.',
panel_save_warn_tips: "Your changes will be lost if you don't save them",
do_not_save: "Don't Save",
save_and_close: 'Save'
save_and_close: 'Save',
drill: 'drill',
linkage: 'linkage'
},
plugin: {
local_install: 'Local installation',

View File

@ -837,7 +837,10 @@ export default {
drill: '鉆取',
drag_block_treemap_label: '色塊標簽',
drag_block_treemap_size: '色塊大小',
bubble_symbol: '圖形'
bubble_symbol: '圖形',
gap_width: '間隔',
width: '寬度',
height: '高度'
},
dataset: {
sheet_warn: '有多個sheet頁面默認抽取第一個',
@ -1176,7 +1179,9 @@ export default {
panel_save_tips: '仪表板已变动,是否保存?',
panel_save_warn_tips: '如果未保存,你对仪表板做的变更将会丢失!',
do_not_save: '不保存',
save: '保存'
save: '保存',
drill: '下钻',
linkage: '联动'
},
plugin: {
local_install: '本地安裝',

View File

@ -837,7 +837,10 @@ export default {
drill: '钻取',
drag_block_treemap_label: '色块标签',
drag_block_treemap_size: '色块大小',
bubble_symbol: '图形'
bubble_symbol: '图形',
gap_width: '间隔',
width: '宽度',
height: '高度'
},
dataset: {
sheet_warn: '有多个 Sheet 页,默认抽取第一个',
@ -1178,7 +1181,9 @@ export default {
panel_save_tips: '仪表板已变动,是否保存?',
panel_save_warn_tips: '如果未保存,你对仪表板做的变更将会丢失!',
do_not_save: '不保存',
save: '保存'
save: '保存',
drill: '下钻',
linkage: '联动'
},
plugin: {
local_install: '本地安装',

View File

@ -0,0 +1,16 @@
<template>
<div id="nolic" style="height:100%;">
<router-view />
</div>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,17 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/nolic/index.vue'),
meta: {
title: '首页'
}
}
]
})

View File

@ -0,0 +1,26 @@
import Vue from 'vue'
import Nolic from './Nolic.vue'
import router from './nolic-router'
import store from '../store'
import '@/styles/index.scss' // global css
import i18n from '../lang' // internationalization
import ElementUI from 'element-ui'
import '@/components/canvas/custom-component' // 注册自定义组件
import widgets from '@/components/widget'
import * as echarts from 'echarts'
import UmyUi from 'umy-ui'
Vue.use(UmyUi)
Vue.prototype.$echarts = echarts
Vue.config.productionTip = false
Vue.use(widgets)
Vue.use(ElementUI, {
i18n: (key, value) => i18n.t(key, value)
})
new Vue({
router,
store,
i18n,
render: h => h(Nolic)
}).$mount('#nolic')

View File

@ -21,7 +21,9 @@ import event from '@/components/canvas/store/event'
import layer from '@/components/canvas/store/layer'
import snapshot from '@/components/canvas/store/snapshot'
import lock from '@/components/canvas/store/lock'
import { valueValid, formatCondition } from '@/utils/conditionUtil'
import { valueValid, formatCondition, formatLinkageCondition } from '@/utils/conditionUtil'
import { Condition } from '@/components/widget/bean/Condition'
import {
DEFAULT_COMMON_CANVAS_STYLE_STRING
} from '@/views/panel/panel'
@ -54,7 +56,9 @@ const data = {
// 当前设置联动的组件
curLinkageView: null,
// 和当前组件联动的目标组件
targetLinkageInfo: []
targetLinkageInfo: [],
// 当前仪表板联动 下钻 上卷等信息
nowPanelTrackInfo: {}
},
mutations: {
...animation.mutations,
@ -154,6 +158,46 @@ const data = {
state.componentData[index] = element
}
},
// 添加联动 下钻 等过滤组件
addViewTrackFilter(state, data) {
const viewId = data.viewId
const trackInfo = state.nowPanelTrackInfo
for (let index = 0; index < state.componentData.length; index++) {
const element = state.componentData[index]
if (!element.type || element.type !== 'view') continue
const currentFilters = element.linkageFilters || [] // 当前联动filter
data.dimensionList.forEach(dimension => {
const sourceInfo = viewId + '#' + dimension.id
// 获取所有目标联动信息
const targetInfoList = trackInfo[sourceInfo] || []
targetInfoList.forEach(targetInfo => {
const targetInfoArray = targetInfo.split('#')
const targetViewId = targetInfoArray[0] // 目标视图
if (element.propValue.viewId === targetViewId) { // 如果目标视图 和 当前循环组件id相等 则进行条件增减
const targetFieldId = targetInfoArray[1] // 目标视图列ID
const condition = new Condition('', targetFieldId, 'eq', [dimension.value], [targetViewId])
let j = currentFilters.length
while (j--) {
const filter = currentFilters[j]
// 兼容性准备 viewIds 只会存放一个值
if (targetFieldId === filter.fieldId && filter.viewIds.includes(targetViewId)) {
currentFilters.splice(j, 1)
}
}
// 不存在该条件 且 条件有效 直接保存该条件
// !filterExist && vValid && currentFilters.push(condition)
currentFilters.push(condition)
}
})
})
element.linkageFilters = currentFilters
state.componentData[index] = element
}
},
setComponentWithId(state, component) {
for (let index = 0; index < state.componentData.length; index++) {
const element = state.componentData[index]
@ -189,6 +233,17 @@ const data = {
state.linkageSettingStatus = false
state.curLinkageView = null
state.targetLinkageInfo = []
},
setNowPanelTrackInfo(state, trackInfo) {
state.nowPanelTrackInfo = trackInfo
},
clearPanelLinkageInfo(state) {
state.componentData.forEach(item => {
if (item.linkageFilters && item.linkageFilters.length > 0) {
item.linkageFilters.splice(0, item.linkageFilters.length)
}
})
state.styleChangeTimes++
}
},
modules: {

View File

@ -3,9 +3,9 @@
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
@ -215,35 +215,35 @@
margin: 1em 0;
}
.markdown > p,
.markdown > blockquote,
.markdown > .highlight,
.markdown > ol,
.markdown > ul {
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul > li {
.markdown ul>li {
list-style: circle;
}
.markdown > ul li,
.markdown blockquote ul > li {
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown > ul li p,
.markdown > ol li p {
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol > li {
.markdown ol>li {
list-style: decimal;
}
.markdown > ol li,
.markdown blockquote ol > li {
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
@ -260,7 +260,7 @@
font-weight: 600;
}
.markdown > table {
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
@ -269,20 +269,20 @@
margin-bottom: 24px;
}
.markdown > table th {
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown > table th,
.markdown > table td {
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown > table th {
.markdown>table th {
background: #F7F7F7;
}
@ -318,8 +318,8 @@
display: inline-block;
}
.markdown > br,
.markdown > p > br {
.markdown>br,
.markdown>p>br {
clear: both;
}
@ -453,13 +453,13 @@ pre[class*="language-"] {
overflow: auto;
}
:not(pre) > code[class*="language-"],
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;

View File

@ -54,6 +54,48 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe973;</span>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">&amp;#xe973;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6ed;</span>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">&amp;#xe6ed;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6f7;</span>
<div class="name">联动</div>
<div class="code-name">&amp;#xe6f7;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe613;</span>
<div class="name">下钻</div>
<div class="code-name">&amp;#xe613;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe61f;</span>
<div class="name">上钻</div>
<div class="code-name">&amp;#xe61f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe637;</span>
<div class="name">取消联动</div>
<div class="code-name">&amp;#xe637;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe604;</span>
<div class="name">edit-2</div>
<div class="code-name">&amp;#xe604;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe612;</span>
<div class="name">edit-2</div>
@ -318,9 +360,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1627282547459') format('woff2'),
url('iconfont.woff?t=1627282547459') format('woff'),
url('iconfont.ttf?t=1627282547459') format('truetype');
src: url('iconfont.woff2?t=1628652979833') format('woff2'),
url('iconfont.woff?t=1628652979833') format('woff'),
url('iconfont.ttf?t=1628652979833') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -346,6 +388,69 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-quxiaoshangzuan"></span>
<div class="name">
线性图标-取消下钻
</div>
<div class="code-name">.icon-quxiaoshangzuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-quxiaoxiazuan"></span>
<div class="name">
线性图标-取消下钻
</div>
<div class="code-name">.icon-quxiaoxiazuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-linkage"></span>
<div class="name">
联动
</div>
<div class="code-name">.icon-linkage
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiazuan"></span>
<div class="name">
下钻
</div>
<div class="code-name">.icon-xiazuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shangzuan"></span>
<div class="name">
上钻
</div>
<div class="code-name">.icon-shangzuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-quxiaoliandong"></span>
<div class="name">
取消联动
</div>
<div class="code-name">.icon-quxiaoliandong
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-edit-outline"></span>
<div class="name">
edit-2
</div>
<div class="code-name">.icon-edit-outline
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-edit"></span>
<div class="name">
@ -742,6 +847,62 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaoshangzuan"></use>
</svg>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">#icon-quxiaoshangzuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaoxiazuan"></use>
</svg>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">#icon-quxiaoxiazuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-linkage"></use>
</svg>
<div class="name">联动</div>
<div class="code-name">#icon-linkage</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiazuan"></use>
</svg>
<div class="name">下钻</div>
<div class="code-name">#icon-xiazuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shangzuan"></use>
</svg>
<div class="name">上钻</div>
<div class="code-name">#icon-shangzuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaoliandong"></use>
</svg>
<div class="name">取消联动</div>
<div class="code-name">#icon-quxiaoliandong</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-edit-outline"></use>
</svg>
<div class="name">edit-2</div>
<div class="code-name">#icon-edit-outline</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-edit"></use>

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2459092 */
src: url('iconfont.woff2?t=1627282547459') format('woff2'),
url('iconfont.woff?t=1627282547459') format('woff'),
url('iconfont.ttf?t=1627282547459') format('truetype');
src: url('iconfont.woff2?t=1628652979833') format('woff2'),
url('iconfont.woff?t=1628652979833') format('woff'),
url('iconfont.ttf?t=1628652979833') format('truetype');
}
.iconfont {
@ -13,6 +13,34 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-quxiaoshangzuan:before {
content: "\e973";
}
.icon-quxiaoxiazuan:before {
content: "\e6ed";
}
.icon-linkage:before {
content: "\e6f7";
}
.icon-xiazuan:before {
content: "\e613";
}
.icon-shangzuan:before {
content: "\e61f";
}
.icon-quxiaoliandong:before {
content: "\e637";
}
.icon-edit-outline:before {
content: "\e604";
}
.icon-edit:before {
content: "\e612";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,55 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "23496077",
"name": "线性图标-取消下钻",
"font_class": "quxiaoshangzuan",
"unicode": "e973",
"unicode_decimal": 59763
},
{
"icon_id": "23005499",
"name": "线性图标-取消下钻",
"font_class": "quxiaoxiazuan",
"unicode": "e6ed",
"unicode_decimal": 59117
},
{
"icon_id": "8657066",
"name": "联动",
"font_class": "linkage",
"unicode": "e6f7",
"unicode_decimal": 59127
},
{
"icon_id": "12725578",
"name": "下钻",
"font_class": "xiazuan",
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "13006352",
"name": "上钻",
"font_class": "shangzuan",
"unicode": "e61f",
"unicode_decimal": 58911
},
{
"icon_id": "22983243",
"name": "取消联动",
"font_class": "quxiaoliandong",
"unicode": "e637",
"unicode_decimal": 58935
},
{
"icon_id": "5384479",
"name": "edit-2",
"font_class": "edit-outline",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "3684252",
"name": "edit-2",

View File

@ -30,3 +30,9 @@ export const formatCondition = obj => {
const condition = new Condition(component.id, fieldId, operator, value, viewIds)
return condition
}
export const formatLinkageCondition = obj => {
const { viewIds, fieldId, value, operator } = obj
const condition = new Condition(null, fieldId, operator, value, viewIds)
return condition
}

View File

@ -39,7 +39,9 @@ export const DEFAULT_SIZE = {
dimensionShow: true,
quotaShow: true,
scatterSymbol: 'circle',
scatterSymbolSize: 20
scatterSymbolSize: 20,
treemapWidth: 80,
treemapHeight: 80
}
export const DEFAULT_LABEL = {
show: false,
@ -623,7 +625,7 @@ export const BASE_MAP = {
{
name: '',
type: 'map',
map: 'HK',
map: 'MAP',
roam: true,
// label: {
// show: true

View File

@ -33,16 +33,22 @@ export function baseMapOption(chart_option, chart) {
}
// visualMap
const valueArr = chart.data.series[0].data
chart_option.visualMap.min = Math.min(...valueArr)
chart_option.visualMap.max = Math.max(...valueArr)
const values = []
valueArr.forEach(function(ele) {
values.push(ele.value)
})
chart_option.visualMap.min = Math.min(...values)
chart_option.visualMap.max = Math.max(...values)
if (customAttr.color && customAttr.color.colors) {
chart_option.visualMap.inRange.color = customAttr.color.colors
}
for (let i = 0; i < valueArr.length; i++) {
const y = {
name: chart.data.x[i],
value: valueArr[i]
}
// const y = {
// name: chart.data.x[i],
// value: valueArr[i]
// }
const y = valueArr[i]
y.name = chart.data.x[i]
// color
// y.itemStyle = {
// color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha),

View File

@ -24,12 +24,13 @@ export function baseTreemapOption(chart_option, chart) {
// chart_option.series[0].name = chart.data.series[0].name
// size
if (customAttr.size) {
// chart_option.series[0].radius = [customAttr.size.pieInnerRadius + '%', customAttr.size.pieOuterRadius + '%']
chart_option.series[0].width = (customAttr.size.treemapWidth ? customAttr.size.treemapWidth : 80) + '%'
chart_option.series[0].height = (customAttr.size.treemapHeight ? customAttr.size.treemapHeight : 80) + '%'
}
// label
if (customAttr.label) {
// chart_option.series[0].label = customAttr.label
}
// if (customAttr.label) {
// chart_option.series[0].label = customAttr.label
// }
const valueArr = chart.data.series[0].data
for (let i = 0; i < valueArr.length; i++) {
// const y = {

View File

@ -1,5 +1,6 @@
<template>
<div style="display: flex;">
<view-track-bar ref="viewTrack" :track-menu="trackMenu" class="track-bar" :style="trackBarStyleTime" @trackClick="trackClick" />
<div :id="chartId" style="width: 100%;height: 100%;" />
</div>
</template>
@ -18,9 +19,11 @@ import { baseTreemapOption } from '../chart/treemap/treemap'
// import eventBus from '@/components/canvas/utils/eventBus'
import { uuid } from 'vue-uuid'
import { geoJson } from '@/api/map/map'
import ViewTrackBar from '@/components/canvas/components/Editor/ViewTrackBar'
export default {
name: 'ChartComponent',
components: { ViewTrackBar },
props: {
chart: {
type: Object,
@ -32,13 +35,33 @@ export default {
default: function() {
return {}
}
},
trackMenu: {
type: Array,
required: false,
default: function() {
return ['drill']
}
}
},
data() {
return {
myChart: {},
chartId: uuid.v1(),
currentGeoJson: null
currentGeoJson: null,
showTrackBar: true,
trackBarStyle: {
position: 'absolute',
left: '0px',
top: '0px'
},
pointParam: null
}
},
computed: {
trackBarStyleTime() {
return this.trackBarStyle
}
},
watch: {
@ -62,6 +85,7 @@ export default {
preDraw() {
// domecharts
// echartdom,idechart id
const that = this
new Promise((resolve) => { resolve() }).then(() => {
// domechartsdom
this.myChart = this.$echarts.getInstanceByDom(document.getElementById(this.chartId))
@ -69,6 +93,18 @@ export default {
this.myChart = this.$echarts.init(document.getElementById(this.chartId))
}
this.drawEcharts()
this.myChart.off('click')
this.myChart.on('click', function(param) {
that.pointParam = param
if (that.trackMenu.length < 2) { //
that.trackClick(that.trackMenu[0])
} else { //
that.trackBarStyle.left = param.event.offsetX + 'px'
that.trackBarStyle.top = (param.event.offsetY - 15) + 'px'
that.$refs.viewTrack.trackButtonClick()
}
})
})
},
drawEcharts() {
@ -136,7 +172,7 @@ export default {
},
initMapChart(geoJson, chart) {
// this.$echarts.registerMap('HK', geoJson)
this.$echarts.getMap('HK') || this.$echarts.registerMap('HK', geoJson)
this.$echarts.getMap('MAP') || this.$echarts.registerMap('MAP', geoJson)
const base_json = JSON.parse(JSON.stringify(BASE_MAP))
const chart_option = baseMapOption(base_json, chart)
this.myEcharts(chart_option)
@ -153,6 +189,23 @@ export default {
//
const chart = this.myChart
chart.resize()
},
trackClick(trackAction) {
const linkageParam = {
viewId: this.chart.id,
dimensionList: this.pointParam.data.dimensionList,
quotaList: this.pointParam.data.quotaList
}
switch (trackAction) {
case 'drill':
this.$emit('onChartClick', this.pointParam)
break
case 'linkage':
this.$store.commit('addViewTrackFilter', linkageParam)
break
default:
break
}
}
}
}

View File

@ -151,6 +151,15 @@
<el-slider v-model="sizeForm.scatterSymbolSize" show-input :show-input-controls="false" input-size="mini" :min="1" :max="20" @change="changeBarSizeCase" />
</el-form-item>
</el-form>
<el-form v-show="chart.type && chart.type === 'treemap'" ref="sizeFormLine" :disabled="param && !hasDataPermission('manage',param.privileges)" :model="sizeForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.width')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.treemapWidth" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" />
</el-form-item>
<el-form-item :label="$t('chart.height')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.treemapHeight" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" />
</el-form-item>
</el-form>
</el-col>
<!-- <el-popover-->
<!-- placement="right"-->
@ -353,6 +362,8 @@ export default {
}
if (customAttr.size) {
this.sizeForm = customAttr.size
this.sizeForm.treemapWidth = this.sizeForm.treemapWidth ? this.sizeForm.treemapWidth : 80
this.sizeForm.treemapHeight = this.sizeForm.treemapHeight ? this.sizeForm.treemapHeight : 80
}
}
},

View File

@ -247,30 +247,6 @@
/>
</span>
</el-row>
<el-row class="padding-lr">
<span style="width: 80px;text-align: right;">
<span>{{ $t('chart.drill') }}</span>
/
<span>{{ $t('chart.dimension') }}</span>
</span>
<draggable
v-model="view.drillFields"
:disabled="!hasDataPermission('manage',param.privileges)"
group="drag"
animation="300"
:move="onMove"
class="drag-block-style"
@add="addDrill"
@update="save(true)"
>
<transition-group class="draggable-group">
<drill-item v-for="(item,index) in view.drillFields" :key="item.id" :param="param" :index="index" :item="item" @onDimensionItemChange="drillItemChange" @onDimensionItemRemove="drillItemRemove" />
</transition-group>
</draggable>
<div v-if="!view.drillFields || view.drillFields.length === 0" class="drag-placeholder-style">
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
<el-row v-if="view.type !=='text' && view.type !== 'gauge'" class="padding-lr">
<span style="width: 80px;text-align: right;">
<span v-if="view.type && view.type.includes('table')">{{ $t('chart.drag_block_table_data_column') }}</span>
@ -404,6 +380,30 @@
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
<el-row v-if="view.type && view.type !== 'treemap' && !view.type.includes('table') && !view.type.includes('text') && !view.type.includes('radar') && !view.type.includes('gauge')" class="padding-lr" style="margin-top: 6px;">
<span style="width: 80px;text-align: right;">
<span>{{ $t('chart.drill') }}</span>
/
<span>{{ $t('chart.dimension') }}</span>
</span>
<draggable
v-model="view.drillFields"
:disabled="!hasDataPermission('manage',param.privileges)"
group="drag"
animation="300"
:move="onMove"
class="drag-block-style"
@add="addDrill"
@update="save(true)"
>
<transition-group class="draggable-group">
<drill-item v-for="(item,index) in view.drillFields" :key="item.id" :param="param" :index="index" :item="item" @onDimensionItemChange="drillItemChange" @onDimensionItemRemove="drillItemRemove" />
</transition-group>
</draggable>
<div v-if="!view.drillFields || view.drillFields.length === 0" class="drag-placeholder-style">
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
</div>
</el-row>
</el-row>
</div>
</el-col>
@ -427,7 +427,7 @@
<el-collapse-item name="color" :title="$t('chart.color')">
<color-selector :param="param" class="attr-selector" :chart="chart" @onColorChange="onColorChange" />
</el-collapse-item>
<el-collapse-item v-show="chart.type !== 'map' && chart.type !== 'treemap'" name="size" :title="$t('chart.size')">
<el-collapse-item v-show="chart.type !== 'map'" name="size" :title="$t('chart.size')">
<size-selector :param="param" class="attr-selector" :chart="chart" @onSizeChange="onSizeChange" />
</el-collapse-item>
<el-collapse-item v-show="!view.type.includes('table') && !view.type.includes('text') && view.type !== 'treemap'" name="label" :title="$t('chart.label')">
@ -483,7 +483,7 @@
<el-col style="height: 100%;min-width: 500px;border-top: 1px solid #E6E6E6;">
<el-row style="width: 100%;height: 100%;" class="padding-lr">
<div ref="imageWrapper" style="height: 100%">
<chart-component v-if="httpRequest.status && chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :chart-id="chart.id" :chart="chart" class="chart-class" />
<chart-component v-if="httpRequest.status && chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :chart-id="chart.id" :chart="chart" class="chart-class" @onChartClick="chartClick" />
<table-normal v-if="httpRequest.status && chart.type && chart.type.includes('table')" :chart="chart" class="table-class" />
<label-normal v-if="httpRequest.status && chart.type && chart.type.includes('text')" :chart="chart" class="table-class" />
<div v-if="!httpRequest.status" class="chart-error-class">
@ -494,6 +494,9 @@
</div>
</div>
</div>
<div style="position: absolute;left: 20px;bottom:14px;">
<drill-path :drill-filters="drillFilters" @onDrillJump="drillJump" />
</div>
</el-row>
</el-col>
</el-row>
@ -603,6 +606,7 @@ import ChartDragItem from '../components/drag-item/ChartDragItem'
import DrillItem from '../components/drag-item/DrillItem'
import ResultFilterEditor from '../components/filter/ResultFilterEditor'
import ChartComponent from '../components/ChartComponent'
import DrillPath from '@/views/chart/view/DrillPath'
import bus from '@/utils/bus'
import DatasetChartDetail from '../../dataset/common/DatasetChartDetail'
// shape attr,component style
@ -663,7 +667,8 @@ export default {
DimensionItem,
draggable,
ChartDragItem,
DrillItem
DrillItem,
DrillPath
},
props: {
param: {
@ -738,7 +743,9 @@ export default {
filterItem: {},
places: [],
attrActiveNames: [],
styleActiveNames: []
styleActiveNames: [],
drillClickDimensionList: [],
drillFilters: []
}
},
computed: {
@ -750,6 +757,7 @@ export default {
},
watch: {
'param': function() {
this.resetDrill()
if (this.param.optType === 'new') {
//
} else {
@ -877,6 +885,13 @@ export default {
if (view.type === 'treemap' && trigger === 'chart') {
view.customAttr.label.show = true
}
if (view.type === 'treemap' ||
view.type.includes('table') ||
view.type.includes('text') ||
view.type.includes('gauge') ||
view.type.includes('radar')) {
view.drillFields = []
}
view.customFilter.forEach(function(ele) {
if (ele && !ele.filter) {
ele.filter = []
@ -894,6 +909,7 @@ export default {
// this.get(response.data.id);
// this.getData(response.data.id)
this.resetDrill()
if (getData) {
this.getData(response.data.id)
} else {
@ -983,7 +999,8 @@ export default {
getData(id) {
if (id) {
ajaxGetData(id, {
filter: []
filter: [],
drill: this.drillClickDimensionList
}).then(response => {
this.initTableData(response.data.tableId)
this.view = JSON.parse(JSON.stringify(response.data))
@ -1003,8 +1020,13 @@ export default {
if (this.chart.privileges) {
this.param.privileges = this.chart.privileges
}
if (!response.data.drill) {
this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1)
}
this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters))
}).catch(err => {
this.resetView()
this.resetDrill()
this.httpRequest.status = err.response.data.success
this.httpRequest.msg = err.response.data.message
this.$nextTick(() => {
@ -1487,6 +1509,21 @@ export default {
bubbleItemRemove(item) {
this.view.extBubble.splice(item.index, 1)
this.save(true)
},
chartClick(param) {
if (this.drillClickDimensionList.length < this.view.drillFields.length - 1) {
this.drillClickDimensionList.push({ dimensionList: param.data.dimensionList })
this.getData(this.param.id)
}
},
resetDrill() {
this.drillClickDimensionList = []
},
drillJump(index) {
this.drillClickDimensionList = this.drillClickDimensionList.slice(0, index)
this.getData(this.param.id)
}
}
}

View File

@ -0,0 +1,47 @@
<template>
<div v-if="drillFilters && drillFilters.length > 0">
<el-breadcrumb separator-class="el-icon-arrow-right" class="drill-style">
<el-breadcrumb-item class="drill-item" @click.native="drillJump(0)">{{ $t('commons.all') }}</el-breadcrumb-item>
<el-breadcrumb-item v-for="(filter,index) in drillFilters" :key="index" class="drill-item" @click.native="drillJump(index + 1)">{{ filter.value[0] }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default {
name: 'DrillPath',
props: {
drillFilters: {
type: Array,
required: true
}
},
data() {
return {
}
},
watch: {
},
mounted() {
},
methods: {
drillJump(index) {
if (index < this.drillFilters.length) {
this.$emit('onDrillJump', index)
}
}
}
}
</script>
<style scoped>
.drill-style {
font-size: 12px;
}
.drill-style >>> .el-breadcrumb__separator{
margin: 0!important;
}
.drill-item{
cursor: pointer;
}
</style>

Some files were not shown because too many files have changed in this diff Show More