diff --git a/.gitignore b/.gitignore index 3d31f5c62e..7647865be8 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,7 @@ target/ .DS_Store node_modules /dist - +node/ # local env files .env.demo @@ -47,5 +47,10 @@ pnpm-debug.log* *.njsproj *.sln *.sw? +*.lock +*.classpath +*.project +.settings/ + package-lock.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..da05358bd4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM registry.fit2cloud.com/fit2cloud3/fabric8-java-alpine-openjdk8-jre + +ARG IMAGE_TAG + +RUN mkdir -p /opt/apps + +ADD backend/target/backend-1.0.jar /opt/apps + +ENV JAVA_APP_JAR=/opt/apps/backend-1.0.jar + +ENV AB_OFF=true + +ENV JAVA_OPTIONS=-Dfile.encoding=utf-8 + +HEALTHCHECK --interval=15s --timeout=5s --retries=20 --start-period=30s CMD curl -f 127.0.0.1:8081 + +CMD ["/deployments/run-java.sh"] diff --git a/backend/pom.xml b/backend/pom.xml index c814656394..80a883c497 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -303,17 +303,6 @@ reflections8 0.11.7 - - org.springframework.boot @@ -325,6 +314,25 @@ ehcache 2.9.1 + + + org.apache.hbase + hbase-client + 2.4.1 + + + org.apache.hbase + hbase-common + 2.4.1 + + + + org.testng + testng + 6.8 + test + + @@ -430,6 +438,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/main/java/io/dataease/auth/config/F2CRealm.java b/backend/src/main/java/io/dataease/auth/config/F2CRealm.java index 4dee2a8df7..5d686c2abe 100644 --- a/backend/src/main/java/io/dataease/auth/config/F2CRealm.java +++ b/backend/src/main/java/io/dataease/auth/config/F2CRealm.java @@ -13,8 +13,9 @@ import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import javax.annotation.Resource; import java.util.Set; import java.util.stream.Collectors; @@ -23,7 +24,8 @@ import java.util.stream.Collectors; @Component public class F2CRealm extends AuthorizingRealm { - @Resource + @Autowired + @Lazy //shiro组件加载过早 让authUserService等一等再注入 否则 注入的可能不是代理对象 private AuthUserService authUserService; @@ -36,7 +38,6 @@ public class F2CRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { Long userId = JWTUtils.tokenInfoByToken(principals.toString()).getUserId(); - //SysUserEntity user = authUserService.getUserById(userId); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); Set role = authUserService.roles(userId).stream().collect(Collectors.toSet()); simpleAuthorizationInfo.addRoles(role); diff --git a/backend/src/main/java/io/dataease/auth/config/WhitelistConfig.java b/backend/src/main/java/io/dataease/auth/config/WhitelistConfig.java new file mode 100644 index 0000000000..357222cc20 --- /dev/null +++ b/backend/src/main/java/io/dataease/auth/config/WhitelistConfig.java @@ -0,0 +1,17 @@ +package io.dataease.auth.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +@Configuration +@ConfigurationProperties(prefix = "dataease") +@Data +public class WhitelistConfig { + + private List whitelist; + + +} diff --git a/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java b/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java index 7a0602d105..314803d371 100644 --- a/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java +++ b/backend/src/main/java/io/dataease/auth/filter/JWTFilter.java @@ -6,6 +6,9 @@ import io.dataease.auth.entity.TokenInfo; import io.dataease.auth.service.AuthUserService; import io.dataease.auth.util.JWTUtils; import io.dataease.commons.utils.CommonBeanFactory; +import io.dataease.commons.utils.ServletUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; import org.slf4j.Logger; @@ -23,6 +26,8 @@ public class JWTFilter extends BasicHttpAuthenticationFilter { private Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + public final static String expireMessage = "login token is expire"; + /*@Autowired private AuthUserService authUserService;*/ @@ -45,7 +50,10 @@ public class JWTFilter extends BasicHttpAuthenticationFilter { protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String authorization = httpServletRequest.getHeader("Authorization"); - + // 当没有出现登录超时 且需要刷新token 则执行刷新token + if (JWTUtils.loginExpire(authorization)){ + throw new AuthenticationException(expireMessage); + } if (JWTUtils.needRefresh(authorization)){ authorization = refreshToken(request, response); } @@ -67,7 +75,12 @@ public class JWTFilter extends BasicHttpAuthenticationFilter { boolean loginSuccess = executeLogin(request, response); return loginSuccess; } catch (Exception e) { - response401(request, response); + if (e instanceof AuthenticationException && StringUtils.equals(e.getMessage(), expireMessage)){ + responseExpire(request, response); + }else { + response401(request, response); + } + } } return false; @@ -81,7 +94,13 @@ public class JWTFilter extends BasicHttpAuthenticationFilter { AuthUserService authUserService = CommonBeanFactory.getBean(AuthUserService.class); SysUserEntity user = authUserService.getUserById(tokenInfo.getUserId()); String password = user.getPassword(); + + // 删除老token操作时间 + JWTUtils.removeTokenExpire(token); String newToken = JWTUtils.sign(tokenInfo, password); + // 记录新token操作时间 + JWTUtils.addTokenExpire(newToken); + JWTToken jwtToken = new JWTToken(newToken); this.getSubject(request, response).login(jwtToken); // 设置响应的Header头新Token @@ -123,4 +142,16 @@ public class JWTFilter extends BasicHttpAuthenticationFilter { LOGGER.error(e.getMessage()); } } + + private void responseExpire(ServletRequest req, ServletResponse resp) { + try { + HttpServletResponse httpServletResponse = (HttpServletResponse) resp; + httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status"); + httpServletResponse.setHeader("authentication-status", "login_expire"); + httpServletResponse.setStatus(401); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + } diff --git a/backend/src/main/java/io/dataease/auth/server/AuthServer.java b/backend/src/main/java/io/dataease/auth/server/AuthServer.java index bdb56b337b..474e013a69 100644 --- a/backend/src/main/java/io/dataease/auth/server/AuthServer.java +++ b/backend/src/main/java/io/dataease/auth/server/AuthServer.java @@ -49,6 +49,8 @@ public class AuthServer implements AuthApi { Map result = new HashMap<>(); TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).lastLoginTime(System.currentTimeMillis()).build(); String token = JWTUtils.sign(tokenInfo, realPwd); + // 记录token操作时间 + JWTUtils.addTokenExpire(token); result.put("token", token); ServletUtils.setToken(token); return result; @@ -79,6 +81,9 @@ public class AuthServer implements AuthApi { @Override public String test() { + SysUserEntity userById = authUserService.getUserById(4L); + String nickName = userById.getNickName(); + System.out.println(nickName); return "apple"; } } diff --git a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java index f8ffd69827..53894c4e8d 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java @@ -1,17 +1,22 @@ package io.dataease.auth.service.impl; +import io.dataease.auth.config.WhitelistConfig; import io.dataease.auth.service.ShiroService; +import org.apache.commons.collections.CollectionUtils; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; - -import javax.annotation.Resource; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.StringJoiner; @Service public class ShiroServiceImpl implements ShiroService { + + private final static String ANON = "anon"; + + @Autowired + private WhitelistConfig whitelistConfig; @Override public Map loadFilterChainDefinitionMap() { @@ -20,47 +25,38 @@ public class ShiroServiceImpl implements ShiroService { // 配置过滤:不会被拦截的链接 -> 放行 start ---------------------------------------------------------- // 放行Swagger2页面,需要放行这些 - filterChainDefinitionMap.put("/swagger-ui.html","anon"); - filterChainDefinitionMap.put("/swagger-ui/**","anon"); - - filterChainDefinitionMap.put("/swagger/**","anon"); - filterChainDefinitionMap.put("/webjars/**", "anon"); - filterChainDefinitionMap.put("/swagger-resources/**","anon"); - filterChainDefinitionMap.put("/v2/**","anon"); - filterChainDefinitionMap.put("/v3/**","anon"); - filterChainDefinitionMap.put("/static/**", "anon"); - filterChainDefinitionMap.put("/common-files/**", "anon"); - - - // filterChainDefinitionMap.put("/401", "anon"); - // filterChainDefinitionMap.put("/404", "anon"); - // 登陆 - // filterChainDefinitionMap.put("/api/auth/logout", "anon"); - filterChainDefinitionMap.put("/api/auth/login", "anon"); - // 退出 - - // 放行未授权接口,重定向使用 - filterChainDefinitionMap.put("/unauth", "anon"); - filterChainDefinitionMap.put("/display/**", "anon"); - - // token过期接口 - filterChainDefinitionMap.put("/tokenExpired", "anon"); - // 被挤下线 - filterChainDefinitionMap.put("/downline", "anon"); - // 放行 end ---------------------------------------------------------- - - /*List extPermissionBeans = extUserMapper.getPermissions(); - - extPermissionBeans.forEach(item -> { - StringJoiner f2cPerms = new StringJoiner(",", "f2cPerms[", "]"); - f2cPerms.add(item.getPermission()); - filterChainDefinitionMap.put(item.getPath(), "jwt," + f2cPerms); + filterChainDefinitionMap.put("/swagger-ui.html",ANON); + filterChainDefinitionMap.put("/swagger-ui/**",ANON); + filterChainDefinitionMap.put("/swagger/**",ANON); + filterChainDefinitionMap.put("/webjars/**", ANON); + filterChainDefinitionMap.put("/swagger-resources/**",ANON); + filterChainDefinitionMap.put("/v2/**",ANON); + filterChainDefinitionMap.put("/v3/**",ANON); + filterChainDefinitionMap.put("/static/**", ANON); + filterChainDefinitionMap.put("/css/**", ANON); + filterChainDefinitionMap.put("/js/**", ANON); + filterChainDefinitionMap.put("/img/**", ANON); + filterChainDefinitionMap.put("/fonts/**", ANON); + filterChainDefinitionMap.put("/favicon.ico", ANON); + filterChainDefinitionMap.put("/", ANON); + filterChainDefinitionMap.put("/index.html", ANON); + filterChainDefinitionMap.put("/api/auth/login", ANON); + filterChainDefinitionMap.put("/unauth", ANON); + filterChainDefinitionMap.put("/display/**", ANON); + filterChainDefinitionMap.put("/tokenExpired", ANON); + filterChainDefinitionMap.put("/downline", ANON); + List whitelist = whitelistConfig.getWhitelist(); + if (CollectionUtils.isNotEmpty(whitelist)) + whitelist.forEach(path -> { + filterChainDefinitionMap.put(path, ANON); }); -*/ + filterChainDefinitionMap.put("/api/auth/logout", "logout"); filterChainDefinitionMap.put("/**", "jwt"); return filterChainDefinitionMap; } + + @Override public void updatePermission(ShiroFilterFactoryBean shiroFilterFactoryBean, Integer roleId, Boolean isRemoveSession) { diff --git a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java index 32b20022a7..b43ae98bd3 100644 --- a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java +++ b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java @@ -6,20 +6,23 @@ import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.DecodedJWT; import io.dataease.auth.entity.TokenInfo; -import io.dataease.commons.utils.ServletUtils; +import io.dataease.auth.filter.JWTFilter; +import io.dataease.commons.utils.CommonBeanFactory; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import javax.servlet.http.HttpServletResponse; +import org.apache.shiro.authc.AuthenticationException; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; import java.util.Date; public class JWTUtils { - // token过期时间5min (过期会自动刷新续命 目的是避免一直都是同一个token ) - private static final long EXPIRE_TIME = 1*60*1000; + // token过期时间1min (过期会自动刷新续命 目的是避免一直都是同一个token ) + private static final long EXPIRE_TIME = 1*60*1000/2; // 登录间隔时间10min 超过这个时间强制重新登录 - private static final long Login_Interval = 10*60*1000; + private static final long Login_Interval = 20*60*1000; /** @@ -35,16 +38,12 @@ public class JWTUtils { .withClaim("username", tokenInfo.getUsername()) .withClaim("userId", tokenInfo.getUserId()) .build(); - DecodedJWT jwt = verifier.verify(token); - Long lastLoginTime = jwt.getClaim("lastLoginTime").asLong(); - long now = System.currentTimeMillis(); - if (now - lastLoginTime > Login_Interval){ + verifier.verify(token); + if (loginExpire(token)){ // 登录超时 - HttpServletResponse response = ServletUtils.response(); - response.addHeader("Access-Control-Expose-Headers", "authentication-status"); - response.setHeader("authentication-status", "login_expire"); + throw new AuthenticationException(JWTFilter.expireMessage); // 前端拦截 登录超时状态 直接logout - return false; + //return false; } return true; } @@ -74,6 +73,17 @@ public class JWTUtils { return new Date().getTime() >= exp.getTime(); } + /** + * 当前token是否登录超时 + * @param token + * @return + */ + public static boolean loginExpire(String token){ + Long now = System.currentTimeMillis(); + Long lastOperateTime = tokenLastOperateTime(token); + return now - lastOperateTime > Login_Interval; + } + public static Date getExp(String token) { try { DecodedJWT jwt = JWT.decode(token); @@ -106,4 +116,29 @@ public class JWTUtils { return null; } } + + /** + * 获取当前token上次操作时间 + * @param token + * @return + */ + public static Long tokenLastOperateTime(String token){ + CacheManager cacheManager = CommonBeanFactory.getBean(CacheManager.class); + Cache tokens_expire = cacheManager.getCache("tokens_expire"); + Long expTime = tokens_expire.get(token, Long.class); + return expTime; + } + + public static void removeTokenExpire(String token){ + CacheManager cacheManager = CommonBeanFactory.getBean(CacheManager.class); + Cache tokens_expire = cacheManager.getCache("tokens_expire"); + tokens_expire.evict(token); + } + + public static void addTokenExpire(String token){ + CacheManager cacheManager = CommonBeanFactory.getBean(CacheManager.class); + Cache tokens_expire = cacheManager.getCache("tokens_expire"); + long now = System.currentTimeMillis(); + tokens_expire.put(token, now); + } } diff --git a/backend/src/main/java/io/dataease/base/domain/DatasetTableField.java b/backend/src/main/java/io/dataease/base/domain/DatasetTableField.java index 6e7288c65e..9cd293962b 100644 --- a/backend/src/main/java/io/dataease/base/domain/DatasetTableField.java +++ b/backend/src/main/java/io/dataease/base/domain/DatasetTableField.java @@ -1,9 +1,12 @@ package io.dataease.base.domain; import java.io.Serializable; + +import lombok.Builder; import lombok.Data; @Data +@Builder public class DatasetTableField implements Serializable { private String id; @@ -24,4 +27,4 @@ public class DatasetTableField implements Serializable { private Integer deType; private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtDeptMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/ExtDeptMapper.java index f8f8b503ad..5a71f86c61 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtDeptMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtDeptMapper.java @@ -1,9 +1,8 @@ package io.dataease.base.mapper.ext; -import org.apache.ibatis.annotations.Delete; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; +import io.dataease.base.mapper.ext.query.GridExample; +import io.dataease.controller.sys.request.SimpleTreeNode; +import org.apache.ibatis.annotations.*; import java.util.List; @@ -22,4 +21,9 @@ public interface ExtDeptMapper { " #{id} " + "") int batchDelete(@Param("ids") List ids); + + + List allNodes(); + + List nodesByExample(GridExample example); } diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtDeptMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtDeptMapper.xml new file mode 100644 index 0000000000..9dcec17d12 --- /dev/null +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtDeptMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.java index 31ae070772..05c47bff5d 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.java @@ -1,6 +1,7 @@ package io.dataease.base.mapper.ext; import io.dataease.base.domain.SysRole; +import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.controller.sys.request.RoleGridRequest; import io.dataease.controller.sys.response.RoleUserItem; import org.apache.ibatis.annotations.Param; @@ -12,7 +13,7 @@ import java.util.Map; public interface ExtSysRoleMapper { - List query(@Param("request")RoleGridRequest request); + List query(GridExample example); int deleteRoleMenu(@Param("roleId") Long roleId); diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.xml index 37459e831b..1f3fe93d21 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysRoleMapper.xml @@ -9,15 +9,19 @@ - select r.* from sys_role r - - - AND r.name like CONCAT('%', #{request.name},'%') - - - order by r.update_time desc + + + + + order by ${orderByClause} + + + order by r.update_time desc + + diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java index 7fd6fc89c2..9c957c6b1f 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.java @@ -1,5 +1,7 @@ package io.dataease.base.mapper.ext; +import io.dataease.base.mapper.ext.query.GridExample; +import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.request.UserGridRequest; import io.dataease.controller.sys.response.SysUserGridResponse; import org.apache.ibatis.annotations.Param; @@ -8,5 +10,5 @@ import java.util.List; public interface ExtSysUserMapper { - List query(@Param("request")UserGridRequest request); + List query(GridExample example); } diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml index 981982136c..b13fb659f8 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtSysUserMapper.xml @@ -27,17 +27,24 @@ - select u.*,u.user_id as id, r.role_id,r.name as role_name , d.pid, d.name as dept_name from sys_user u left join sys_users_roles ur on u.user_id = ur.user_id left join sys_role r on r.role_id = ur.role_id left join sys_dept d on d.dept_id = u.dept_id - - - AND u.name like CONCAT('%', #{request.name},'%') - - - order by u.update_time desc + + + + + + order by ${orderByClause} + + + order by u.update_time desc + + diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/query/GridExample.java b/backend/src/main/java/io/dataease/base/mapper/ext/query/GridExample.java new file mode 100644 index 0000000000..2bb6eaf3e6 --- /dev/null +++ b/backend/src/main/java/io/dataease/base/mapper/ext/query/GridExample.java @@ -0,0 +1,259 @@ +package io.dataease.base.mapper.ext.query; + +import io.dataease.controller.sys.base.ConditionEntity; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public class GridExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public GridExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + + + public Criteria addCondtion(ConditionEntity conditionEntity){ + String field = conditionEntity.getField(); + Object value = conditionEntity.getValue(); + String operator = conditionEntity.getOperator(); + if (StringUtils.isEmpty(operator)) + operator = "like"; + switch (operator){ + case "eq": + addCriterion(field+" = ", value, field); + break; + case "ne": + addCriterion(field+" <> ", value, field); + break; + case "like": + addCriterion(field+" like ", "%"+value+"%", field); + break; + case "not like": + addCriterion(field+" not like ", value, field); + break; + case "in": + List invalues = (List)value; + addCriterion(field+" in", invalues, field); + break; + case "not in": + List notinvalues = (List)value; + addCriterion(field+" not in", notinvalues, field); + break; + case "between": + List values = (List)value; + Object v1 = values.get(0); + Object v2 = values.get(1); + addCriterion(field+" between", v1, v2, field); + break; + case "gt": + addCriterion(field+" > ", value, field); + break; + case "ge": + addCriterion(field+" >= ", value, field); + break; + case "lt": + addCriterion(field+" < ", value, field); + break; + case "le": + addCriterion(field+" <= ", value, field); + break; + } + return (Criteria) this; + } + + + + + + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/query/GridSql.java b/backend/src/main/java/io/dataease/base/mapper/ext/query/GridSql.java new file mode 100644 index 0000000000..fefd5df763 --- /dev/null +++ b/backend/src/main/java/io/dataease/base/mapper/ext/query/GridSql.java @@ -0,0 +1,4 @@ +package io.dataease.base.mapper.ext.query; + +public interface GridSql { +} diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/query/GridSql.xml b/backend/src/main/java/io/dataease/base/mapper/ext/query/GridSql.xml new file mode 100644 index 0000000000..a11cd3c87e --- /dev/null +++ b/backend/src/main/java/io/dataease/base/mapper/ext/query/GridSql.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + diff --git a/backend/src/main/java/io/dataease/commons/constants/DatasetMode.java b/backend/src/main/java/io/dataease/commons/constants/DatasetMode.java new file mode 100644 index 0000000000..b47fe5c05f --- /dev/null +++ b/backend/src/main/java/io/dataease/commons/constants/DatasetMode.java @@ -0,0 +1,6 @@ +package io.dataease.commons.constants; + +public class DatasetMode { + public static final String EXTRACT = "1"; + public static final String DIRECT = "0"; +} diff --git a/backend/src/main/java/io/dataease/commons/constants/JobStatus.java b/backend/src/main/java/io/dataease/commons/constants/JobStatus.java new file mode 100644 index 0000000000..59d7672641 --- /dev/null +++ b/backend/src/main/java/io/dataease/commons/constants/JobStatus.java @@ -0,0 +1,5 @@ +package io.dataease.commons.constants; + +public enum JobStatus { + Prepare, Underway, Completed, Error +} diff --git a/backend/src/main/java/io/dataease/commons/constants/TestPlanStatus.java b/backend/src/main/java/io/dataease/commons/constants/TestPlanStatus.java deleted file mode 100644 index 24aefa1ce1..0000000000 --- a/backend/src/main/java/io/dataease/commons/constants/TestPlanStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.dataease.commons.constants; - -public enum TestPlanStatus { - Prepare, Underway, Completed -} diff --git a/backend/src/main/java/io/dataease/config/HbaseConfig.java b/backend/src/main/java/io/dataease/config/HbaseConfig.java new file mode 100644 index 0000000000..f7b8bfaece --- /dev/null +++ b/backend/src/main/java/io/dataease/config/HbaseConfig.java @@ -0,0 +1,30 @@ +package io.dataease.config; + +import com.fit2cloud.autoconfigure.QuartzAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.core.env.Environment; + +import javax.annotation.Resource; + +@Configuration +@AutoConfigureBefore(QuartzAutoConfiguration.class) +public class HbaseConfig { + + @Resource + private Environment env; // 保存了配置文件的信息 + + + @Bean + @ConditionalOnMissingBean + public org.apache.hadoop.conf.Configuration configuration(){ + org.apache.hadoop.conf.Configuration configuration = new org.apache.hadoop.conf.Configuration(); + configuration.set("hbase.zookeeper.quorum", env.getProperty("hbase.zookeeper.quorum")); + configuration.set("hbase.zookeeper.property.clientPort", env.getProperty("hbase.zookeeper.property.clientPort")); + configuration.set("hbase.client.retries.number", env.getProperty("hbase.client.retries.number", "1")); + return configuration; + } +} diff --git a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java index 691948db33..d4d135ccfd 100644 --- a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java +++ b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java @@ -19,7 +19,7 @@ public class DataSetTableFieldController { @PostMapping("list/{tableId}") public List list(@PathVariable String tableId) { - DatasetTableField datasetTableField = new DatasetTableField(); + DatasetTableField datasetTableField = DatasetTableField.builder().build(); datasetTableField.setTableId(tableId); return dataSetTableFieldsService.list(datasetTableField); } diff --git a/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java b/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java index fcbe71ce65..0f922996ef 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysDeptController.java @@ -3,6 +3,7 @@ package io.dataease.controller.sys; 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.DeptDeleteRequest; import io.dataease.controller.sys.request.DeptStatusRequest; @@ -39,6 +40,19 @@ public class SysDeptController extends ResultHolder { return nodeResponses; } + @PostMapping("/search") + public List search(@RequestBody BaseGridRequest request){ + List nodes = deptService.nodesTreeByCondition(request); + //List nodes = deptService.nodesByPid(pid); + List nodeResponses = nodes.stream().map(node -> { + DeptNodeResponse deptNodeResponse = BeanUtils.copyBean(new DeptNodeResponse(), node); + deptNodeResponse.setHasChildren(node.getSubCount() > 0); + deptNodeResponse.setTop(node.getPid() == deptService.DEPT_ROOT_PID); + return deptNodeResponse; + }).collect(Collectors.toList()); + return nodeResponses; + } + @ApiOperation("查询部门") @PostMapping("/root") public ResultHolder rootData(){ diff --git a/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java b/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java index eb1cb93a2a..2927dd94a1 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysRoleController.java @@ -6,6 +6,7 @@ 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.RoleGridRequest; import io.dataease.controller.sys.request.RoleMenusRequest; import io.dataease.controller.sys.response.RoleUserItem; @@ -49,7 +50,7 @@ public class SysRoleController { @ApiOperation("查询角色") @PostMapping("/roleGrid/{goPage}/{pageSize}") - public Pager> roleGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody RoleGridRequest request) { + public Pager> roleGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody BaseGridRequest request) { Page page = PageHelper.startPage(goPage, pageSize, true); Pager> listPager = PageUtils.setPageInfo(page, sysRoleService.query(request)); return listPager; diff --git a/backend/src/main/java/io/dataease/controller/sys/SysUserController.java b/backend/src/main/java/io/dataease/controller/sys/SysUserController.java index bdaeb7ed1a..4fe8913321 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysUserController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysUserController.java @@ -5,6 +5,7 @@ import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; 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.SysUserCreateRequest; import io.dataease.controller.sys.request.SysUserPwdRequest; import io.dataease.controller.sys.request.SysUserStateRequest; @@ -27,10 +28,14 @@ public class SysUserController { @ApiOperation("查询用户") @PostMapping("/userGrid/{goPage}/{pageSize}") - public Pager> userGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody UserGridRequest request) { + public Pager> userGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody BaseGridRequest request) { Page page = PageHelper.startPage(goPage, pageSize, true); return PageUtils.setPageInfo(page, sysUserService.query(request)); } + /*public Pager> userGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody UserGridRequest request) { + Page page = PageHelper.startPage(goPage, pageSize, true); + return PageUtils.setPageInfo(page, sysUserService.query(request)); + }*/ @ApiOperation("创建用户") @PostMapping("/create") diff --git a/backend/src/main/java/io/dataease/controller/sys/base/BaseGridRequest.java b/backend/src/main/java/io/dataease/controller/sys/base/BaseGridRequest.java new file mode 100644 index 0000000000..4448c64b82 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/sys/base/BaseGridRequest.java @@ -0,0 +1,24 @@ +package io.dataease.controller.sys.base; + +import io.dataease.base.mapper.ext.query.GridExample; +import lombok.Data; +import org.apache.commons.collections.CollectionUtils; + +import java.io.Serializable; +import java.util.List; + + +@Data +public class BaseGridRequest implements Serializable { + + private List conditions; + + public GridExample convertExample(){ + GridExample gridExample = new GridExample(); + if (CollectionUtils.isEmpty(conditions))return gridExample; + + GridExample.Criteria criteria = gridExample.createCriteria(); + conditions.forEach(criteria::addCondtion); + return gridExample; + } +} diff --git a/backend/src/main/java/io/dataease/controller/sys/base/ConditionEntity.java b/backend/src/main/java/io/dataease/controller/sys/base/ConditionEntity.java new file mode 100644 index 0000000000..0da0774c41 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/sys/base/ConditionEntity.java @@ -0,0 +1,16 @@ +package io.dataease.controller.sys.base; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class ConditionEntity implements Serializable { + + private String field; + + private String operator; + + private Object value; + +} diff --git a/backend/src/main/java/io/dataease/controller/sys/request/SimpleTreeNode.java b/backend/src/main/java/io/dataease/controller/sys/request/SimpleTreeNode.java new file mode 100644 index 0000000000..53548d41b2 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/sys/request/SimpleTreeNode.java @@ -0,0 +1,11 @@ +package io.dataease.controller.sys.request; + +import lombok.Data; + +@Data +public class SimpleTreeNode { + + private Long id; + + private Long pid; +} diff --git a/backend/src/main/java/io/dataease/controller/sys/request/UserGridRequest.java b/backend/src/main/java/io/dataease/controller/sys/request/UserGridRequest.java index 4b325a3c17..55da77bea9 100644 --- a/backend/src/main/java/io/dataease/controller/sys/request/UserGridRequest.java +++ b/backend/src/main/java/io/dataease/controller/sys/request/UserGridRequest.java @@ -1,10 +1,18 @@ package io.dataease.controller.sys.request; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @Data public class UserGridRequest implements Serializable { + @ApiModelProperty("快速检索") + private String quick; + @ApiModelProperty("名称") private String name; + @ApiModelProperty("组织") + private String deptId; + @ApiModelProperty("状态") + private String enabled; } diff --git a/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java b/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java index 42c0a1a20a..d1dc06956d 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java +++ b/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java @@ -23,4 +23,8 @@ public abstract class DatasourceProvider { getData(datasourceRequest); } + abstract public Long count(DatasourceRequest datasourceRequest)throws Exception; + + abstract public List getPageData(DatasourceRequest datasourceRequest) throws Exception; + } diff --git a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java index d3c94c8230..4b53abfb49 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java +++ b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java @@ -9,6 +9,7 @@ import io.dataease.datasource.request.DatasourceRequest; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import java.sql.*; +import java.text.MessageFormat; import java.util.*; @Service("jdbc") @@ -23,23 +24,7 @@ public class JdbcProvider extends DatasourceProvider{ Statement stat = connection.createStatement(); ResultSet rs = stat.executeQuery(datasourceRequest.getQuery()) ) { - ResultSetMetaData metaData = rs.getMetaData(); - int columnCount = metaData.getColumnCount(); - while (rs.next()) { - String[] row = new String[columnCount]; - for (int j = 0; j < columnCount; j++) { - int columType = metaData.getColumnType(j + 1); - switch (columType) { - case java.sql.Types.DATE: - row[j] = rs.getDate(j + 1).toString(); - break; - default: - row[j] = rs.getString(j + 1); - break; - } - } - list.add(row); - } + list = fetchResult(rs); } catch (SQLException e){ throw new Exception("ERROR:" + e.getMessage(), e); }catch (Exception e) { @@ -48,6 +33,46 @@ public class JdbcProvider extends DatasourceProvider{ return list; } + @Override + public List getPageData(DatasourceRequest datasourceRequest) throws Exception { + List list = new LinkedList<>(); + try ( + Connection connection = getConnection(datasourceRequest); + Statement stat = connection.createStatement(); + ResultSet rs = stat.executeQuery(datasourceRequest.getQuery() + MessageFormat.format(" LIMIT {0}, {1}", (datasourceRequest.getStartPage() -1)*datasourceRequest.getPageSize(), datasourceRequest.getPageSize())) + ) { + list = fetchResult(rs); + } catch (SQLException e){ + throw new Exception("ERROR:" + e.getMessage(), e); + }catch (Exception e) { + throw new Exception("ERROR:" + e.getMessage(), e); + } + return list; + } + + + private List fetchResult( ResultSet rs) throws Exception{ + List list = new LinkedList<>(); + ResultSetMetaData metaData = rs.getMetaData(); + int columnCount = metaData.getColumnCount(); + while (rs.next()) { + String[] row = new String[columnCount]; + for (int j = 0; j < columnCount; j++) { + int columType = metaData.getColumnType(j + 1); + switch (columType) { + case java.sql.Types.DATE: + row[j] = rs.getDate(j + 1).toString(); + break; + default: + row[j] = rs.getString(j + 1); + break; + } + } + list.add(row); + } + return list; + } + @Override public List getTables(DatasourceRequest datasourceRequest) throws Exception { List tables = new ArrayList<>(); @@ -106,6 +131,19 @@ public class JdbcProvider extends DatasourceProvider{ } } + + public Long count(DatasourceRequest datasourceRequest)throws Exception{ + try (Connection con = getConnection(datasourceRequest); Statement ps = con.createStatement()) { + ResultSet resultSet = ps.executeQuery(datasourceRequest.getQuery()); + while (resultSet.next()) { + return resultSet.getLong(1); + } + } catch (Exception e) { + throw new Exception("ERROR: " + e.getMessage(), e); + } + return 0L; + } + private Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { String username = null; String password = null; diff --git a/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java b/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java index 60d7b4f1b0..9521b50af5 100644 --- a/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java +++ b/backend/src/main/java/io/dataease/datasource/request/DatasourceRequest.java @@ -11,5 +11,8 @@ public class DatasourceRequest { protected String query; protected String table; protected Datasource datasource; + private Long pageSize; + private Long startPage; + } diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java new file mode 100644 index 0000000000..b748b624d9 --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java @@ -0,0 +1,30 @@ +package io.dataease.dto.chart; + +import lombok.Data; + +/** + * @Author gin + * @Date 2021/3/11 1:18 下午 + */ +@Data +public class ChartViewFieldDTO { + private String id; + + private String tableId; + + private String originName; + + private String name; + + private String type; + + private Boolean checked; + + private Integer columnIndex; + + private Long lastSyncTime; + + private Integer deType; + + private String summary; +} diff --git a/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java b/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java index 6e2a336853..3c409114d8 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java +++ b/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java @@ -1,22 +1,25 @@ package io.dataease.job.sechedule; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; +import io.dataease.commons.utils.LogUtil; +import org.quartz.*; public abstract class DeScheduleJob implements Job { + protected String datasetTableId; + protected String expression; + protected String taskId; + @Override public void execute(JobExecutionContext context) throws JobExecutionException { + JobKey jobKey = context.getTrigger().getJobKey(); + JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); + this.datasetTableId = jobDataMap.getString("datasetTableId"); + this.expression = jobDataMap.getString("expression"); + this.taskId = jobDataMap.getString("taskId"); -// JobKey jobKey = context.getTrigger().getJobKey(); -// JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); -// this.resourceId = jobDataMap.getString("resourceId"); -// this.userId = jobDataMap.getString("userId"); -// this.expression = jobDataMap.getString("expression"); -// -// LogUtil.info(jobKey.getGroup() + " Running: " + resourceId); -// LogUtil.info("CronExpression: " + expression); + LogUtil.info(jobKey.getGroup() + " Running: " + datasetTableId); + LogUtil.info(jobKey.getName() + " Running: " + datasetTableId); + LogUtil.info("CronExpression: " + expression); businessExecute(context); } diff --git a/backend/src/main/java/io/dataease/job/sechedule/ExtractDataJob.java b/backend/src/main/java/io/dataease/job/sechedule/ExtractDataJob.java new file mode 100644 index 0000000000..2704f33a02 --- /dev/null +++ b/backend/src/main/java/io/dataease/job/sechedule/ExtractDataJob.java @@ -0,0 +1,22 @@ +package io.dataease.job.sechedule; + +import io.dataease.commons.utils.CommonBeanFactory; +import io.dataease.service.dataset.ExtractDataService; +import org.quartz.JobExecutionContext; +import org.springframework.stereotype.Component; + +@Component +public class ExtractDataJob extends DeScheduleJob{ + private ExtractDataService extractDataService; + + public ExtractDataJob() { + extractDataService = (ExtractDataService) CommonBeanFactory.getBean(ExtractDataService.class); + } + + + @Override + void businessExecute(JobExecutionContext context) { + extractDataService.extractData(datasetTableId, taskId); + } + +} diff --git a/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java b/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java index 045ba851fb..44bdf3aaad 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java +++ b/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java @@ -369,11 +369,11 @@ public class ScheduleManager { addOrUpdateCronJob(jobKey, triggerKey, jobClass, cron, startTime, endTime, null); } - public JobDataMap getDefaultJobDataMap(String resourceId, String expression, String userId) { + public JobDataMap getDefaultJobDataMap(String resourceId, String expression, String taskId) { JobDataMap jobDataMap = new JobDataMap(); - jobDataMap.put("resourceId", resourceId); + jobDataMap.put("datasetTableId", resourceId); + jobDataMap.put("taskId", taskId); jobDataMap.put("expression", expression); - jobDataMap.put("userId", userId); return jobDataMap; } diff --git a/backend/src/main/java/io/dataease/listener/AppStartListener.java b/backend/src/main/java/io/dataease/listener/AppStartListener.java index 11dfdfac91..f44b517d36 100644 --- a/backend/src/main/java/io/dataease/listener/AppStartListener.java +++ b/backend/src/main/java/io/dataease/listener/AppStartListener.java @@ -20,13 +20,7 @@ public class AppStartListener implements ApplicationListener list = dataSetTableTaskService.list(new DatasetTableTask()); for (DatasetTableTask task : list) { diff --git a/backend/src/main/java/io/dataease/service/ScheduleService.java b/backend/src/main/java/io/dataease/service/ScheduleService.java index 79739fa41e..5885687dcb 100644 --- a/backend/src/main/java/io/dataease/service/ScheduleService.java +++ b/backend/src/main/java/io/dataease/service/ScheduleService.java @@ -1,8 +1,8 @@ package io.dataease.service; import io.dataease.base.domain.DatasetTableTask; +import io.dataease.job.sechedule.ExtractDataJob; import io.dataease.job.sechedule.ScheduleManager; -import io.dataease.job.sechedule.TestJob; import org.apache.commons.lang3.StringUtils; import org.quartz.JobKey; import org.quartz.TriggerKey; @@ -24,8 +24,8 @@ public class ScheduleService { if (StringUtils.equalsIgnoreCase(datasetTableTask.getRate(), "0")) { scheduleManager.addOrUpdateSingleJob(new JobKey(datasetTableTask.getId(), datasetTableTask.getTableId()), new TriggerKey(datasetTableTask.getId(), datasetTableTask.getTableId()), - TestJob.class,//TODO - new Date(datasetTableTask.getStartTime())); + ExtractDataJob.class, + new Date(datasetTableTask.getStartTime()), scheduleManager.getDefaultJobDataMap(datasetTableTask.getTableId(), datasetTableTask.getCron(), datasetTableTask.getId())); } else if (StringUtils.equalsIgnoreCase(datasetTableTask.getRate(), "1")) { Date endTime; if (datasetTableTask.getEndTime() == null || datasetTableTask.getEndTime() == 0) { @@ -36,8 +36,9 @@ public class ScheduleService { scheduleManager.addOrUpdateCronJob(new JobKey(datasetTableTask.getId(), datasetTableTask.getTableId()), new TriggerKey(datasetTableTask.getId(), datasetTableTask.getTableId()), - TestJob.class,// TODO - datasetTableTask.getCron(), new Date(datasetTableTask.getStartTime()), endTime); + ExtractDataJob.class, + datasetTableTask.getCron(), new Date(datasetTableTask.getStartTime()), endTime, + scheduleManager.getDefaultJobDataMap(datasetTableTask.getTableId(), datasetTableTask.getCron(), datasetTableTask.getId())); } } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 803c3f094d..9dd307c471 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -12,6 +12,7 @@ import io.dataease.datasource.provider.ProviderFactory; import io.dataease.datasource.request.DatasourceRequest; import io.dataease.datasource.service.DatasourceService; import io.dataease.dto.chart.ChartViewDTO; +import io.dataease.dto.chart.ChartViewFieldDTO; import io.dataease.dto.chart.Series; import io.dataease.dto.dataset.DataTableInfoDTO; import io.dataease.service.dataset.DataSetTableFieldsService; @@ -76,9 +77,9 @@ public class ChartViewService { public ChartViewDTO getData(String id) throws Exception { ChartViewWithBLOBs view = chartViewMapper.selectByPrimaryKey(id); - List xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken>() { + List xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken>() { }.getType()); - List yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken>() { + List yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken>() { }.getType()); List x = new ArrayList<>(); @@ -88,25 +89,25 @@ public class ChartViewService { BeanUtils.copyBean(dto, view); return dto; } - List xIds = xAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList()); - List yIds = yAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList()); - List xList = dataSetTableFieldsService.getListByIds(xIds); - List yList = dataSetTableFieldsService.getListByIds(yIds); +// List xIds = xAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList()); +// List yIds = yAxis.stream().map(DatasetTableField::getId).collect(Collectors.toList()); +// List xList = dataSetTableFieldsService.getListByIds(xIds); +// List yList = dataSetTableFieldsService.getListByIds(yIds); - // 获取数据源 + // 获取数据集 DatasetTable table = dataSetTableService.get(view.getTableId()); + // todo 判断连接方式,直连或者定时抽取 table.mode Datasource ds = datasourceService.get(table.getDataSourceId()); - DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType()); DatasourceRequest datasourceRequest = new DatasourceRequest(); datasourceRequest.setDatasource(ds); DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class); datasourceRequest.setTable(dataTableInfoDTO.getTable()); - datasourceRequest.setQuery(getSQL(ds.getType(), dataTableInfoDTO.getTable(), xList, yList)); + datasourceRequest.setQuery(getSQL(ds.getType(), dataTableInfoDTO.getTable(), xAxis, yAxis)); List data = datasourceProvider.getData(datasourceRequest); // todo 处理结果,目前做一个单系列图表,后期图表组件再扩展 - for (DatasetTableField y : yList) { + for (ChartViewFieldDTO y : yAxis) { Series series1 = new Series(); series1.setName(y.getName()); series1.setType(view.getType()); @@ -116,16 +117,16 @@ public class ChartViewService { for (String[] d : data) { StringBuilder a = new StringBuilder(); BigDecimal b = new BigDecimal("0"); - for (int i = 0; i < xList.size(); i++) { - if (i == xList.size() - 1) { + 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()); - for (int i = xList.size(); i < xList.size() + yList.size(); i++) { - int j = i - xList.size(); + for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) { + int j = i - xAxis.size(); series.get(j).getData().add(new BigDecimal(d[i])); } } @@ -139,7 +140,7 @@ public class ChartViewService { return dto; } - public String getSQL(String type, String table, List xAxis, List yAxis) { + public String getSQL(String type, String table, List xAxis, List yAxis) { DatasourceTypes datasourceType = DatasourceTypes.valueOf(type); switch (datasourceType) { case mysql: @@ -150,10 +151,10 @@ public class ChartViewService { } } - public String transMysqlSQL(String table, List xAxis, List yAxis) { - // TODO 此处sum后期由用户前端传入 - String[] field = yAxis.stream().map(y -> "sum(" + y.getOriginName() + ")").toArray(String[]::new); - String[] group = xAxis.stream().map(DatasetTableField::getOriginName).toArray(String[]::new); + public String transMysqlSQL(String table, List xAxis, List yAxis) { + // TODO 字段汇总 排序等 + String[] field = yAxis.stream().map(y -> "CAST(" + y.getSummary() + "(" + y.getOriginName() + ") AS DECIMAL(20,2))").toArray(String[]::new); + String[] group = xAxis.stream().map(ChartViewFieldDTO::getOriginName).toArray(String[]::new); return MessageFormat.format("SELECT {0},{1} FROM {2} GROUP BY {3}", StringUtils.join(group, ","), StringUtils.join(field, ","), table, StringUtils.join(group, ",")); } } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index 6bd40b6720..518042cb89 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -37,6 +37,8 @@ public class DataSetTableService { private DatasourceMapper datasourceMapper; @Resource private DataSetTableFieldsService dataSetTableFieldsService; + @Resource + private DataSetTableTaskService dataSetTableTaskService; public void batchInsert(List datasetTable) throws Exception { for (DatasetTable table : datasetTable) { @@ -67,11 +69,15 @@ public class DataSetTableService { public void delete(String id) { datasetTableMapper.deleteByPrimaryKey(id); dataSetTableFieldsService.deleteByTableId(id); + // 删除同步任务 + dataSetTableTaskService.deleteByTableId(id); } public List list(DataSetTableRequest dataSetTableRequest) { DatasetTableExample datasetTableExample = new DatasetTableExample(); - datasetTableExample.createCriteria().andSceneIdEqualTo(dataSetTableRequest.getSceneId()); + if (StringUtils.isNotEmpty(dataSetTableRequest.getSceneId())) { + datasetTableExample.createCriteria().andSceneIdEqualTo(dataSetTableRequest.getSceneId()); + } if (StringUtils.isNotEmpty(dataSetTableRequest.getSort())) { datasetTableExample.setOrderByClause(dataSetTableRequest.getSort()); } @@ -92,7 +98,7 @@ public class DataSetTableService { } public Map> getFieldsFromDE(DataSetTableRequest dataSetTableRequest) throws Exception { - DatasetTableField datasetTableField = new DatasetTableField(); + DatasetTableField datasetTableField = DatasetTableField.builder().build(); datasetTableField.setTableId(dataSetTableRequest.getId()); datasetTableField.setChecked(Boolean.TRUE); List fields = dataSetTableFieldsService.list(datasetTableField); @@ -121,7 +127,7 @@ public class DataSetTableService { datasourceRequest.setDatasource(ds); String table = new Gson().fromJson(dataSetTableRequest.getInfo(), DataTableInfoDTO.class).getTable(); - DatasetTableField datasetTableField = new DatasetTableField(); + DatasetTableField datasetTableField = DatasetTableField.builder().build(); datasetTableField.setTableId(dataSetTableRequest.getId()); datasetTableField.setChecked(Boolean.TRUE); List fields = dataSetTableFieldsService.list(datasetTableField); @@ -137,15 +143,13 @@ public class DataSetTableService { DatasourceRequest datasourceRequest = new DatasourceRequest(); datasourceRequest.setDatasource(ds); String table = new Gson().fromJson(dataSetTableRequest.getInfo(), DataTableInfoDTO.class).getTable(); -// datasourceRequest.setTable(table); - DatasetTableField datasetTableField = new DatasetTableField(); + DatasetTableField datasetTableField = DatasetTableField.builder().build(); datasetTableField.setTableId(dataSetTableRequest.getId()); datasetTableField.setChecked(Boolean.TRUE); List fields = dataSetTableFieldsService.list(datasetTableField); String[] fieldArray = fields.stream().map(DatasetTableField::getOriginName).toArray(String[]::new); -// datasourceRequest.setQuery("SELECT " + StringUtils.join(fieldArray, ",") + " FROM " + table + " LIMIT 0,10;"); datasourceRequest.setQuery(createQuerySQL(ds.getType(), table, fieldArray) + " LIMIT 0,10"); List data = new ArrayList<>(); @@ -154,17 +158,6 @@ public class DataSetTableService { } catch (Exception e) { } - - /*JSONArray jsonArray = new JSONArray(); - if (CollectionUtils.isNotEmpty(data)) { - data.forEach(ele -> { - JSONObject jsonObject = new JSONObject(); - for (int i = 0; i < ele.length; i++) { - jsonObject.put(fieldArray[i], ele[i]); - } - jsonArray.add(jsonObject); - }); - }*/ List> jsonArray = new ArrayList<>(); if (CollectionUtils.isNotEmpty(data)) { jsonArray = data.stream().map(ele -> { @@ -184,6 +177,53 @@ public class DataSetTableService { return map; } + public List getDataSetData(String datasourceId, String table, List fields) { + List data = new ArrayList<>(); + Datasource ds = datasourceMapper.selectByPrimaryKey(datasourceId); + DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType()); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDatasource(ds); + String[] fieldArray = fields.stream().map(DatasetTableField::getOriginName).toArray(String[]::new); + datasourceRequest.setQuery(createQuerySQL(ds.getType(), table, fieldArray) + " LIMIT 0, 10"); + try { + data.addAll(datasourceProvider.getData(datasourceRequest)); + } catch (Exception e) { + } + return data; + } + + public Long getDataSetTotalData(String datasourceId, String table) { + List data = new ArrayList<>(); + Datasource ds = datasourceMapper.selectByPrimaryKey(datasourceId); + DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType()); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDatasource(ds); + datasourceRequest.setQuery("select count(*) from " + table); + try { + return datasourceProvider.count(datasourceRequest); + } catch (Exception e) { + + } + return 0l; + } + + public List getDataSetPageData(String datasourceId, String table, List fields, Long startPage, Long pageSize) { + List data = new ArrayList<>(); + Datasource ds = datasourceMapper.selectByPrimaryKey(datasourceId); + DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType()); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDatasource(ds); + String[] fieldArray = fields.stream().map(DatasetTableField::getOriginName).toArray(String[]::new); + datasourceRequest.setPageSize(pageSize); + datasourceRequest.setStartPage(startPage); + datasourceRequest.setQuery(createQuerySQL(ds.getType(), table, fieldArray)); + try { + return datasourceProvider.getData(datasourceRequest); + } catch (Exception e) { + } + return data; + } + public void saveTableField(DatasetTable datasetTable) throws Exception { Datasource ds = datasourceMapper.selectByPrimaryKey(datasetTable.getDataSourceId()); DataSetTableRequest dataSetTableRequest = new DataSetTableRequest(); @@ -193,7 +233,7 @@ public class DataSetTableService { if (CollectionUtils.isNotEmpty(fields)) { for (int i = 0; i < fields.size(); i++) { TableFiled filed = fields.get(i); - DatasetTableField datasetTableField = new DatasetTableField(); + DatasetTableField datasetTableField = DatasetTableField.builder().build(); datasetTableField.setTableId(datasetTable.getId()); datasetTableField.setOriginName(filed.getFieldName()); datasetTableField.setName(filed.getRemarks()); diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java index fe687d4f75..783e564be7 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java @@ -48,4 +48,11 @@ public class DataSetTableTaskLogService { return extDataSetTaskMapper.list(request); } + public void deleteByTaskId(String taskId){ + DatasetTableTaskLogExample datasetTableTaskLogExample = new DatasetTableTaskLogExample(); + DatasetTableTaskLogExample.Criteria criteria = datasetTableTaskLogExample.createCriteria(); + criteria.andTaskIdEqualTo(taskId); + datasetTableTaskLogMapper.deleteByExample(datasetTableTaskLogExample); + } + } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java index 44d5d0719e..ba494c375a 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java @@ -7,6 +7,7 @@ import io.dataease.service.ScheduleService; import org.apache.commons.lang3.StringUtils; import org.quartz.CronExpression; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @@ -17,10 +18,12 @@ import java.util.UUID; * @Date 2021/3/4 1:26 下午 */ @Service +@Transactional public class DataSetTableTaskService { @Resource private DatasetTableTaskMapper datasetTableTaskMapper; - + @Resource + private DataSetTableTaskLogService dataSetTableTaskLogService; @Resource private ScheduleService scheduleService; @@ -46,6 +49,25 @@ public class DataSetTableTaskService { DatasetTableTask datasetTableTask = datasetTableTaskMapper.selectByPrimaryKey(id); datasetTableTaskMapper.deleteByPrimaryKey(id); scheduleService.deleteSchedule(datasetTableTask); + dataSetTableTaskLogService.deleteByTaskId(id); + } + + public void delete(DatasetTableTask task) { + datasetTableTaskMapper.deleteByPrimaryKey(task.getId()); + scheduleService.deleteSchedule(task); + dataSetTableTaskLogService.deleteByTaskId(task.getId()); + } + + public void deleteByTableId(String id) { + DatasetTableTaskExample datasetTableTaskExample = new DatasetTableTaskExample(); + DatasetTableTaskExample.Criteria criteria = datasetTableTaskExample.createCriteria(); + criteria.andTableIdEqualTo(id); + List datasetTableTasks = datasetTableTaskMapper.selectByExample(datasetTableTaskExample); + datasetTableTasks.forEach(this::delete); + } + + public DatasetTableTask get(String id) { + return datasetTableTaskMapper.selectByPrimaryKey(id); } public List list(DatasetTableTask datasetTableTask) { diff --git a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java new file mode 100644 index 0000000000..037fe397d5 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java @@ -0,0 +1,93 @@ +package io.dataease.service.dataset; + +import com.google.gson.Gson; +import io.dataease.base.domain.DatasetTable; +import io.dataease.base.domain.DatasetTableField; +import io.dataease.base.domain.DatasetTableTaskLog; +import io.dataease.commons.constants.JobStatus; +import io.dataease.commons.utils.CommonBeanFactory; +import io.dataease.dto.dataset.DataTableInfoDTO; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.*; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Service +public class ExtractDataService { + + @Resource + private DataSetTableService dataSetTableService; + @Resource + private DataSetTableFieldsService dataSetTableFieldsService; + @Resource + private DataSetTableTaskLogService dataSetTableTaskLogService; + private Long pageSize = 10000l; + private static ExecutorService pool = Executors.newScheduledThreadPool(50); //设置连接池 + private Connection connection; + + public void extractData(String datasetTableId, String taskId) { + DatasetTableTaskLog datasetTableTaskLog = new DatasetTableTaskLog(); + try { + datasetTableTaskLog.setTableId(datasetTableId); + datasetTableTaskLog.setTaskId(taskId); + datasetTableTaskLog.setStatus(JobStatus.Underway.name()); + datasetTableTaskLog.setStartTime(System.currentTimeMillis()); + dataSetTableTaskLogService.save(datasetTableTaskLog); + Admin admin = getConnection().getAdmin(); + DatasetTable datasetTable = dataSetTableService.get(datasetTableId); + List datasetTableFields = dataSetTableFieldsService.list(DatasetTableField.builder().tableId(datasetTable.getId()).build()); + String table = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getTable(); + TableName tableName = TableName.valueOf(table + "-" + datasetTable.getDataSourceId()); + if(!admin.tableExists(tableName)){ + TableDescriptorBuilder descBuilder = TableDescriptorBuilder.newBuilder(tableName); + ColumnFamilyDescriptor hcd = ColumnFamilyDescriptorBuilder.of("cf"); + descBuilder.setColumnFamily(hcd); + TableDescriptor desc = descBuilder.build(); + admin.createTable(desc); + } + admin.disableTable(tableName); + admin.truncateTable(tableName, true); + + Table tab = getConnection().getTable(tableName); + Long total = dataSetTableService.getDataSetTotalData(datasetTable.getDataSourceId(), table); + Long pageCount = total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1; + + for (Long pageIndex = 1l; pageIndex <= pageCount; pageIndex++) { + List data = dataSetTableService.getDataSetPageData(datasetTable.getDataSourceId(), table, datasetTableFields, pageIndex, pageSize); + for (String[] d : data) { + for(int i=0;i nodesByPid(Long pid){ @@ -120,4 +124,59 @@ public class DeptService { return sysDeptMapper.updateByPrimaryKeySelective(sysDept); } + + + public List nodesTreeByCondition(BaseGridRequest request){ + //DeptService proxy = proxy(); + List allNodes = allNodes(); + List targetNodes = nodeByCondition(request); + List ids = upTree(allNodes, targetNodes); + SysDeptExample example = new SysDeptExample(); + SysDeptExample.Criteria criteria = example.createCriteria(); + criteria.andDeptIdIn(ids); + example.setOrderByClause("dept_sort"); + List sysDepts = sysDeptMapper.selectByExample(example); + return sysDepts; + } + + private DeptService proxy(){ + return CommonBeanFactory.getBean(DeptService.class); + } + + + private List allNodes(){ + List simpleTreeNodes = extDeptMapper.allNodes(); + return simpleTreeNodes; + } + + private List nodeByCondition(BaseGridRequest request){ + GridExample gridExample = request.convertExample(); + List simpleTreeNodes = extDeptMapper.nodesByExample(gridExample); + return simpleTreeNodes; + } + + /** + * 找出目标节点所在路径上的所有节点 向上找 + * @param allNodes 所有节点 + * @param targetNodes 目标节点 + * @return + */ + private List upTree(List allNodes, List targetNodes){ + final Map map = allNodes.stream().collect(Collectors.toMap(SimpleTreeNode::getId, node -> node)); + List results = targetNodes.parallelStream().flatMap(targetNode -> { + //向上逐级找爹 + List ids = new ArrayList<>(); + SimpleTreeNode node = targetNode; + while (node != null) { + ids.add(node.getId()); + Long pid = node.getPid(); + node = map.get(pid); + } + return ids.stream(); + }).distinct().collect(Collectors.toList()); + return results; + } + + + } diff --git a/backend/src/main/java/io/dataease/service/sys/SysRoleService.java b/backend/src/main/java/io/dataease/service/sys/SysRoleService.java index 0ad1d6f3bd..5500878071 100644 --- a/backend/src/main/java/io/dataease/service/sys/SysRoleService.java +++ b/backend/src/main/java/io/dataease/service/sys/SysRoleService.java @@ -6,6 +6,7 @@ import io.dataease.base.domain.SysUsersRolesExample; import io.dataease.base.mapper.SysRoleMapper; 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.RoleGridRequest; import io.dataease.controller.sys.request.RoleMenusRequest; import io.dataease.controller.sys.response.RoleUserItem; @@ -56,8 +57,8 @@ public class SysRoleService { } - public List query(RoleGridRequest request){ - List result = extSysRoleMapper.query(request); + public List query(BaseGridRequest request){ + List result = extSysRoleMapper.query(request.convertExample()); return result; } diff --git a/backend/src/main/java/io/dataease/service/sys/SysUserService.java b/backend/src/main/java/io/dataease/service/sys/SysUserService.java index 70fce60ae4..f36e23c859 100644 --- a/backend/src/main/java/io/dataease/service/sys/SysUserService.java +++ b/backend/src/main/java/io/dataease/service/sys/SysUserService.java @@ -7,8 +7,10 @@ import io.dataease.base.domain.SysUsersRolesKey; import io.dataease.base.mapper.SysUserMapper; import io.dataease.base.mapper.SysUsersRolesMapper; import io.dataease.base.mapper.ext.ExtSysUserMapper; +import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.CodingUtil; +import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.request.SysUserCreateRequest; import io.dataease.controller.sys.request.SysUserPwdRequest; import io.dataease.controller.sys.request.SysUserStateRequest; @@ -40,8 +42,10 @@ public class SysUserService { @Resource private ExtSysUserMapper extSysUserMapper; - public List query(UserGridRequest request){ - List lists = extSysUserMapper.query(request); + + public List query(BaseGridRequest request){ + GridExample gridExample = request.convertExample(); + List lists = extSysUserMapper.query(gridExample); lists.forEach(item -> { List roles = item.getRoles(); List roleIds = roles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()); @@ -111,6 +115,7 @@ public class SysUserService { return sysUserMapper.updateByPrimaryKeySelective(sysUser); } + @CacheEvict(value = USER_CACHE_NAME, key = "'user' + #request.userId") public int adminUpdatePwd(SysUserPwdRequest request){ SysUser sysUser = new SysUser(); sysUser.setUserId(request.getUserId()); diff --git a/backend/src/main/resources/ehcache/ehcache.xml b/backend/src/main/resources/ehcache/ehcache.xml index 6af1c3769d..a5e5d7b09a 100644 --- a/backend/src/main/resources/ehcache/ehcache.xml +++ b/backend/src/main/resources/ehcache/ehcache.xml @@ -7,10 +7,10 @@ user.dir - 用户当前工作目录 java.io.tmpdir - 默认临时文件路径 --> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/backend/src/main/resources/static/img/logo-light-MeterSphere.svg b/backend/src/main/resources/static/img/logo-light-MeterSphere.svg deleted file mode 100755 index 1fb78563d5..0000000000 --- a/backend/src/main/resources/static/img/logo-light-MeterSphere.svg +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/backend/src/main/resources/static/img/tapd.png b/backend/src/main/resources/static/img/tapd.png deleted file mode 100644 index 4331f89694..0000000000 Binary files a/backend/src/main/resources/static/img/tapd.png and /dev/null differ diff --git a/backend/src/main/resources/static/img/template.png b/backend/src/main/resources/static/img/template.png deleted file mode 100644 index 1edb6c8bf7..0000000000 Binary files a/backend/src/main/resources/static/img/template.png and /dev/null differ diff --git a/backend/src/main/resources/static/img/xmind.jpg b/backend/src/main/resources/static/img/xmind.jpg deleted file mode 100644 index 3cd0340ada..0000000000 Binary files a/backend/src/main/resources/static/img/xmind.jpg and /dev/null differ diff --git a/backend/src/main/resources/static/img/zentao.jpg b/backend/src/main/resources/static/img/zentao.jpg deleted file mode 100644 index 703a906898..0000000000 Binary files a/backend/src/main/resources/static/img/zentao.jpg and /dev/null differ diff --git a/frontend/.env.production b/frontend/.env.production index 80c810301f..a33fdd2479 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -2,5 +2,5 @@ ENV = 'production' # base api -VUE_APP_BASE_API = '/prod-api' +VUE_APP_BASE_API = 'http://localhost:8081/' diff --git a/frontend/package.json b/frontend/package.json index 5dd552a5d0..9cadee7c56 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,6 +7,7 @@ "private": true, "scripts": { "serve": "vue-cli-service serve", + "build": "vue-cli-service build", "build:prod": "vue-cli-service build", "build:stage": "vue-cli-service build --mode staging", "preview": "node build/index.js --preview", diff --git a/frontend/pom.xml b/frontend/pom.xml new file mode 100644 index 0000000000..42b160c006 --- /dev/null +++ b/frontend/pom.xml @@ -0,0 +1,64 @@ + + + + + dataease-server + io.dataease + 1.0 + + + 4.0.0 + frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v8.11.1 + 5.6.0 + + + + + npm install + + npm + + + + install + + + + + npm run build + + npm + + + run build + + + + + + + diff --git a/frontend/src/api/system/dept.js b/frontend/src/api/system/dept.js index 0e9ab11803..e322d2f08d 100644 --- a/frontend/src/api/system/dept.js +++ b/frontend/src/api/system/dept.js @@ -3,7 +3,17 @@ import request from '@/utils/request' export function getDeptTree(pid) { return request({ url: 'api/dept/childNodes/' + pid, - method: 'post' + method: 'post', + loading: true + }) +} + +export function loadTable(data) { + return request({ + url: 'api/dept/search', + method: 'post', + data, + loading: true }) } @@ -31,4 +41,4 @@ export function editDept(data) { }) } -export default { addDept, delDept, editDept, getDeptTree } +export default { addDept, delDept, editDept, getDeptTree, loadTable } diff --git a/frontend/src/api/system/menu.js b/frontend/src/api/system/menu.js index b46aafcc27..a093687647 100644 --- a/frontend/src/api/system/menu.js +++ b/frontend/src/api/system/menu.js @@ -3,7 +3,8 @@ import request from '@/utils/request' export function getMenusTree(pid) { return request({ url: 'api/menu/childNodes/' + pid, - method: 'post' + method: 'post', + loading: true }) } diff --git a/frontend/src/api/system/role.js b/frontend/src/api/system/role.js index 7407008c33..07be60da4e 100644 --- a/frontend/src/api/system/role.js +++ b/frontend/src/api/system/role.js @@ -3,7 +3,8 @@ import request from '@/utils/request' export function allRoles() { return request({ url: '/api/role/all', - method: 'post' + method: 'post', + loading: true }) } @@ -11,7 +12,8 @@ export function roleGrid(pageIndex, pageSize, data) { return request({ url: '/api/role/roleGrid/' + pageIndex + '/' + pageSize, method: 'post', - data + data, + loading: true }) } diff --git a/frontend/src/components/business/condition-table/index.vue b/frontend/src/components/business/condition-table/index.vue new file mode 100644 index 0000000000..f15562ef70 --- /dev/null +++ b/frontend/src/components/business/condition-table/index.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/frontend/src/lang/index.js b/frontend/src/lang/index.js index 4a3b179365..a4cc3d7d19 100644 --- a/frontend/src/lang/index.js +++ b/frontend/src/lang/index.js @@ -11,17 +11,22 @@ import zhLocale from './zh' import twLocale from './tw' import esLocale from './es' import jaLocale from './ja' +import fuZh from 'fit2cloud-ui/src/locale/lang/zh-CN' // 加载fit2cloud的内容 + +import fuEn from 'fit2cloud-ui/src/locale/lang/en_US' // 加载fit2cloud的内容 Vue.use(VueI18n) const messages = { en: { ...enLocale, - ...elementEnLocale + ...elementEnLocale, + ...fuEn }, zh: { ...zhLocale, - ...elementZhLocale + ...elementZhLocale, + ...fuZh }, tw: { ...twLocale, diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index a7dc83d283..efd0a7e737 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -80,7 +80,9 @@ export default { password: '密码', any: '随便填', thirdparty: '第三方登录', - thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!' + thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!', + expires: '登录token过期,请重新登录', + tokenError: 'token错误,请重新登录' }, commons: { upload: '上传', @@ -422,6 +424,7 @@ export default { input_email: '请输入邮箱', input_password: '请输入密码', input_phone: '请输入电话号码', + input_roles: '请选择角色', special_characters_are_not_supported: '不支持特殊字符', mobile_number_format_is_incorrect: '手机号码格式不正确', email_format_is_incorrect: '邮箱格式不正确', @@ -445,7 +448,8 @@ export default { menu: { create: '创建菜单', modify: '修改菜单', - delete: '删除菜单' + delete: '删除菜单', + delete_confirm: '确定删除菜单吗' }, organization: { create: '创建组织', @@ -587,7 +591,16 @@ export default { result_filter: '结果过滤器', x_axis: '横轴', y_axis: '纵轴', - chart: '视图' + chart: '视图', + close: '关闭', + summary: '汇总方式', + fast_calc: '快速计算', + sum: '求和', + avg: '平均', + max: '最大值', + min: '最小值', + std: '标准差', + var_samp: '方差' }, dataset: { datalist: '数据集', diff --git a/frontend/src/store/modules/user.js b/frontend/src/store/modules/user.js index ab250c4e0f..2ceab1fc30 100644 --- a/frontend/src/store/modules/user.js +++ b/frontend/src/store/modules/user.js @@ -42,6 +42,9 @@ const mutations = { }, SET_PERMISSIONS: (state, permissions) => { state.permissions = permissions + }, + SET_LOGIN_MSG: (state, msg) => { + state.loginMsg = msg } } @@ -53,6 +56,7 @@ const actions = { login({ username: username.trim(), password: password }).then(response => { const { data } = response commit('SET_TOKEN', data.token) + commit('SET_LOGIN_MSG', null) setToken(data.token) resolve() }).catch(error => { @@ -117,6 +121,9 @@ const actions = { commit('RESET_STATE') resolve() }) + }, + setLoginMsg({ commit, msg }) { + commit('SET_LOGIN_MSG', msg) } } diff --git a/frontend/src/utils/auth.js b/frontend/src/utils/auth.js index c0663e529e..033e976420 100644 --- a/frontend/src/utils/auth.js +++ b/frontend/src/utils/auth.js @@ -1,5 +1,6 @@ import Cookies from 'js-cookie' import Config from '@/settings' + const TokenKey = Config.TokenKey export function getToken() { @@ -13,3 +14,4 @@ export function setToken(token) { export function removeToken() { return Cookies.remove(TokenKey) } + diff --git a/frontend/src/utils/index.js b/frontend/src/utils/index.js index 61899c6e3a..e1d77a8393 100644 --- a/frontend/src/utils/index.js +++ b/frontend/src/utils/index.js @@ -136,3 +136,29 @@ export function param2Obj(url) { '"}' ) } + +// export function formatCondition(param) { +// if (!param) { +// return null +// } +// const condition = {} +// for (const key in param) { +// if (Object.hasOwnProperty.call(param, key)) { +// const element = param[key] +// condition[element.field] = element.value +// } +// } +// return condition +// } + +export function formatCondition(param) { + if (!param) { + return null + } + const result = { conditions: [] } + for (const [key, value] of Object.entries(param)) { + console.log(`${key}`) + result.conditions.push(value) + } + return result +} diff --git a/frontend/src/utils/message.js b/frontend/src/utils/message.js index dc0d92f324..6fb5c6d1cc 100644 --- a/frontend/src/utils/message.js +++ b/frontend/src/utils/message.js @@ -1,7 +1,7 @@ import { MessageBox, Message } from 'element-ui' - +import i18n from '@/lang' export const $alert = (message, callback, options) => { - const title = this.$t('common.message_box.alert') + const title = i18n.t('common.message_box.alert') MessageBox.alert(message, title, options).then(() => { callback() }) @@ -9,12 +9,12 @@ export const $alert = (message, callback, options) => { export const $confirm = (message, callback, options = {}) => { const defaultOptions = { - confirmButtonText: this.$t('common.button.ok'), - cancelButtonText: this.$t('common.button.cancel'), + confirmButtonText: i18n.t('common.button.ok'), + cancelButtonText: i18n.t('common.button.cancel'), type: 'warning', ...options } - const title = this.$t('common.message_box.confirm') + const title = i18n.t('common.message_box.confirm') MessageBox.confirm(message, title, defaultOptions).then(() => { callback() }) diff --git a/frontend/src/utils/permission.js b/frontend/src/utils/permission.js new file mode 100644 index 0000000000..54be75573a --- /dev/null +++ b/frontend/src/utils/permission.js @@ -0,0 +1,9 @@ +import store from '@/store' +export function checkPermission(pers) { + const permissions = store.getters.permissions + const hasPermission = pers.every(needP => { + const result = permissions.includes(needP) + return result + }) + return hasPermission +} diff --git a/frontend/src/utils/request.js b/frontend/src/utils/request.js index 2a93f3eab2..7232afaea8 100644 --- a/frontend/src/utils/request.js +++ b/frontend/src/utils/request.js @@ -4,7 +4,7 @@ import store from '@/store' import { $alert, $error } from './message' import { getToken } from '@/utils/auth' import Config from '@/settings' - +import i18n from '@/lang' import { tryShowLoading, tryHideLoading } from './loading' // import router from '@/router' @@ -44,16 +44,19 @@ service.interceptors.request.use( const checkAuth = response => { // 请根据实际需求修改 - if (response.headers['authentication-status'] === 'invalid' || response.status === 401) { - const message = this.$t('login.expires') + + if (response.headers['authentication-status'] === 'login_expire') { + const message = i18n.t('login.expires') + store.dispatch('user/setLoginMsg', message) $alert(message, () => { store.dispatch('user/logout').then(() => { location.reload() }) }) } - if (response.headers['authentication-status'] === 'login_expire') { - const message = this.$t('login.expires') + + if (response.headers['authentication-status'] === 'invalid' || response.status === 401) { + const message = i18n.t('login.tokenError') $alert(message, () => { store.dispatch('user/logout').then(() => { location.reload() diff --git a/frontend/src/utils/validate.js b/frontend/src/utils/validate.js index 1e5024e641..de31eda81e 100644 --- a/frontend/src/utils/validate.js +++ b/frontend/src/utils/validate.js @@ -18,3 +18,5 @@ export function validUsername(str) { const valid_map = ['admin', 'cyw'] return valid_map.indexOf(str.trim()) >= 0 } + +export const PHONE_REGEX = '^1[3|4|5|7|8][0-9]{9}$' diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index 4f61c83d7f..7392c1b3d2 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -15,6 +15,23 @@ export const BASE_BAR = { series: [] } -export default { - BASE_BAR +export const BASE_LINE = { + title: { + text: '' + }, + tooltip: {}, + legend: { + data: [] + }, + xAxis: { + data: [] + }, + yAxis: { + type: 'value' + }, + series: [] +} + +export default { + BASE_BAR, BASE_LINE } diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue new file mode 100644 index 0000000000..20c906e16b --- /dev/null +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/frontend/src/views/chart/components/DimensionItem.vue b/frontend/src/views/chart/components/DimensionItem.vue new file mode 100644 index 0000000000..e9812f5c10 --- /dev/null +++ b/frontend/src/views/chart/components/DimensionItem.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/frontend/src/views/chart/components/QuotaItem.vue b/frontend/src/views/chart/components/QuotaItem.vue new file mode 100644 index 0000000000..dcf0f26220 --- /dev/null +++ b/frontend/src/views/chart/components/QuotaItem.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/frontend/src/views/chart/group/Group.vue b/frontend/src/views/chart/group/Group.vue index 19e6fe3c9e..64d42e578a 100644 --- a/frontend/src/views/chart/group/Group.vue +++ b/frontend/src/views/chart/group/Group.vue @@ -7,7 +7,7 @@ {{ $t('chart.datalist') }} - + @@ -101,7 +101,7 @@ - +