feat: 设置 Excel 字段长度

This commit is contained in:
taojinlong 2021-06-07 10:17:55 +08:00
commit b42e1e2855
84 changed files with 584 additions and 453 deletions

View File

@ -31,7 +31,4 @@ public interface AuthApi {
@PostMapping("/validateName")
Boolean validateName(Map<String, String> nameDto);
@GetMapping("/test")
String test();
}

View File

@ -29,6 +29,8 @@ public class DynamicMenuDto implements Serializable {
private Integer type;
private Integer menuSort;
private Boolean isPlugin;
private Boolean noLayout;

View File

@ -19,7 +19,6 @@ 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 java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

View File

@ -13,8 +13,6 @@ public class TokenInfo implements Serializable {
private Long userId;
private Long lastLoginTime;
public String format(){
return username + "," +userId;
}

View File

@ -6,6 +6,7 @@ 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.LogUtil;
import io.dataease.i18n.Translator;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
@ -28,9 +29,6 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
public final static String expireMessage = "Login token is expire.";
/*@Autowired
private AuthUserService authUserService;*/
/**
* 判断用户是否想要登入
@ -52,22 +50,15 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
String authorization = httpServletRequest.getHeader("Authorization");
// 当没有出现登录超时 且需要刷新token 则执行刷新token
if (JWTUtils.loginExpire(authorization)){
throw new AuthenticationException(expireMessage);
throw new AuthenticationException(expireMessage);
}
if (JWTUtils.needRefresh(authorization)){
String oldAuthorization = authorization;
authorization = refreshToken(request, response);
JWTUtils.removeTokenExpire(oldAuthorization);
}
// 删除老的操作时间
JWTUtils.removeTokenExpire(authorization);
// 设置新的操作时间
JWTUtils.addTokenExpire(authorization);
JWTToken token = new JWTToken(authorization);
Subject subject = getSubject(request, response);
// 提交给realm进行登入如果错误他会抛出异常并被捕获
subject.login(token);
return true;
}
@ -82,10 +73,11 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
boolean loginSuccess = executeLogin(request, response);
return loginSuccess;
} catch (Exception e) {
LogUtil.error(e);
if (e instanceof AuthenticationException && StringUtils.equals(e.getMessage(), expireMessage)){
responseExpire(request, response);
responseExpire(request, response, e);
}else {
response401(request, response);
tokenError(request, response, e);
}
}
}
@ -107,14 +99,8 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
}
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
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.addHeader("Access-Control-Expose-Headers", "RefreshAuthorization");
@ -141,29 +127,17 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
return super.preHandle(request, response);
}
/**
* 将非法请求跳转到 /401
*/
private void response401(ServletRequest req, ServletResponse resp) {
try {
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status");
httpServletResponse.setHeader("authentication-status", "invalid");
httpServletResponse.setStatus(401);
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
private void tokenError(ServletRequest req, ServletResponse resp, Exception e1) {
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status");
httpServletResponse.setHeader("authentication-status", "invalid");
}
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());
}
private void responseExpire(ServletRequest req, ServletResponse resp, Exception e1) {
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status");
httpServletResponse.setHeader("authentication-status", "login_expire");
}
}

View File

@ -14,16 +14,14 @@ import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CodingUtil;
import io.dataease.commons.utils.ServletUtils;
/*import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
import io.dataease.plugins.xpack.display.service.DisPlayXpackService;*/
import io.dataease.i18n.Translator;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -41,11 +39,11 @@ public class AuthServer implements AuthApi {
String password = loginDto.getPassword();
SysUserEntity user = authUserService.getUserByName(username);
if (ObjectUtils.isEmpty(user)){
throw new RuntimeException("没有该用户!");
if (ObjectUtils.isEmpty(user)) {
throw new RuntimeException(Translator.get("i18n_id_or_pwd_error"));
}
if (user.getEnabled()==0){
throw new RuntimeException("用户已经失效!");
if (user.getEnabled() == 0) {
throw new RuntimeException(Translator.get("i18n_id_or_pwd_error"));
}
String realPwd = user.getPassword();
//私钥解密
@ -53,14 +51,13 @@ public class AuthServer implements AuthApi {
//md5加密
pwd = CodingUtil.md5(pwd);
if (!StringUtils.equals(pwd, realPwd)){
throw new RuntimeException("密码错误!");
if (!StringUtils.equals(pwd, realPwd)) {
throw new RuntimeException(Translator.get("i18n_id_or_pwd_error"));
}
Map<String,Object> result = new HashMap<>();
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).lastLoginTime(System.currentTimeMillis()).build();
Map<String, Object> result = new HashMap<>();
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).build();
String token = JWTUtils.sign(tokenInfo, realPwd);
// 记录token操作时间
JWTUtils.addTokenExpire(token);
result.put("token", token);
ServletUtils.setToken(token);
return result;
@ -68,7 +65,7 @@ public class AuthServer implements AuthApi {
@Override
public CurrentUserDto userInfo() {
CurrentUserDto userDto = (CurrentUserDto)SecurityUtils.getSubject().getPrincipal();
CurrentUserDto userDto = (CurrentUserDto) SecurityUtils.getSubject().getPrincipal();
if (ObjectUtils.isEmpty(userDto)) {
String token = ServletUtils.getToken();
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
@ -84,7 +81,7 @@ public class AuthServer implements AuthApi {
}
@Override
public String logout(){
public String logout() {
String token = ServletUtils.getToken();
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
authUserService.clearCache(userId);
@ -105,20 +102,5 @@ public class AuthServer implements AuthApi {
return null;
}
@Override
public String test() {
SysUserEntity userById = authUserService.getUserById(4L);
String nickName = userById.getNickName();
// System.out.println(nickName);
/* Map<String, DisPlayXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(DisPlayXpackService.class);
for (Map.Entry entry : beansOfType.entrySet()) {
Object key = entry.getKey();
DisPlayXpackService value = (DisPlayXpackService)entry.getValue();
List<SysSettingDto> sysSettingDtos = value.systemSettings();
String name = entry.getValue().getClass().getName();
System.out.println("key: "+ key + ", value: "+ name);
}*/
return "apple";
}
}

View File

@ -8,6 +8,7 @@ import io.dataease.base.mapper.ext.AuthMapper;
import io.dataease.auth.service.AuthUserService;
import io.dataease.base.mapper.ext.ExtPluginSysMenuMapper;
import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.utils.LogUtil;
import io.dataease.plugins.common.dto.PluginSysMenu;
import io.dataease.plugins.util.PluginUtils;
import org.apache.commons.collections4.CollectionUtils;
@ -17,7 +18,6 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@ -99,7 +99,7 @@ public class AuthUserServiceImpl implements AuthUserService {
})
@Override
public void clearCache(Long userId) {
LogUtil.info("正在清除用户缓存【{}】",userId);
}
@Transactional

View File

@ -14,6 +14,7 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class DynamicMenuServiceImpl implements DynamicMenuService {
@ -35,6 +36,12 @@ public class DynamicMenuServiceImpl implements DynamicMenuService {
List<DynamicMenuDto> pluginDtos = pluginSysMenus.stream().map(this::convert).collect(Collectors.toList());
dynamicMenuDtos.addAll(pluginDtos);
}
dynamicMenuDtos = dynamicMenuDtos.stream().sorted((s1, s2) -> {
int sortIndex1 = null == s1.getMenuSort() ? 999: s1.getMenuSort();
int sortIndex2 = null == s2.getMenuSort() ? 999: s2.getMenuSort();
return sortIndex1 - sortIndex2;
}).collect(Collectors.toList());
dynamicMenuDtos.sort((s1, s2) -> s1.getHidden().compareTo(s2.getHidden()));
List<DynamicMenuDto> result = buildTree(dynamicMenuDtos);
return result;
}
@ -53,6 +60,7 @@ public class DynamicMenuServiceImpl implements DynamicMenuService {
menuMeta.setIcon(sysMenu.getIcon());
dynamicMenuDto.setMeta(menuMeta);
dynamicMenuDto.setPermission(sysMenu.getPermission());
dynamicMenuDto.setMenuSort(sysMenu.getMenuSort());
dynamicMenuDto.setHidden(sysMenu.getHidden());
dynamicMenuDto.setIsPlugin(false);
return dynamicMenuDto;
@ -71,6 +79,7 @@ public class DynamicMenuServiceImpl implements DynamicMenuService {
menuMeta.setIcon(sysMenu.getIcon());
dynamicMenuDto.setMeta(menuMeta);
dynamicMenuDto.setPermission(sysMenu.getPermission());
dynamicMenuDto.setMenuSort(sysMenu.getMenuSort());
dynamicMenuDto.setHidden(sysMenu.getHidden());
dynamicMenuDto.setIsPlugin(true);
dynamicMenuDto.setNoLayout(!!sysMenu.isNoLayout());

View File

@ -11,8 +11,7 @@ import io.dataease.commons.utils.CommonBeanFactory;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.core.env.Environment;
import java.util.Date;
@ -24,7 +23,7 @@ public class JWTUtils {
// token过期时间1min (过期会自动刷新续命 目的是避免一直都是同一个token )
private static final long EXPIRE_TIME = 1*60*1000;
// 登录间隔时间10min 超过这个时间强制重新登录
private static long Login_Interval;
private static long Login_Interval;
@ -38,17 +37,10 @@ public class JWTUtils {
public static boolean verify(String token, TokenInfo tokenInfo, String secret) {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim("lastLoginTime", tokenInfo.getLastLoginTime())
.withClaim("username", tokenInfo.getUsername())
.withClaim("userId", tokenInfo.getUserId())
.build();
verifier.verify(token);
if (loginExpire(token)){
// 登录超时
throw new AuthenticationException(JWTFilter.expireMessage);
// 前端拦截 登录超时状态 直接logout
//return false;
}
return true;
}
@ -60,11 +52,10 @@ public class JWTUtils {
DecodedJWT jwt = JWT.decode(token);
String username = jwt.getClaim("username").asString();
Long userId = jwt.getClaim("userId").asLong();
Long lastLoginTime = jwt.getClaim("lastLoginTime").asLong();
if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) || ObjectUtils.isEmpty(lastLoginTime)){
if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) ){
throw new RuntimeException("token格式错误");
}
TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).lastLoginTime(lastLoginTime).build();
TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).build();
return tokenInfo;
}
@ -84,15 +75,15 @@ public class JWTUtils {
*/
public static boolean loginExpire(String token){
if (Login_Interval==0) {
// 默认超时时间是8h
int minute = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout", Integer.class, 8*60);
// 分钟换算成毫秒
Login_Interval = minute * 1000 * 60;
}
Long now = System.currentTimeMillis();
Long lastOperateTime = tokenLastOperateTime(token);
if (ObjectUtils.isEmpty(lastOperateTime)) return true;
boolean isExpire = false;
boolean isExpire = true;
if (lastOperateTime != null) {
Long now = System.currentTimeMillis();
isExpire = now - lastOperateTime > Login_Interval;
}
return isExpire;
@ -109,7 +100,7 @@ public class JWTUtils {
}
/**
* 生成签名,1min后过期
* 生成签名,5min后过期
* @param tokenInfo 用户信息
* @param secret 用户的密码
* @return 加密的token
@ -120,10 +111,8 @@ public class JWTUtils {
Algorithm algorithm = Algorithm.HMAC256(secret);
// 附带username信息
return JWT.create()
.withClaim("lastLoginTime", tokenInfo.getLastLoginTime())
.withClaim("username", tokenInfo.getUsername())
.withClaim("userId", tokenInfo.getUserId())
.withClaim("exp", date)
.withExpiresAt(date)
.sign(algorithm);
} catch (Exception e) {
@ -155,26 +144,9 @@ public class JWTUtils {
* @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);
// System.out.println("get-------"+token+" :"+expTime);
return expTime;
}
public static void removeTokenExpire(String token){
// System.out.println("remove----"+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();
// System.out.println("add-------"+token+" :"+now);
tokens_expire.put(token, now);
DecodedJWT jwt = JWT.decode(token);
Date expiresAt = jwt.getExpiresAt();
return expiresAt.getTime();
}
}

View File

@ -64,6 +64,9 @@
<if test="sort != null">
order by ${sort}
</if>
<if test="sort == null">
order by panel_group.create_time desc
</if>
</select>
<delete id="deleteCircle">

View File

@ -83,6 +83,9 @@
<if test="sort != null">
order by ${sort}
</if>
<if test="sort == null">
order by panel_template.create_time desc
</if>
</select>
<delete id="deleteCircle">

View File

@ -1,12 +1,13 @@
package io.dataease.base.mapper.ext;
import io.dataease.dto.panel.PanelViewDto;
import io.dataease.dto.panel.po.PanelViewPo;
import java.util.List;
public interface ExtPanelViewMapper {
List<PanelViewPo> groups(String userId);
List<PanelViewDto> groups(String userId);
List<PanelViewPo> views(String userId);
List<PanelViewDto> views(String userId);
}

View File

@ -2,7 +2,7 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="io.dataease.base.mapper.ext.ExtPanelViewMapper">
<resultMap id="treeNodeMap" type="io.dataease.dto.panel.po.PanelViewPo">
<resultMap id="treeNodeMap" type="io.dataease.dto.panel.PanelViewDto">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="pid" property="pid" />
@ -12,7 +12,7 @@
<select id="groups" resultMap="treeNodeMap">
select id, pid, name, `type`
select id, ifnull(pid,0) as pid, name, `type`
from (select GET_V_AUTH_MODEL_ID_P_USE (#{userId}, 'chart') cids) t,chart_group
<where>
FIND_IN_SET(chart_group.id,cids)

View File

@ -8,18 +8,30 @@
<result column="leaf" property="leaf"/>
</resultMap>
<!-- 函数嵌套会导致循环调用函数 导致查询速度变慢 所有预先经需要嵌套查询的函数分解查询-->
<select id="searchTree" resultMap="BaseResultMapDTO">
SELECT
auth.*,
authCount.children_count AS children_count,
IF
(( authCount.children_count > 0 ), 0, 1 ) AS leaf
FROM (select get_grant_auths (#{modelType},#{createBy}) cids1) t1,
( SELECT * FROM (select get_grant_auths (#{modelType},#{createBy}) cids2) t2 ,v_auth_model
FROM (select get_grant_auths (#{modelType},#{createBy}) c_auth_ids) t1,
( SELECT * FROM (select GET_V_AUTH_MODEL_WITH_PARENT(get_grant_auths (#{modelType},#{createBy}),#{modelType}) c_auth_parent_ids) t2,
<if test="withExtend == 'parent' and id != null">
(select GET_V_AUTH_MODEL_WITH_PARENT(#{id},#{modelType}) c_model_parent_ids) tmp,
</if>
<if test="withExtend == 'children' and id != null">
(select GET_V_AUTH_MODEL_WITH_CHILDREN(#{id},#{modelType}) c_model_children_ids) tmc,
</if>
<if test="name != null and name !='' and withExtend == 'parent'">
(select GET_V_AUTH_MODEL_WITH_PARENT ( (select GROUP_CONCAT(id) from
v_auth_model where model_type = #{modelType} and `name` like CONCAT('%', #{name},'%')) ,#{modelType}) c_model_parent_seartch_ids) tmsc,
</if>
v_auth_model
<where>
model_type = #{modelType}
<if test="1== withAuth">
and FIND_IN_SET(v_auth_model.id,GET_V_AUTH_MODEL_WITH_PARENT ( cids2 ,#{modelType}))
and FIND_IN_SET(v_auth_model.id,c_auth_parent_ids)
</if>
<if test="pid !=null">
and v_auth_model.pid = #{pid}
@ -29,15 +41,14 @@
and v_auth_model.id = #{id}
</if>
<if test="withExtend == 'parent' and id != null">
and FIND_IN_SET(v_auth_model.id,GET_V_AUTH_MODEL_WITH_PARENT(#{id},#{modelType}))
and FIND_IN_SET(v_auth_model.id,c_model_parent_ids)
</if>
<if test="withExtend == 'children' and id != null">
and FIND_IN_SET(v_auth_model.id,GET_V_AUTH_MODEL_WITH_CHILDREN(#{id},#{modelType}))
and FIND_IN_SET(v_auth_model.id,c_model_children_ids)
</if>
<if test="name != null and name !='' and withExtend == 'parent'">
and FIND_IN_SET(v_auth_model.id,GET_V_AUTH_MODEL_WITH_PARENT ( (select GROUP_CONCAT(id) from
v_auth_model where model_type = #{modelType} and `name` like CONCAT('%', #{name},'%')) ,#{modelType}))
and FIND_IN_SET(v_auth_model.id,c_model_parent_seartch_ids)
</if>
<if test="name != null and name =='' and withExtend == 'parent'">
@ -51,11 +62,11 @@
count( 1 ) AS `children_count`,
`authTemp`.`pid` AS `pid`
FROM
( SELECT * FROM (select get_grant_auths (#{modelType},#{createBy}) cids3) t3,v_auth_model
( SELECT * FROM (select GET_V_AUTH_MODEL_WITH_PARENT(get_grant_auths (#{modelType},#{createBy}),#{modelType}) cids3) t3,v_auth_model
<where>
model_type = #{modelType}
<if test="1== withAuth">
and FIND_IN_SET(v_auth_model.id,GET_V_AUTH_MODEL_WITH_PARENT ( cids3 ,#{modelType}))
and FIND_IN_SET(v_auth_model.id,cids3)
</if>
</where>
) authTemp
@ -65,7 +76,7 @@
auth.id = authCount.pid
<where>
<if test="1== withAuth">
(authCount.children_count>0 or FIND_IN_SET(auth.id,cids1) )
(authCount.children_count>0 or FIND_IN_SET(auth.id,c_auth_ids) )
</if>
</where>

View File

@ -26,12 +26,7 @@ public class StoreServer implements StoreApi {
}
@Override
public void remove(String storeId) {
try {
Long id = Long.parseLong(storeId);
storeService.remove(id);
} catch (Exception e) {
storeService.removeByPanelId(storeId);
}
public void remove(String panelId) {
storeService.removeByPanelId(panelId);
}
}

View File

@ -3,6 +3,7 @@ package io.dataease.controller.panel.server;
import io.dataease.base.domain.ChartView;
import io.dataease.base.domain.ChartViewWithBLOBs;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.TreeUtils;
import io.dataease.controller.panel.api.ViewApi;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.base.ConditionEntity;
@ -10,6 +11,7 @@ import io.dataease.dto.panel.PanelViewDto;
import io.dataease.dto.panel.po.PanelViewPo;
import io.dataease.service.chart.ChartViewService;
import io.dataease.service.panel.PanelViewService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@ -35,10 +37,13 @@ public class ViewServer implements ViewApi {
*/
@Override
public List<PanelViewDto> treeWithAuth() {
List<PanelViewPo> groups = panelViewService.groups();
List<PanelViewPo> views = panelViewService.views();
List<PanelViewDto> panelViewDtos = panelViewService.buildTree(groups, views);
return panelViewDtos;
List<PanelViewDto> groups = panelViewService.groups();
List<PanelViewDto> views = panelViewService.views();
if(CollectionUtils.isNotEmpty(groups)&&CollectionUtils.isNotEmpty(views)){
groups.addAll(views);
}
// List<PanelViewDto> panelViewDtos = panelViewService.buildTree(groups, views);
return TreeUtils.mergeTree(groups);
}
@Override

View File

@ -21,6 +21,7 @@ import io.dataease.dto.dataset.DataTableInfoDTO;
import io.dataease.i18n.Translator;
import io.dataease.service.dataset.DataSetGroupService;
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.springframework.transaction.annotation.Transactional;
@ -124,7 +125,11 @@ public class DatasourceService {
dbTableDTO.setEnableCheck(false);
List<DatasetGroup> parents = dataSetGroupService.getParents(datasetTable.getSceneId());
StringBuilder stringBuilder = new StringBuilder();
parents.forEach(ele -> stringBuilder.append(ele.getName()).append("/"));
parents.forEach(ele -> {
if (ObjectUtils.isNotEmpty(ele)) {
stringBuilder.append(ele.getName()).append("/");
}
});
stringBuilder.append(datasetTable.getName());
dbTableDTO.setDatasetPath(stringBuilder.toString());
break;

View File

@ -1,5 +1,6 @@
package io.dataease.dto.panel;
import io.dataease.commons.model.ITreeBase;
import lombok.Data;
import java.util.ArrayList;
@ -7,7 +8,7 @@ import java.util.List;
import java.util.Optional;
@Data
public class PanelViewDto {
public class PanelViewDto implements ITreeBase<PanelViewDto> {
private String id;

View File

@ -1,9 +1,10 @@
package io.dataease.dto.panel.po;
import io.dataease.commons.model.ITreeBase;
import lombok.Data;
@Data
public class PanelViewPo {
public class PanelViewPo{
private String id;

View File

@ -1,11 +1,9 @@
package io.dataease.plugins.config;
import io.dataease.base.domain.MyPlugin;
import io.dataease.commons.utils.DeFileUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.service.sys.PluginService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
@ -26,7 +24,7 @@ public class PluginRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
public void run(ApplicationArguments args) {
// 执行加载插件逻辑
BaseGridRequest request = new BaseGridRequest();
List<MyPlugin> plugins = pluginService.query(request);
@ -45,17 +43,14 @@ public class PluginRunner implements ApplicationRunner {
if (jarFile.exists()) {
pluginService.loadJar(jarPath, plugin);
}else {
LogUtil.error("插件错误");
LogUtil.error("插件路径不存在 {} ", jarPath);
}
} catch (Exception e) {
e.printStackTrace();
LogUtil.error(e);
//e.printStackTrace();
}
});
}
private boolean isPluginJar(File file) {
String name = file.getName();
return StringUtils.equals(DeFileUtils.getExtensionName(name), "jar");
}
}

View File

@ -82,6 +82,14 @@ public class DorisQueryProvider extends QueryProvider {
} else {
stringBuilder.append(f.getDataeaseName());
}
} else if (f.getDeExtractType() == 0) {
if (f.getDeType() == 2) {
stringBuilder.append("cast(").append(f.getDataeaseName()).append(" as decimal(20,0)) as ").append(f.getDataeaseName());
} else if (f.getDeType() == 3) {
stringBuilder.append("cast(").append(f.getDataeaseName()).append(" as decimal(20,2)) as ").append(f.getDataeaseName());
} else {
stringBuilder.append(f.getDataeaseName());
}
} else {
if (f.getDeType() == 1) {
stringBuilder.append("FROM_UNIXTIME(cast(").append(f.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(f.getDataeaseName());

View File

@ -82,6 +82,14 @@ public class MysqlQueryProvider extends QueryProvider {
} else {
stringBuilder.append(f.getOriginName());
}
} else if (f.getDeExtractType() == 0) {
if (f.getDeType() == 2) {
stringBuilder.append("cast(").append(f.getOriginName()).append(" as decimal(20,0)) as ").append(f.getOriginName());
} else if (f.getDeType() == 3) {
stringBuilder.append("cast(").append(f.getOriginName()).append(" as decimal(20,2)) as ").append(f.getOriginName());
} else {
stringBuilder.append(f.getOriginName());
}
} else {
if (f.getDeType() == 1) {
stringBuilder.append("FROM_UNIXTIME(cast(").append(f.getOriginName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(f.getOriginName());

View File

@ -813,6 +813,7 @@ public class DataSetTableService {
if (cellTypeEnum.equals(CellType.STRING)) {
if (cellType) {
tableFiled.setFieldType("TEXT");
tableFiled.setFieldSize(65533);
}
return cell.getStringCellValue();
}

View File

@ -1,8 +1,6 @@
package io.dataease.service.dataset;
import io.dataease.base.domain.DatasetTableTask;
import io.dataease.base.domain.DatasetTableTaskExample;
import io.dataease.base.domain.DatasetTableTaskLog;
import io.dataease.base.domain.*;
import io.dataease.base.mapper.DatasetTableTaskMapper;
import io.dataease.commons.constants.JobStatus;
import io.dataease.commons.constants.ScheduleType;
@ -38,7 +36,9 @@ public class DataSetTableTaskService {
private DataSetTableService dataSetTableService;
@Resource
private ExtractDataService extractDataService;
public DatasetTableTask save(DataSetTaskRequest dataSetTaskRequest) throws Exception {
checkName(dataSetTaskRequest);
DatasetTableTask datasetTableTask = dataSetTaskRequest.getDatasetTableTask();
dataSetTableService.saveIncrementalConfig(dataSetTaskRequest.getDatasetTableIncrementalConfig());
@ -60,8 +60,8 @@ public class DataSetTableTaskService {
datasetTableTask.setId(UUID.randomUUID().toString());
datasetTableTask.setCreateTime(System.currentTimeMillis());
// SIMPLE 类型提前占位
if(datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())){
if(extractDataService.updateSyncStatus(dataSetTableService.get(datasetTableTask.getTableId()))){
if (datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())) {
if (extractDataService.updateSyncStatus(dataSetTableService.get(datasetTableTask.getTableId()))) {
throw new Exception(Translator.get("i18n_sync_job_exists"));
}else {
//write log
@ -119,4 +119,22 @@ public class DataSetTableTaskService {
datasetTableTaskExample.setOrderByClause("create_time desc,name asc");
return datasetTableTaskMapper.selectByExample(datasetTableTaskExample);
}
private void checkName(DataSetTaskRequest dataSetTaskRequest) {
DatasetTableTaskExample datasetTableTaskExample = new DatasetTableTaskExample();
DatasetTableTaskExample.Criteria criteria = datasetTableTaskExample.createCriteria();
if (StringUtils.isNotEmpty(dataSetTaskRequest.getDatasetTableTask().getId())) {
criteria.andIdNotEqualTo(dataSetTaskRequest.getDatasetTableTask().getId());
}
if (StringUtils.isNotEmpty(dataSetTaskRequest.getDatasetTableTask().getTableId())) {
criteria.andTableIdEqualTo(dataSetTaskRequest.getDatasetTableTask().getTableId());
}
if (StringUtils.isNotEmpty(dataSetTaskRequest.getDatasetTableTask().getName())) {
criteria.andNameEqualTo(dataSetTaskRequest.getDatasetTableTask().getName());
}
List<DatasetTableTask> list = datasetTableTaskMapper.selectByExample(datasetTableTaskExample);
if (list.size() > 0) {
throw new RuntimeException(Translator.get("i18n_task_name_repeat"));
}
}
}

View File

@ -689,6 +689,7 @@ public class ExtractDataService {
String tmp_code = code.replace("alterColumnTypeCode", needToChangeColumnType).replace("Column_Fields", String.join(",", datasetTableFields.stream().map(DatasetTableField::getOriginName).collect(Collectors.toList())));
if(isExcel){
tmp_code = tmp_code.replace("handleExcelIntColumn", handleExcelIntColumn);
tmp_code = tmp_code.replace("handleExcelWraps", handleExcelWraps);
}else {
tmp_code = tmp_code.replace("handleExcelIntColumn", "");
}
@ -746,6 +747,14 @@ public class ExtractDataService {
" }catch (Exception e){}\n" +
" }";
private static String handleExcelWraps = " \n" +
" if(tmp != null ){\n" +
" tmp = 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" +
"import java.util.List;\n" +
"import java.io.File;\n" +
@ -775,6 +784,7 @@ public class ExtractDataService {
" List<String> fileds = Arrays.asList(\"Column_Fields\".split(\",\"));\n" +
" for (String filed : fileds) {\n" +
" String tmp = get(Fields.In, filed).getString(r);\n" +
"handleExcelWraps \n" +
"alterColumnTypeCode \n" +
"handleExcelIntColumn \n" +
" str = str + tmp;\n" +

View File

@ -26,11 +26,11 @@ public class PanelViewService {
private final static String SCENE_TYPE = "scene";
public List<PanelViewPo> groups(){
public List<PanelViewDto> groups(){
return extPanelViewMapper.groups(String.valueOf(AuthUtils.getUser().getUserId()));
}
public List<PanelViewPo> views(){
public List<PanelViewDto> views(){
return extPanelViewMapper.views(String.valueOf(AuthUtils.getUser().getUserId()));
}

View File

@ -34,14 +34,15 @@ public class StoreService {
}
public void removeByPanelId(String panelId) {
Long userId = AuthUtils.getUser().getUserId();
PanelStoreExample panelStoreExample = new PanelStoreExample();
panelStoreExample.createCriteria().andPanelGroupIdEqualTo(panelId);
panelStoreExample.createCriteria().andPanelGroupIdEqualTo(panelId).andUserIdEqualTo(userId);
panelStoreMapper.deleteByExample(panelStoreExample);
}
public void remove(Long storeId) {
/*public void remove(Long storeId) {
panelStoreMapper.deleteByPrimaryKey(storeId);
}
}*/
/**
* 按照当前用户ID查询收藏仪表板

View File

@ -29,7 +29,7 @@
<defaultCache
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="true"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="600"
@ -38,47 +38,36 @@
<cache
name="users_info"
eternal="false"
maxElementsInMemory="1000"
maxElementsOnDisk="0"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="28800"
timeToLiveSeconds="36000"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="users_roles_info"
eternal="false"
maxElementsInMemory="1000"
maxElementsOnDisk="0"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="28800"
timeToLiveSeconds="36000"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="users_permissions_info"
eternal="false"
maxElementsInMemory="1000"
maxElementsOnDisk="0"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="28800"
timeToLiveSeconds="36000"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="tokens_expire"
eternal="false"
maxElementsInMemory="1000"
maxElementsOnDisk="0"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="28800"
timeToLiveSeconds="36000"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>

View File

@ -241,9 +241,11 @@ i18n_union_field_exists=The same field can't in two dataset
i18n_cron_time_error=Start time can't greater then end time
i18n_auth_source_be_canceled=This Auth Resource Already Be Canceled
i18n_username_exists=ID is already exists
i18n_ds_name_exists=Datasource name exists
i18n_ds_name_exists=Datasource name used
i18n_sync_job_exists=There is already a synchronization task running, please try again later
i18n_datasource_check_fail=Invalid,please check config
i18n_not_find_user=Can not find user.
i18n_sql_not_empty=SQL can not be empty.
i18n_datasource_not_allow_delete_msg= datasets are using this data source and cannot be deleted
i18n_datasource_not_allow_delete_msg= datasets are using this data source and cannot be deleted
i18n_task_name_repeat=Name is used in same data set
i18n_id_or_pwd_error=Invalid ID or password

View File

@ -243,9 +243,11 @@ i18n_union_field_exists=两个数据集之间关联不能出现多次相同字
i18n_cron_time_error=开始时间不能大于结束时间
i18n_auth_source_be_canceled=当前资源授权权限已经被取消
i18n_username_exists=用户 ID 已存在
i18n_ds_name_exists=数据源名称已存在
i18n_ds_name_exists=数据源名称已被使用
i18n_sync_job_exists=已经有同步任务在运行,稍后重试
i18n_datasource_check_fail=校验失败,请检查配置信息
i18n_not_find_user=未找到用户
i18n_sql_not_empty=SQL 不能为空
i18n_datasource_not_allow_delete_msg= 个数据集正在使用此数据源,无法删除
i18n_datasource_not_allow_delete_msg= 个数据集正在使用此数据源,无法删除
i18n_task_name_repeat=同一数据集下任务名称已被使用
i18n_id_or_pwd_error=无效的ID或密码

View File

@ -243,9 +243,11 @@ i18n_union_field_exists=兩個數據集之間關聯不能出現多次相同字
i18n_cron_time_error=開始時間不能大於結束時間
i18n_auth_source_be_canceled=當前資源授權權限已經被取消
i18n_username_exists=用戶ID已存在
i18n_ds_name_exists=數據源名稱已存在
i18n_ds_name_exists=數據源名稱已被使用
i18n_sync_job_exists=已經有同步任務在運行,稍後重試
i18n_datasource_check_fail=校驗失敗,請檢查配置信息
i18n_not_find_user=未找到用戶
i18n_sql_not_empty=SQL 不能為空
i18n_datasource_not_allow_delete_msg= 個數據集正在使用此數據源,無法刪除
i18n_datasource_not_allow_delete_msg= 個數據集正在使用此數據源,無法刪除
i18n_task_name_repeat=同一數據集下任務名稱已被使用
i18n_id_or_pwd_error=無效的ID或密碼

View File

@ -38,6 +38,7 @@
"vue-axios": "3.2.4",
"vue-clipboard2": "0.3.1",
"vue-codemirror": "^4.0.6",
"vue-fullscreen": "^2.5.1",
"vue-i18n": "7.3.2",
"vue-router": "3.0.6",
"vue-uuid": "2.0.2",

View File

@ -30,7 +30,6 @@ export function querySubjectWithGroup(data) {
return request({
url: '/panel/subject/querySubjectWithGroup',
method: 'post',
loading: true,
data
})
}

View File

@ -4,7 +4,6 @@ export function tree(data) {
return request({
url: '/api/panelView/tree',
method: 'post',
loading: true,
data
})
}

View File

@ -18,7 +18,6 @@ export function showTemplateList(data) {
return request({
url: '/template/templateList',
data: data,
loading: true,
method: 'post'
})
}
@ -26,7 +25,6 @@ export function showTemplateList(data) {
export function findOne(id) {
return request({
url: '/template/findOne/' + id,
loading: true,
method: 'get'
})
}

View File

@ -108,7 +108,7 @@ export default {
},
computed: {
styleKeys() {
console.log(this.$store.state.curComponent.style)
// console.log(this.$store.state.curComponent.style)
return this.$store.state.curComponent ? Object.keys(this.$store.state.curComponent.style) : []
},
curComponent() {

View File

@ -1,11 +1,8 @@
<template>
<div style="width: 100%;height: 100vh;">
<span style="line-height: 35px; position: absolute; top:10px;right: 20px;z-index:100000">
<el-button size="mini" @click="close">
关闭
</el-button>
</span>
<Preview />
<fullscreen style="background: #ffffff" :fullscreen.sync="fullscreen" @change="fullscreenChange">
<Preview v-if="fullscreen" />
</fullscreen>
</div>
</template>
@ -16,10 +13,21 @@ import bus from '@/utils/bus'
export default {
components: { Preview },
data() {
return {
fullscreen: false
}
},
mounted() {
this.fullscreen = false
this.$nextTick(() => (this.fullscreen = true))
},
methods: {
close() {
bus.$emit('previewFullScreenClose')
fullscreenChange(fullscreen) {
if (!fullscreen) {
bus.$emit('previewFullScreenClose')
}
}
}
}

View File

@ -152,7 +152,7 @@ export default {
width: this.format(this.canvasStyleData.width, this.scaleWidth) + 'px',
height: this.format(this.canvasStyleData.height, this.scaleHeight) + 'px'
}
console.log('customStyle=>' + JSON.stringify(style))
// console.log('customStyle=>' + JSON.stringify(style))
if (this.canvasStyleData.openCommonStyle) {
if (this.canvasStyleData.panel.backgroundType === 'image' && this.canvasStyleData.panel.imageUrl) {
@ -160,7 +160,7 @@ export default {
background: `url(${this.canvasStyleData.panel.imageUrl}) no-repeat`,
...style
}
} else {
} else if (this.canvasStyleData.panel.backgroundType === 'color') {
style = {
background: this.canvasStyleData.panel.color,
...style
@ -401,7 +401,7 @@ export default {
},
filterValueChange(value) {
console.log('emit:' + value)
// console.log('emit:' + value)
},
setConditionValue(obj) {
@ -432,7 +432,7 @@ export default {
this.executeSearch()
},
executeSearch() {
console.log('当前查询条件是: ' + JSON.stringify(this.conditions))
// console.log(': ' + JSON.stringify(this.conditions))
},
format(value, scale) {
//

View File

@ -43,7 +43,7 @@
<el-button class="el-icon-document-delete" size="mini" circle @click="clearCanvas" />
</el-tooltip>
<input id="input" ref="files" type="file" hidden @change="handleFileChange">
<el-tooltip :content="$t('panel.preview')">
<el-tooltip :content="$t('panel.fullscreen_preview')">
<el-button class="el-icon-view" size="mini" circle @click="clickPreview" />
</el-tooltip>

View File

@ -69,13 +69,17 @@ export default {
changeValue(value) {
this.setCondition()
// this.inDraw && this.$emit('set-condition-value', { component: this.element, value: [value], operator: this.operator })
this.showNumber = false
this.$nextTick(() => {
if (!this.$refs.deSelect.$refs.tags || !this.options.attrs.multiple) {
return
}
const kids = this.$refs.deSelect.$refs.tags.children[0].children
let contentWidth = 0
kids.forEach(kid => {
contentWidth += kid.offsetWidth
})
this.showNumber = contentWidth > (this.$refs.deSelect.$refs.tags.clientWidth * 0.7)
this.showNumber = contentWidth > (this.$refs.deSelect.$refs.tags.clientWidth * 0.9)
})
},

View File

@ -10,7 +10,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -26,7 +26,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -22,7 +22,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -27,7 +27,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -24,7 +24,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -22,7 +22,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -22,7 +22,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -20,7 +20,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -22,7 +22,7 @@ const drawPanel = {
type: 'custom',
style: {
width: 300,
height: 35,
height: 47,
fontSize: 14,
fontWeight: 500,
lineHeight: '',

View File

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1622003025732" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7043" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M810.666667 213.333333l0 597.333333L213.333333 810.666667 213.333333 213.333333 810.666667 213.333333M810.666667 128 213.333333 128C166.4 128 128 166.4 128 213.333333l0 597.333333c0 46.933333 38.4 85.333333 85.333333 85.333333l597.333333 0c46.933333 0 85.333333-38.4 85.333333-85.333333L896 213.333333C896 166.4 857.6 128 810.666667 128L810.666667 128z" p-id="7044" fill="#bfbfbf"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1622801178544" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1323" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M2 512c0-141 114-255 255-255h510c141 0 255 114 255 255S908 767 767 767H257C116 767 2 653 2 512z m255 208.8c115.5 0 208.8-93.2 208.8-208.8S372.5 303.2 257 303.2c-115.5 0-208.8 93.2-208.8 208.8S141.5 720.8 257 720.8z" fill="#DCDFE6" p-id="1324"></path></svg>

Before

Width:  |  Height:  |  Size: 771 B

After

Width:  |  Height:  |  Size: 633 B

View File

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1622002928181" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6752" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M810.666667 128H213.333333c-46.933333 0-85.333333 38.4-85.333333 85.333333v597.333334c0 46.933333 38.4 85.333333 85.333333 85.333333h597.333334c46.933333 0 85.333333-38.4 85.333333-85.333333V213.333333c0-46.933333-38.4-85.333333-85.333333-85.333333z m-384 597.333333l-213.333334-213.333333 59.733334-59.733333 153.6 153.6 324.266666-324.266667L810.666667 341.333333l-384 384z" p-id="6753" fill="#0a7be0"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1622801110786" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="17204" data-spm-anchor-id="a313x.7781069.0.i2" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M2 512c0-141 114-255 255-255h510c141 0 255 114 255 255S908 767 767 767H257C116 767 2 653 2 512z m765 208.8c115.5 0 208.8-93.2 208.8-208.8S882.5 303.2 767 303.2c-115.5 0-208.8 93.2-208.8 208.8S651.5 720.8 767 720.8z" fill="#0a7be0" p-id="17205"></path></svg>

Before

Width:  |  Height:  |  Size: 794 B

After

Width:  |  Height:  |  Size: 675 B

View File

@ -283,7 +283,13 @@ export default {
},
datasource: 'Datasource',
char_can_not_more_50: 'Can not more 50 char',
share_success: 'Share Success'
share_success: 'Share Success',
input_id: 'Please input ID',
input_pwd: 'Please input password',
message_box: {
alert: 'Alert',
confirm: 'Confirm'
}
},
documentation: {
documentation: 'Documentation',
@ -821,7 +827,8 @@ export default {
edit_field: 'Edit Field',
preview_100_data: 'Show 100 lines data',
invalid_table_check: 'Please sync data first.',
parse_error: 'Parse Error'
parse_error: 'Parse Error',
origin_field_type: 'Origin Type'
},
datasource: {
datasource: 'Data Source',
@ -899,6 +906,8 @@ export default {
save_to_panel: 'Save to template',
export_to_panel: 'Export to template',
preview: 'Preview',
fullscreen_preview: 'Fullscreen Preview',
new_tab_preview: 'New Tab Preview',
select_panel_from_left: 'Please select Dashboard from left',
template_nale: 'Template name',
template: 'Template',

View File

@ -283,7 +283,13 @@ export default {
},
datasource: '數據源',
char_can_not_more_50: '不能超過50字符',
share_success: '分享成功'
share_success: '分享成功',
input_id: '請輸入ID',
input_pwd: '請輸入密碼',
message_box: {
alert: '警告',
confirm: '確認'
}
},
documentation: {
documentation: '文檔',
@ -659,7 +665,7 @@ export default {
rose_radius: '園角',
view_name: '視圖名稱',
name_can_not_empty: '名稱不能為空',
template_can_not_empty: '请选择仪表',
template_can_not_empty: '请选择仪表',
custom_count: '記錄數',
table_title_fontsize: '表頭字體大小',
table_item_fontsize: '表格字體大小',
@ -821,7 +827,8 @@ export default {
edit_field: '編輯自斷',
preview_100_data: '顯示前100行數據',
invalid_table_check: '非直連數據集請先完成數據同步',
parse_error: '解析錯誤'
parse_error: '解析錯誤',
origin_field_type: '原始類型'
},
datasource: {
datasource: '數據源',
@ -899,6 +906,8 @@ export default {
save_to_panel: '保存為模板',
export_to_panel: '導出為模板',
preview: '預覽',
fullscreen_preview: '全屏预览',
new_tab_preview: '新Tab页预览',
select_panel_from_left: '請從左側選擇儀表板',
template_nale: '模板名稱',
template: '模板',

View File

@ -283,7 +283,13 @@ export default {
},
datasource: '数据源',
char_can_not_more_50: '不能超过50字符',
share_success: '分享成功'
share_success: '分享成功',
input_id: '请输入ID',
input_pwd: '请输入密码',
message_box: {
alert: '警告',
confirm: '确认'
}
},
documentation: {
documentation: '文档',
@ -659,7 +665,7 @@ export default {
rose_radius: '圆角',
view_name: '视图名称',
name_can_not_empty: '名称不能为空',
template_can_not_empty: '请选择仪表',
template_can_not_empty: '请选择仪表',
custom_count: '记录数',
table_title_fontsize: '表头字体大小',
table_item_fontsize: '表格字体大小',
@ -821,7 +827,8 @@ export default {
edit_field: '编辑字段',
preview_100_data: '显示前100行数据',
invalid_table_check: '非直连数据集请先完成数据同步',
parse_error: '解析错误'
parse_error: '解析错误',
origin_field_type: '原始类型'
},
datasource: {
datasource: '数据源',
@ -899,6 +906,8 @@ export default {
save_to_panel: '保存为模板',
export_to_panel: '导出为模板',
preview: '预览',
fullscreen_preview: '全屏预览',
new_tab_preview: '新Tab页预览',
select_panel_from_left: '请从左侧选择仪表板',
template_nale: '模板名称',
template: '模板',

View File

@ -37,6 +37,10 @@ Vue.use(UmyUi)
import vcolorpicker from 'vcolorpicker'
Vue.use(vcolorpicker)
// 全屏插件
import fullscreen from 'vue-fullscreen'
Vue.use(fullscreen)
/**
* If you don't want to use mock-server
* you want to use MockJs for mock api

View File

@ -124,9 +124,9 @@ const hasCurrentRouter = (locations, routers, index) => {
// 根据权限过滤菜单
const filterRouter = routers => {
const user_permissions = store.getters.permissions
if (!user_permissions || user_permissions.length === 0) {
return routers
}
// if (!user_permissions || user_permissions.length === 0) {
// return routers
// }
const tempResults = routers.filter(router => hasPermission(router, user_permissions))
// 如果是一级菜单(目录) 没有字菜单 那就移除
return tempResults.filter(item => {

View File

@ -57,7 +57,7 @@ const checkAuth = response => {
if (response.headers['authentication-status'] === 'login_expire') {
const message = i18n.t('login.expires')
store.dispatch('user/setLoginMsg', message)
// store.dispatch('user/setLoginMsg', message)
$alert(message, () => {
store.dispatch('user/logout').then(() => {
location.reload()
@ -65,7 +65,7 @@ const checkAuth = response => {
})
}
if (response.headers['authentication-status'] === 'invalid' || response.status === 401) {
if (response.headers['authentication-status'] === 'invalid') {
const message = i18n.t('login.tokenError')
$alert(message, () => {
store.dispatch('user/logout').then(() => {
@ -85,59 +85,6 @@ const checkAuth = response => {
}
}
const checkPermission = response => {
// 请根据实际需求修改
if (response.status === 404) {
location.href = '/404'
}
if (response.status === 401) {
location.href = '/401'
}
}
// response interceptor
/**
service.interceptors.response.use(
response => {
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 20000) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
*/
// 请根据实际需求修改
service.interceptors.response.use(response => {
response.config.loading && tryHideLoading(store.getters.currentPath)
@ -148,12 +95,12 @@ service.interceptors.response.use(response => {
let msg
if (error.response) {
checkAuth(error.response)
checkPermission(error.response)
// checkPermission(error.response)
msg = error.response.data.message || error.response.data
} else {
msg = error.message
}
!error.config.hideMsg && $error(msg)
!error.config.hideMsg && (!error.response.headers['authentication-status']) && $error(msg)
return Promise.reject(error)
})
export default service

View File

@ -104,9 +104,9 @@ export const BASE_BAR = {
fontWeight: 'normal'
}
},
// grid: {
// containLabel: true
// },
grid: {
containLabel: true
},
tooltip: {},
legend: {
show: true,
@ -136,9 +136,9 @@ export const HORIZONTAL_BAR = {
fontWeight: 'normal'
}
},
// grid: {
// containLabel: true
// },
grid: {
containLabel: true
},
tooltip: {},
legend: {
show: true,
@ -169,9 +169,9 @@ export const BASE_LINE = {
fontWeight: 'normal'
}
},
// grid: {
// containLabel: true
// },
grid: {
containLabel: true
},
tooltip: {},
legend: {
show: true,
@ -203,9 +203,9 @@ export const BASE_PIE = {
fontWeight: 'normal'
}
},
// grid: {
// containLabel: true
// },
grid: {
containLabel: true
},
tooltip: {},
legend: {
show: true,
@ -239,9 +239,9 @@ export const BASE_FUNNEL = {
fontWeight: 'normal'
}
},
// grid: {
// containLabel: true
// },
grid: {
containLabel: true
},
tooltip: {
trigger: 'item'
},
@ -298,9 +298,9 @@ export const BASE_RADAR = {
fontWeight: 'normal'
}
},
// grid: {
// containLabel: true
// },
grid: {
containLabel: true
},
tooltip: {},
legend: {
show: true,
@ -336,9 +336,9 @@ export const BASE_GAUGE = {
fontWeight: 'normal'
}
},
// grid: {
// containLabel: true
// },
grid: {
containLabel: true
},
tooltip: {},
legend: {
show: true,

View File

@ -51,7 +51,7 @@
<!-- />-->
<svg-icon icon-class="scene" class="ds-icon-scene" />
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
</span>
<span v-if="hasDataPermission('manage',data.privileges)">
<span v-if="data.type ==='group'" @click.stop>
@ -114,8 +114,8 @@
<!--scene-->
<el-col v-if="sceneMode">
<el-row class="title-css">
<span class="title-text">
<el-row class="title-css scene-title">
<span class="title-text scene-title-name" :title="currGroup.name">
{{ currGroup.name }}
</span>
<el-button icon="el-icon-back" size="mini" style="float: right" circle @click="back">
@ -153,7 +153,7 @@
<span slot-scope="{ node, data }" class="custom-tree-node-list">
<span style="display: flex;flex: 1;width: 0;">
<span><svg-icon :icon-class="data.type" /></span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
</span>
<span v-if="hasDataPermission('manage',data.privileges)">
<span style="margin-left: 12px;" @click.stop>
@ -680,4 +680,16 @@ export default {
.form-item>>>.el-form-item__label{
font-size: 12px;
}
.scene-title{
width: 100%;
display: flex;
}
.scene-title-name{
width: 100%;
overflow: hidden;
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@ -38,7 +38,7 @@
@start="start1"
>
<transition-group>
<span v-for="item in dimension" :key="item.id" class="item">
<span v-for="item in dimension" :key="item.id" class="item" :title="item.name">
<svg-icon v-if="item.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="item.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="item.deType === 2 || item.deType === 3" icon-class="field_value" class="field-icon-value" />
@ -59,7 +59,7 @@
@start="start1"
>
<transition-group>
<span v-for="item in quota" :key="item.id" class="item">
<span v-for="item in quota" :key="item.id" class="item" :title="item.name">
<svg-icon v-if="item.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="item.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="item.deType === 2 || item.deType === 3" icon-class="field_value" class="field-icon-value" />
@ -101,49 +101,75 @@
@change="save(true,'chart')"
>
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
<el-tooltip effect="dark" :content="$t('chart.chart_table_normal')" placement="bottom">
<el-radio value="table-normal" label="table-normal"><svg-icon icon-class="table-normal" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_card')" placement="bottom">
<el-radio value="text" label="text"><svg-icon icon-class="text" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_bar')" placement="bottom">
<el-radio value="bar" label="bar"><svg-icon icon-class="bar" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_bar_stack')" placement="bottom">
<el-radio value="bar-stack" label="bar-stack"><svg-icon icon-class="bar-stack" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_bar_horizontal')" placement="bottom">
<el-radio value="bar-horizontal" label="bar-horizontal"><svg-icon icon-class="bar-horizontal" class="chart-icon" /></el-radio>
</el-tooltip>
<el-radio value="table-normal" label="table-normal">
<span :title="$t('chart.chart_table_normal')">
<svg-icon icon-class="table-normal" class="chart-icon" />
</span>
</el-radio>
<el-radio value="text" label="text">
<span :title="$t('chart.chart_card')">
<svg-icon icon-class="text" class="chart-icon" />
</span>
</el-radio>
<el-radio value="bar" label="bar">
<span :title="$t('chart.chart_bar')">
<svg-icon icon-class="bar" class="chart-icon" />
</span>
</el-radio>
<el-radio value="bar-stack" label="bar-stack">
<span :title="$t('chart.chart_bar_stack')">
<svg-icon icon-class="bar-stack" class="chart-icon" />
</span>
</el-radio>
<el-radio value="bar-horizontal" label="bar-horizontal">
<span :title="$t('chart.chart_bar_horizontal')">
<svg-icon icon-class="bar-horizontal" class="chart-icon" />
</span>
</el-radio>
</div>
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
<el-tooltip effect="dark" :content="$t('chart.chart_bar_stack_horizontal')" placement="bottom">
<el-radio value="bar-stack-horizontal" label="bar-stack-horizontal"><svg-icon icon-class="bar-stack-horizontal" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_line')" placement="bottom">
<el-radio value="line" label="line"><svg-icon icon-class="line" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_line_stack')" placement="bottom">
<el-radio value="line-stack" label="line-stack"><svg-icon icon-class="line-stack" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_pie')" placement="bottom">
<el-radio value="pie" label="pie"><svg-icon icon-class="pie" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_pie_rose')" placement="bottom">
<el-radio value="pie-rose" label="pie-rose"><svg-icon icon-class="pie-rose" class="chart-icon" /></el-radio>
</el-tooltip>
<el-radio value="bar-stack-horizontal" label="bar-stack-horizontal">
<span :title="$t('chart.chart_bar_stack_horizontal')">
<svg-icon icon-class="bar-stack-horizontal" class="chart-icon" />
</span>
</el-radio>
<el-radio value="line" label="line">
<span :title="$t('chart.chart_line')">
<svg-icon icon-class="line" class="chart-icon" />
</span>
</el-radio>
<el-radio value="line-stack" label="line-stack">
<span :title="$t('chart.chart_line_stack')">
<svg-icon icon-class="line-stack" class="chart-icon" />
</span>
</el-radio>
<el-radio value="pie" label="pie">
<span :title="$t('chart.chart_pie')">
<svg-icon icon-class="pie" class="chart-icon" />
</span>
</el-radio>
<el-radio value="pie-rose" label="pie-rose">
<span :title="$t('chart.chart_pie_rose')">
<svg-icon icon-class="pie-rose" class="chart-icon" />
</span>
</el-radio>
</div>
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
<el-tooltip effect="dark" :content="$t('chart.chart_funnel')" placement="bottom">
<el-radio value="funnel" label="funnel"><svg-icon icon-class="funnel" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_radar')" placement="bottom">
<el-radio value="radar" label="radar"><svg-icon icon-class="radar" class="chart-icon" /></el-radio>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('chart.chart_gauge')" placement="bottom">
<el-radio value="gauge" label="gauge"><svg-icon icon-class="gauge" class="chart-icon" /></el-radio>
</el-tooltip>
<el-radio value="funnel" label="funnel">
<span :title="$t('chart.chart_funnel')">
<svg-icon icon-class="funnel" class="chart-icon" />
</span>
</el-radio>
<el-radio value="radar" label="radar">
<span :title="$t('chart.chart_radar')">
<svg-icon icon-class="radar" class="chart-icon" />
</span>
</el-radio>
<el-radio value="gauge" label="gauge">
<span :title="$t('chart.chart_gauge')">
<svg-icon icon-class="gauge" class="chart-icon" />
</span>
</el-radio>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
</div>
@ -236,8 +262,8 @@
<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" />
<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" style=";width: 100%;height: 100%;background-color: #ece7e7; text-align: center">
<div style="font-size: 12px; color: #9ea6b2;">
<div v-if="!httpRequest.status" class="chart-error-class">
<div style="font-size: 12px; color: #9ea6b2;height: 100%;display: flex;align-items: center;justify-content: center;">
{{ $t('panel.error_data') }}<br>
{{ httpRequest.msg }}
</div>
@ -941,7 +967,10 @@ export default {
background-color: white;
display: block;
word-break: break-all;
white-space: normal;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-on-move {
@ -952,6 +981,10 @@ export default {
color: #606266;
/*background-color: rgba(35,46,64,.05);*/
background-color: white;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item + .item {
@ -1070,4 +1103,12 @@ export default {
justify-content: space-between;
align-items: center;
}
.chart-error-class{
text-align: center;
height: calc(100% - 84px);
display: flex;
align-items: center;
justify-content: center;
background-color: #ece7e7;
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<el-col>
<el-row style="height: 25px;">
<span>{{ table.name }}</span>
<span class="table-name">{{ table.name }}</span>
</el-row>
<el-divider />
<el-checkbox v-model="checkAll" :disabled="!(fields.length > 0)" :indeterminate="isIndeterminate" @change="handleCheckAllChange">{{ $t('dataset.check_all') }}</el-checkbox>
@ -105,4 +105,12 @@ export default {
.el-divider--horizontal {
margin: 12px 0
}
.table-name{
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
overflow: hidden;
}
</style>

View File

@ -42,7 +42,7 @@
<!-- />-->
<svg-icon icon-class="scene" class="ds-icon-scene" />
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
</span>
</span>
</el-tree>
@ -52,8 +52,8 @@
<!--scene-->
<el-col v-if="sceneMode" v-loading="dsLoading">
<el-row class="title-css">
<span class="title-text">
<el-row class="title-css scene-title">
<span class="title-text scene-title-name" :title="currGroup.name">
{{ currGroup.name }}
</span>
<el-button icon="el-icon-back" size="mini" style="float: right" circle @click="back">
@ -94,7 +94,7 @@
<span v-if="data.mode === 0" style="margin-left: 6px"><i class="el-icon-s-operation" /></span>
<span v-if="data.mode === 1" style="margin-left: 6px"><i class="el-icon-alarm-clock" /></span>
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
</span>
</span>
</el-tree>
@ -383,4 +383,16 @@ export default {
.title-text {
line-height: 26px;
}
.scene-title{
width: 100%;
display: flex;
}
.scene-title-name{
width: 100%;
overflow: hidden;
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@ -12,7 +12,7 @@
</el-row>
<el-divider />
<el-table :data="tableFields" size="mini" :max-height="maxHeight">
<el-table-column property="type" :label="$t('dataset.field_type')" width="180">
<el-table-column property="deType" :label="$t('dataset.field_type')" width="140">
<template slot-scope="scope">
<el-select v-model="scope.row.deType" size="mini" style="display: inline-block;width: 26px;">
<el-option
@ -46,6 +46,25 @@
</span>
</template>
</el-table-column>
<el-table-column property="deExtractType" :label="$t('dataset.origin_field_type')" width="140">
<template slot-scope="scope">
<span>
<span v-if="scope.row.deExtractType === 0">
<svg-icon v-if="scope.row.deExtractType === 0" icon-class="field_text" class="field-icon-text" />
<span class="field-class">{{ $t('dataset.text') }}</span>
</span>
<span v-if="scope.row.deExtractType === 1">
<svg-icon v-if="scope.row.deExtractType === 1" icon-class="field_time" class="field-icon-time" />
<span class="field-class">{{ $t('dataset.time') }}</span>
</span>
<span v-if="scope.row.deExtractType === 2 || scope.row.deExtractType === 3">
<svg-icon v-if="scope.row.deExtractType === 2 || scope.row.deExtractType === 3" icon-class="field_value" class="field-icon-value" />
<span v-if="scope.row.deExtractType === 2" class="field-class">{{ $t('dataset.value') }}</span>
<span v-if="scope.row.deExtractType === 3" class="field-class">{{ $t('dataset.value') + '(' + $t('dataset.float') + ')' }}</span>
</span>
</span>
</template>
</el-table-column>
<el-table-column property="name" :label="$t('dataset.field_name')" width="180">
<template slot-scope="scope">
<el-input v-model="scope.row.name" size="mini" />

View File

@ -380,7 +380,9 @@ export default {
this.calHeight()
},
created() {
this.timer = setInterval(this.listTaskLog, 5000)
this.timer = setInterval(() => {
this.listTaskLog(false)
}, 5000)
},
beforeDestroy() {
clearInterval(this.timer)
@ -461,10 +463,10 @@ export default {
post('/dataset/table/incrementalConfig', { tableId: this.table.id }).then(response => {
this.incrementalConfig = response.data
this.incrementalUpdateType = 'incrementalAdd'
console.log(this.sql);
console.log(this.sql)
if (this.incrementalConfig.incrementalAdd) {
this.sql = this.incrementalConfig.incrementalAdd
}else {
} else {
this.sql = ''
}
})
@ -543,8 +545,8 @@ export default {
this.taskForm.cron = '0 0 * ? * * *'
}
},
listTaskLog() {
post('/dataset/taskLog/list/' + this.page.currentPage + '/' + this.page.pageSize, { tableId: this.table.id }).then(response => {
listTaskLog(loading = true) {
post('/dataset/taskLog/list/' + this.page.currentPage + '/' + this.page.pageSize, { tableId: this.table.id }, loading).then(response => {
this.taskLogData = response.data.listObject
this.page.total = response.data.itemCount
})

View File

@ -51,7 +51,7 @@
<!-- />-->
<svg-icon icon-class="scene" class="ds-icon-scene" />
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
</span>
<span v-if="hasDataPermission('manage',data.privileges)">
<span v-if="data.type ==='group'" @click.stop>
@ -73,7 +73,7 @@
</el-dropdown-menu>
</el-dropdown>
</span>
<span style="margin-left: 12px;" @click.stop >
<span style="margin-left: 12px;" @click.stop>
<el-dropdown trigger="click" size="small" @command="clickMore">
<span class="el-dropdown-link">
<el-button
@ -82,7 +82,7 @@
size="small"
/>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('rename',data,node)">
{{ $t('dataset.rename') }}
</el-dropdown-item>
@ -117,8 +117,8 @@
<!--scene-->
<el-col v-if="sceneMode">
<el-row class="title-css">
<span class="title-text">
<el-row class="title-css scene-title">
<span class="title-text scene-title-name" :title="currGroup.name">
{{ currGroup.name }}
</span>
<el-button icon="el-icon-back" size="mini" style="float: right" circle @click="back">
@ -191,10 +191,10 @@
<span v-if="data.mode === 0" style="margin-left: 6px"><i class="el-icon-s-operation" /></span>
<span v-if="data.mode === 1" style="margin-left: 6px"><i class="el-icon-alarm-clock" /></span>
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
</span>
<span v-if="hasDataPermission('manage',data.privileges)">
<span style="margin-left: 12px;" @click.stop >
<span style="margin-left: 12px;" @click.stop>
<el-dropdown trigger="click" size="small" @command="clickMore">
<span class="el-dropdown-link">
<el-button
@ -203,7 +203,7 @@
size="small"
/>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('editTable',data,node)">
{{ $t('dataset.rename') }}
</el-dropdown-item>
@ -621,4 +621,16 @@ export default {
.title-text {
line-height: 26px;
}
.scene-title{
width: 100%;
display: flex;
}
.scene-title-name{
width: 100%;
overflow: hidden;
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@ -49,43 +49,43 @@
<script>
import { encrypt } from '@/utils/rsaEncrypt'
import { validateUserName } from '@/api/user'
// import { validateUserName } from '@/api/user'
import { getSysUI } from '@/utils/auth'
export default {
name: 'Login',
data() {
const validateUsername = (rule, value, callback) => {
const userName = value.trim()
validateUserName({ userName: userName }).then(res => {
if (res.data) {
callback()
} else {
callback(this.$t('login.username_error'))
}
}).catch(() => {
callback(this.$t('login.username_error'))
})
// if (!validUsername(value)) {
// callback(new Error('Please enter the correct user name'))
// const validateUsername = (rule, value, callback) => {
// const userName = value.trim()
// validateUserName({ userName: userName }).then(res => {
// if (res.data) {
// callback()
// } else {
// callback(this.$t('login.username_error'))
// }
// }).catch(() => {
// callback(this.$t('login.username_error'))
// })
// // if (!validUsername(value)) {
// // callback(new Error('Please enter the correct user name'))
// // } else {
// // callback()
// // }
// }
// const validatePassword = (rule, value, callback) => {
// if (value.length < 8) {
// callback(this.$t('login.password_error'))
// } else {
// callback()
// }
}
const validatePassword = (rule, value, callback) => {
if (value.length < 8) {
callback(this.$t('login.password_error'))
} else {
callback()
}
}
// }
return {
loginForm: {
username: '',
password: ''
},
loginRules: {
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
password: [{ required: true, trigger: 'blur', validator: validatePassword }]
username: [{ required: true, trigger: 'blur', message: this.$t('commons.input_id') }],
password: [{ required: true, trigger: 'blur', message: this.$t('commons.input_pwd') }]
},
loading: false,
passwordType: 'password',

View File

@ -106,7 +106,7 @@ export default {
reader.readAsDataURL(file.raw)
},
upload(file) {
console.log('this is upload')
// console.log('this is upload')
}
}
}

View File

@ -1,6 +1,6 @@
<template>
<el-row>
<el-row v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<el-row v-loading="slidersLoading">
<el-col :span="2">
<span>&nbsp;</span>
<ul class="direction">
@ -100,6 +100,7 @@ export default {
data() {
return {
sliders: [],
slidersLoading: false,
sliderWidth: 240,
imgWidth: 240,
currentIndex: 1,
@ -150,8 +151,10 @@ export default {
})
},
querySubjectWithGroup() {
this.slidersLoading = true
querySubjectWithGroup({}).then(response => {
this.sliders = response.data
this.slidersLoading = false
})
},
move(offset, direction, speed) {

View File

@ -168,7 +168,7 @@ export default {
this.$emit('templateEdit', this.template)
},
handleDelete() {
console.log('handleDelete')
// console.log('handleDelete')
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<el-col>
<el-col v-loading="loading">
<el-row style="margin-top: 5px">
<el-row style="margin-left: 5px;margin-right: 5px">
<el-input
@ -42,14 +42,14 @@
</span>
</el-tree>
</el-row>
<!-- <el-row v-if="detailItem&&detailItem.snapshot" class="detail-class">-->
<!-- <el-card class="filter-card-class">-->
<!-- <div slot="header" class="button-div-class">-->
<!-- <span>{{ detailItem.name }}</span>-->
<!-- </div>-->
<!-- <img draggable="false" class="view-list-thumbnails" :src="detailItem.snapshot" alt="">-->
<!-- </el-card>-->
<!-- </el-row>-->
<!-- <el-row v-if="detailItem&&detailItem.snapshot" class="detail-class">-->
<!-- <el-card class="filter-card-class">-->
<!-- <div slot="header" class="button-div-class">-->
<!-- <span>{{ detailItem.name }}</span>-->
<!-- </div>-->
<!-- <img draggable="false" class="view-list-thumbnails" :src="detailItem.snapshot" alt="">-->
<!-- </el-card>-->
<!-- </el-row>-->
</el-row>
</el-col>
</template>
@ -68,7 +68,8 @@ export default {
},
data: [],
showdetail: false,
detailItem: null
detailItem: null,
loading: false
}
},
watch: {
@ -91,8 +92,10 @@ export default {
},
loadData() {
const param = {}
this.loading = true
tree(param).then(res => {
this.data = res.data
this.loading = false
})
},
handleDragStart(node, ev) {

View File

@ -141,7 +141,7 @@
:fullscreen="true"
custom-class="preview-dialog"
>
<PreviewFullScreen />
<PreviewFullScreen :fullscreen="previewVisible" />
</el-dialog>
</el-row>
</template>

View File

@ -67,7 +67,7 @@ export default {
return data
},
remove(row) {
deleteEnshrine(row.storeId).then(res => {
deleteEnshrine(row.panelGroupId).then(res => {
this.initData()
this.panelInfo && this.panelInfo.id && row.panelGroupId === this.panelInfo.id && this.setMainNull()
})

View File

@ -1,6 +1,6 @@
<template>
<de-container class="de-dialog-container">
<de-container v-loading="$store.getters.loadingMap[$store.getters.currentPath]" class="de-dialog-container">
<de-aside-container :show-drag-bar="false" class="ms-aside-container">
<el-tabs v-model="activeName" class="filter-dialog-tabs">
<el-tab-pane :lazy="true" class="de-tab" :label="$t('panel.select_by_table')" name="dataset">
@ -43,6 +43,7 @@
<div v-else-if="showDomType === 'field'">
<draggable
v-model="fieldDatas"
:disabled="selectField.length !== 0"
:options="{group:{name: 'dimension',pull:'clone'},sort: true}"
animation="300"
:move="onMove"
@ -93,6 +94,7 @@
<div v-else-if="comShowDomType === 'field'">
<draggable
v-model="comFieldDatas"
:disabled="selectField.length !== 0"
:options="{group:{name: 'dimension',pull:'clone'},sort: true}"
animation="300"
:move="onMove"
@ -119,9 +121,9 @@
<el-col :span="24">
<div class="filter-field">
<div class="field-content">
<div class="field-content-left">
<!-- <div class="field-content-left">
<div class="field-content-text">{{ $t('panel.field') }} </div>
</div>
</div> -->
<div class="field-content-right">
<el-row style="display:flex;height: 32px;">

View File

@ -1,5 +1,5 @@
<template>
<el-row v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<el-row v-loading="loading">
<el-row v-if="editPanel.optType==='new' && editPanel.panelInfo.nodeType==='panel'">
<el-col :span="18" style="height: 40px">
<el-radio v-model="inputType" label="self"> {{ $t('panel.custom') }}</el-radio>
@ -46,6 +46,7 @@ export default {
},
data() {
return {
loading: false,
inputType: 'self',
fieldName: 'name',
tableRadio: null,
@ -92,8 +93,10 @@ export default {
level: '-1',
withChildren: true
}
this.loading = true
showTemplateList(request).then(res => {
this.templateList = res.data
this.loading = false
})
},
handleExceed(file) {
@ -106,7 +109,7 @@ export default {
this.$warning(this.$t('chart.name_can_not_empty'))
return false
}
if (!this.editPanel.panelInfo.panelData) {
if (!this.editPanel.panelInfo.panelData && this.editPanel.optType === 'new' && this.inputType === 'copy') {
this.$warning(this.$t('chart.template_can_not_empty'))
return false
}

View File

@ -323,12 +323,12 @@ export default {
panelType: 'self',
nodeType: null,
children: [],
sort: 'node_type desc,name asc'
sort: 'create_time desc,node_type desc,name asc'
},
tableForm: {
name: '',
mode: '',
sort: 'node_type asc,create_time desc,name asc'
sort: 'create_time desc,node_type asc,create_time desc,name asc'
},
groupFormRules: {
name: [

View File

@ -19,8 +19,14 @@
</el-tooltip>
</span>
<span style="float: right;margin-right: 10px">
<el-tooltip :content="$t('panel.preview')">
<el-button class="el-icon-view" size="mini" circle @click="clickPreview" />
<el-tooltip :content="$t('panel.fullscreen_preview')">
<el-button class="el-icon-view" size="mini" circle @click="clickFullscreen" />
</el-tooltip>
</span>
<span style="float: right;margin-right: 10px">
<el-tooltip :content="$t('panel.new_tab_preview')">
<el-button class="el-icon-data-analysis" size="mini" circle @click="newTab" />
</el-tooltip>
</span>
@ -41,7 +47,9 @@
<!-- 仪表板预览区域-->
<el-row class="panel-design-preview">
<div ref="imageWrapper" style="width: 100%;height: 100%">
<Preview v-if="showMain" />
<fullscreen style="background: #ffffff;height: 100%" :fullscreen.sync="fullscreen">
<Preview v-if="showMain" />
</fullscreen>
</div>
</el-row>
</el-col>
@ -78,7 +86,8 @@ export default {
templateInfo: {},
templateSaveTitle: '保存为模板',
templateSaveShow: false,
hasStar: false
hasStar: false,
fullscreen: false
}
},
computed: {
@ -103,7 +112,10 @@ export default {
mounted() {
},
methods: {
clickPreview() {
clickFullscreen() {
this.fullscreen = true
},
newTab() {
const url = '#/preview/' + this.$store.state.panel.panelInfo.id
window.open(url, '_blank')
},

View File

@ -139,17 +139,24 @@ export default {
this.showTemplateEditDialog('edit', templateInfo)
},
saveTemplateEdit(templateEditForm) {
save(templateEditForm).then(response => {
this.$message({
message: this.$t('commons.save_success'),
type: 'success',
showClose: true
})
this.editTemplate = false
this.getTree()
this.$refs['templateEditForm'].validate((valid) => {
if (valid) {
save(templateEditForm).then(response => {
this.close()
this.$message({
message: this.$t('commons.save_success'),
type: 'success',
showClose: true
})
this.getTree()
})
} else {
return false
}
})
},
close() {
this.$refs['templateEditForm'].resetFields()
this.editTemplate = false
},
getTree() {

View File

@ -10,6 +10,7 @@
<el-tabs v-model="targetActiveName" :class="{'de-search-header': showTargetSearchInput}" @tab-click="handleClick">
<el-tab-pane v-for="(targetInfo, index) in targetInfoArray" :key="index" :lazy="true" :label="targetInfo.tabName" :name="targetInfo.authType">
<lazy-tree
v-if="targetActiveName===targetInfo.authType"
:active-name="targetActiveName"
:filter-text="targetFilterText"
:data-info="targetInfo"
@ -35,6 +36,7 @@
:data-info="sourceInfo"
show-extent
:auth-condition="authCondition"
:attach-active-name="targetActiveName"
/>
</el-tab-pane>
</el-tabs>
@ -115,7 +117,7 @@ export default {
head: this.$t('auth.menuAuthHead'),
direction: 'source',
authType: 'menu',
authTargets: 'role'
authTargets: 'dept,role,user'
}
],
targetActiveName: null,
@ -170,11 +172,11 @@ export default {
this.$emit('close-grant', 0)
},
authNodeClick(val) {
console.log('authNodeClick')
// console.log('authNodeClick')
this.authCondition = val
},
clickAuth(auth) {
console.log('clickAuth')
// console.log('clickAuth')
}
}
}

View File

@ -147,11 +147,11 @@ export default {
this.$emit('close-grant', 0)
},
authNodeClick(val) {
console.log('authNodeClick')
// console.log('authNodeClick')
this.authCondition = val
},
clickAuth(auth) {
console.log('clickAuth')
// console.log('clickAuth')
}
}
}

View File

@ -1,5 +1,5 @@
<template xmlns:el-col="http://www.w3.org/1999/html">
<el-col class="tree-main">
<el-col v-loading="loading" class="tree-main">
<el-row v-if="showExtent" class="tree-head">
<span style="float: left;padding-left: 10px">{{ dataInfo.head }}</span>
<span v-for="auth in defaultAuthDetails" :key="auth.privilegeName" class="auth-span">
@ -67,6 +67,7 @@ export default {
type: String,
required: true
},
attachActiveName: String,
defaultProps: {
type: Object,
required: false,
@ -85,6 +86,7 @@ export default {
},
data() {
return {
loading: false,
treeData: [],
changeIndex: 0,
timeMachine: null,
@ -119,6 +121,12 @@ export default {
this.loadAuth()
},
deep: true
},
attachActiveName: {
handler(newVal, oldVla) {
this.authDetails = {}
},
deep: true
}
},
created() {
@ -138,7 +146,8 @@ export default {
// authTarget authSource
authQueryCondition = {
authTarget: this.authCondition.id,
authTargetType: this.authCondition.type
authTargetType: this.authCondition.type,
authSourceType: this.dataInfo.authType
}
} else {
authQueryCondition = {
@ -248,9 +257,11 @@ export default {
authDetail: auth
}
}
this.loading = true
authChange(authChangeCondition).then(res => {
//
this.loadAuth()
this.loading = false
})
},
//
@ -280,6 +291,7 @@ export default {
.tree-main{
height: calc(100vh - 210px);
border: 1px solid #e6e6e6;
overflow-y: auto!important;
}
.tree-head{
height: 30px;

View File

@ -32,7 +32,7 @@ export default {
},
methods: {
handleClick() {
console.log('===>handleClick')
// console.log('===>handleClick')
}
}

View File

@ -51,7 +51,7 @@ export default {
created() {
if (this.jsname && this.menuid) {
this.showAsync = true
console.log(this.jsname)
// console.log(this.jsname)
this.url = this.baseUrl + this.menuid
// this.url = 'http://localhost:8081/PluginDemo.js'
// this.url = 'http://localhost:8081/SystemParam.js'

View File

@ -181,7 +181,7 @@ export default {
this.depts = null
this.formType = 'add'
this.form = Object.assign({}, this.defaultForm)
console.log(this.form)
// console.log(this.form)
},
edit(row) {
this.depts = null

View File

@ -3,7 +3,7 @@
<complex-table
:data="data"
:columns="columns"
local-key="userGrid"
:search-config="searchConfig"
:pagination-config="paginationConfig"
@select="select"