forked from github/dataease
refactor: 解决冲突
This commit is contained in:
commit
5b86ad0907
1
.gitignore
vendored
1
.gitignore
vendored
@ -40,6 +40,7 @@ yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.lh
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
|
@ -252,11 +252,11 @@
|
||||
<version>20171018</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.13</version>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<!-- 反射工具包 -->
|
||||
<dependency>
|
||||
<groupId>net.oneandone.reflections8</groupId>
|
||||
@ -337,10 +337,10 @@
|
||||
<version>5.7.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-ldap</artifactId>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>ru.yandex.clickhouse</groupId>
|
||||
|
@ -4,9 +4,7 @@ import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
||||
import io.dataease.auth.api.dto.LoginDto;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@ -46,4 +44,9 @@ public interface AuthApi {
|
||||
@PostMapping("/isOpenLdap")
|
||||
boolean isOpenLdap();
|
||||
|
||||
|
||||
@ApiOperation("是否开启oidc")
|
||||
@PostMapping("/isOpenOidc")
|
||||
boolean isOpenOidc();
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ public class TokenInfo implements Serializable {
|
||||
|
||||
private Long userId;
|
||||
|
||||
/* private String idToken; */
|
||||
|
||||
public String format(){
|
||||
return username + "," +userId;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.web.filter.authc.LogoutFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
|
@ -21,17 +21,19 @@ import io.dataease.plugins.util.PluginUtils;
|
||||
import io.dataease.plugins.xpack.ldap.dto.request.LdapValidateRequest;
|
||||
import io.dataease.plugins.xpack.ldap.dto.response.ValidateResult;
|
||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@RestController
|
||||
public class AuthServer implements AuthApi {
|
||||
|
||||
@ -113,6 +115,16 @@ public class AuthServer implements AuthApi {
|
||||
@Override
|
||||
public String logout() {
|
||||
String token = ServletUtils.getToken();
|
||||
|
||||
if (isOpenOidc()) {
|
||||
HttpServletRequest request = ServletUtils.request();
|
||||
String idToken = request.getHeader("IdToken");
|
||||
if (StringUtils.isNotBlank(idToken)) {
|
||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
||||
oidcXpackService.logout(idToken);
|
||||
}
|
||||
|
||||
}
|
||||
if (StringUtils.isEmpty(token) || StringUtils.equals("null", token) || StringUtils.equals("undefined", token)) {
|
||||
return "success";
|
||||
}
|
||||
@ -144,6 +156,15 @@ public class AuthServer implements AuthApi {
|
||||
return open;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpenOidc() {
|
||||
Boolean licValid = PluginUtils.licValid();
|
||||
if(!licValid) return false;
|
||||
return authUserService.supportOidc();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*@Override
|
||||
public Boolean isLogin() {
|
||||
return null;
|
||||
|
@ -13,6 +13,8 @@ public interface AuthUserService {
|
||||
|
||||
SysUserEntity getUserByName(String username);
|
||||
|
||||
SysUserEntity getUserBySub(String sub);
|
||||
|
||||
List<String> roles(Long userId);
|
||||
|
||||
List<String> permissions(Long userId);
|
||||
@ -23,6 +25,8 @@ public interface AuthUserService {
|
||||
|
||||
boolean supportLdap();
|
||||
|
||||
Boolean supportOidc();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import io.dataease.commons.constants.AuthConstants;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
@ -19,6 +21,7 @@ import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -49,6 +52,11 @@ public class AuthUserServiceImpl implements AuthUserService {
|
||||
return authMapper.findUserByName(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUserEntity getUserBySub(String sub) {
|
||||
return authMapper.findUserBySub(sub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> roles(Long userId){
|
||||
return authMapper.roleCodes(userId);
|
||||
@ -107,8 +115,21 @@ public class AuthUserServiceImpl implements AuthUserService {
|
||||
|
||||
@Override
|
||||
public boolean supportLdap() {
|
||||
Map<String, LdapXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LdapXpackService.class));
|
||||
if(beansOfType.keySet().size() == 0) return false;
|
||||
LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class);
|
||||
if(ObjectUtils.isEmpty(ldapXpackService)) return false;
|
||||
return ldapXpackService.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean supportOidc() {
|
||||
Map<String, OidcXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((OidcXpackService.class));
|
||||
if(beansOfType.keySet().size() == 0) return false;
|
||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
||||
if(ObjectUtils.isEmpty(oidcXpackService)) return false;
|
||||
return oidcXpackService.isSuuportOIDC();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -56,9 +56,15 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
// filterChainDefinitionMap.put("/axios.map", ANON);
|
||||
|
||||
filterChainDefinitionMap.put("/api/auth/login", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/logout", ANON);
|
||||
// filterChainDefinitionMap.put("/api/auth/logout", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/validateName", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/isOpenLdap", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/isOpenOidc", ANON);
|
||||
filterChainDefinitionMap.put("/api/pluginCommon/component/*", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/oidc/authInfo", ANON);
|
||||
filterChainDefinitionMap.put("/sso/callBack*", ANON);
|
||||
|
||||
|
||||
filterChainDefinitionMap.put("/unauth", ANON);
|
||||
filterChainDefinitionMap.put("/display/**", ANON);
|
||||
filterChainDefinitionMap.put("/tokenExpired", ANON);
|
||||
|
@ -2,16 +2,18 @@ package io.dataease.auth.util;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.JWTCreator.Builder;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.jwt.interfaces.Verification;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.entity.TokenInfo.TokenInfoBuilder;
|
||||
import io.dataease.commons.utils.CommonBeanFactory;
|
||||
import io.dataease.exception.DataEaseException;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@ -34,10 +36,13 @@ public class JWTUtils {
|
||||
*/
|
||||
public static boolean verify(String token, TokenInfo tokenInfo, String secret) {
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
Verification verification = JWT.require(algorithm)
|
||||
.withClaim("username", tokenInfo.getUsername())
|
||||
.withClaim("userId", tokenInfo.getUserId())
|
||||
.build();
|
||||
.withClaim("userId", tokenInfo.getUserId());
|
||||
/* if (StringUtils.isNotBlank(tokenInfo.getIdToken())) {
|
||||
verification.withClaim("idToken", tokenInfo.getIdToken());
|
||||
} */
|
||||
JWTVerifier verifier = verification.build();
|
||||
verifier.verify(token);
|
||||
return true;
|
||||
}
|
||||
@ -50,10 +55,15 @@ public class JWTUtils {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
String username = jwt.getClaim("username").asString();
|
||||
Long userId = jwt.getClaim("userId").asLong();
|
||||
// String idToken = jwt.getClaim("idToken").asString();
|
||||
if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) ){
|
||||
DataEaseException.throwException("token格式错误!");
|
||||
}
|
||||
TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).build();
|
||||
TokenInfoBuilder tokenInfoBuilder = TokenInfo.builder().username(username).userId(userId);
|
||||
/* if (StringUtils.isNotBlank(idToken)) {
|
||||
tokenInfoBuilder.idToken(idToken);
|
||||
} */
|
||||
TokenInfo tokenInfo = tokenInfoBuilder.build();
|
||||
return tokenInfo;
|
||||
}
|
||||
|
||||
@ -107,12 +117,14 @@ public class JWTUtils {
|
||||
try {
|
||||
Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
// 附带username信息
|
||||
return JWT.create()
|
||||
Builder builder = JWT.create()
|
||||
.withClaim("username", tokenInfo.getUsername())
|
||||
.withClaim("userId", tokenInfo.getUserId())
|
||||
.withExpiresAt(date)
|
||||
.sign(algorithm);
|
||||
.withClaim("userId", tokenInfo.getUserId());
|
||||
/* if (StringUtils.isNotBlank(tokenInfo.getIdToken())) {
|
||||
builder.withClaim("idToken", tokenInfo.getIdToken());
|
||||
} */
|
||||
return builder.withExpiresAt(date).sign(algorithm);
|
||||
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
@ -39,5 +39,7 @@ public class SysUser implements Serializable {
|
||||
|
||||
private Integer from;
|
||||
|
||||
private String sub;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -1213,6 +1213,76 @@ public class SysUserExample {
|
||||
addCriterion("`from` not between", value1, value2, "from");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubIsNull() {
|
||||
addCriterion("sub is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubIsNotNull() {
|
||||
addCriterion("sub is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubEqualTo(String value) {
|
||||
addCriterion("sub =", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubNotEqualTo(String value) {
|
||||
addCriterion("sub <>", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubGreaterThan(String value) {
|
||||
addCriterion("sub >", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("sub >=", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubLessThan(String value) {
|
||||
addCriterion("sub <", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubLessThanOrEqualTo(String value) {
|
||||
addCriterion("sub <=", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubLike(String value) {
|
||||
addCriterion("sub like", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubNotLike(String value) {
|
||||
addCriterion("sub not like", value, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubIn(List<String> values) {
|
||||
addCriterion("sub in", values, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubNotIn(List<String> values) {
|
||||
addCriterion("sub not in", values, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubBetween(String value1, String value2) {
|
||||
addCriterion("sub between", value1, value2, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSubNotBetween(String value1, String value2) {
|
||||
addCriterion("sub not between", value1, value2, "sub");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
@ -19,6 +19,7 @@
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="language" jdbcType="VARCHAR" property="language" />
|
||||
<result column="from" jdbcType="INTEGER" property="from" />
|
||||
<result column="sub" jdbcType="VARCHAR" property="sub" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
@ -81,7 +82,7 @@
|
||||
<sql id="Base_Column_List">
|
||||
user_id, dept_id, username, nick_name, gender, phone, email, `password`, is_admin,
|
||||
enabled, create_by, update_by, pwd_reset_time, create_time, update_time, `language`,
|
||||
`from`
|
||||
`from`, sub
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.dataease.base.domain.SysUserExample" resultMap="BaseResultMap">
|
||||
select
|
||||
@ -119,13 +120,15 @@
|
||||
email, `password`, is_admin,
|
||||
enabled, create_by, update_by,
|
||||
pwd_reset_time, create_time, update_time,
|
||||
`language`, `from`)
|
||||
`language`, `from`, sub
|
||||
)
|
||||
values (#{userId,jdbcType=BIGINT}, #{deptId,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR},
|
||||
#{nickName,jdbcType=VARCHAR}, #{gender,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR},
|
||||
#{email,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{isAdmin,jdbcType=BIT},
|
||||
#{enabled,jdbcType=BIGINT}, #{createBy,jdbcType=VARCHAR}, #{updateBy,jdbcType=VARCHAR},
|
||||
#{pwdResetTime,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||
#{language,jdbcType=VARCHAR}, #{from,jdbcType=INTEGER})
|
||||
#{language,jdbcType=VARCHAR}, #{from,jdbcType=INTEGER}, #{sub,jdbcType=VARCHAR}
|
||||
)
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.dataease.base.domain.SysUser">
|
||||
insert into sys_user
|
||||
@ -181,6 +184,9 @@
|
||||
<if test="from != null">
|
||||
`from`,
|
||||
</if>
|
||||
<if test="sub != null">
|
||||
sub,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="userId != null">
|
||||
@ -234,6 +240,9 @@
|
||||
<if test="from != null">
|
||||
#{from,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="sub != null">
|
||||
#{sub,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.dataease.base.domain.SysUserExample" resultType="java.lang.Long">
|
||||
@ -296,6 +305,9 @@
|
||||
<if test="record.from != null">
|
||||
`from` = #{record.from,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.sub != null">
|
||||
sub = #{record.sub,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
@ -319,7 +331,8 @@
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
`language` = #{record.language,jdbcType=VARCHAR},
|
||||
`from` = #{record.from,jdbcType=INTEGER}
|
||||
`from` = #{record.from,jdbcType=INTEGER},
|
||||
sub = #{record.sub,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
@ -375,6 +388,9 @@
|
||||
<if test="from != null">
|
||||
`from` = #{from,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="sub != null">
|
||||
sub = #{sub,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where user_id = #{userId,jdbcType=BIGINT}
|
||||
</update>
|
||||
@ -395,7 +411,8 @@
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
`language` = #{language,jdbcType=VARCHAR},
|
||||
`from` = #{from,jdbcType=INTEGER}
|
||||
`from` = #{from,jdbcType=INTEGER},
|
||||
sub = #{sub,jdbcType=VARCHAR}
|
||||
where user_id = #{userId,jdbcType=BIGINT}
|
||||
</update>
|
||||
</mapper>
|
@ -25,6 +25,8 @@ public interface AuthMapper {
|
||||
|
||||
SysUserEntity findUserByName(@Param("username") String username);
|
||||
|
||||
SysUserEntity findUserBySub(@Param("sub") String sub);
|
||||
|
||||
|
||||
List<CurrentRoleDto> roles(@Param("userId") Long userId);
|
||||
|
||||
|
@ -28,6 +28,10 @@
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin from sys_user where username = #{username}
|
||||
</select>
|
||||
|
||||
<select id="findUserBySub" resultMap="baseMap">
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin from sys_user where sub = #{sub}
|
||||
</select>
|
||||
|
||||
<select id="roleCodes" resultType="String">
|
||||
select r.id from sys_role r
|
||||
left join sys_users_roles sur on sur.role_id = r.role_id
|
||||
|
@ -6,6 +6,7 @@ public class AuthConstants {
|
||||
public final static String USER_CACHE_NAME = "users_info";
|
||||
public final static String USER_ROLE_CACHE_NAME = "users_roles_info";
|
||||
public final static String USER_PERMISSION_CACHE_NAME = "users_permissions_info";
|
||||
public final static String ID_TOKEN_KEY = "IdToken";
|
||||
|
||||
|
||||
}
|
||||
|
@ -45,9 +45,12 @@ public class DefaultLicenseService {
|
||||
}
|
||||
return f2CLicenseResponse;
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
return F2CLicenseResponse.invalid(e.getMessage());
|
||||
LogUtil.error(e.getMessage());
|
||||
// e.printStackTrace();
|
||||
// return F2CLicenseResponse.invalid(e.getMessage());
|
||||
return F2CLicenseResponse.noRecord();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,7 +95,7 @@ public class DateUtils {
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/* public static void main(String[] args) throws Exception {
|
||||
// System.out.println("start:");
|
||||
Date paramTime = getTime(getTimeString(new Long("1607672440731")));
|
||||
|
||||
@ -110,7 +110,7 @@ public class DateUtils {
|
||||
|
||||
// System.out.println(getTimeString(--countTimeLong));
|
||||
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
/**
|
||||
|
@ -68,8 +68,8 @@ public class ExcelReaderUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/* public static void main(String[] args) throws Exception {
|
||||
String file ="Metersphere_case_DataEase功能用例.xlsx";
|
||||
ExcelReaderUtil.readExcel(file, new FileInputStream("/Users/taojinlong/Desktop/" + file));
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package io.dataease.plugins.config;
|
||||
|
||||
import io.dataease.base.domain.MyPlugin;
|
||||
import io.dataease.plugins.loader.ClassloaderResponsity;
|
||||
import io.dataease.plugins.loader.ControllerLoader;
|
||||
import io.dataease.plugins.loader.ModuleClassLoader;
|
||||
import io.dataease.plugins.loader.MybatisLoader;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -19,6 +20,9 @@ public class LoadjarUtil {
|
||||
@Autowired
|
||||
private MybatisLoader mybatisLoader;
|
||||
|
||||
@Autowired
|
||||
private ControllerLoader controllerLoader;
|
||||
|
||||
public List<?> loadJar(String jarPath, MyPlugin myPlugin) throws Exception{
|
||||
File jar = new File(jarPath);
|
||||
URI uri = jar.toURI();
|
||||
@ -34,6 +38,10 @@ public class LoadjarUtil {
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
classLoader.initBean();
|
||||
mybatisLoader.loadMybatis(myPlugin);
|
||||
|
||||
List<String> controllers = classLoader.getRegisteredController();
|
||||
controllerLoader.registerController(controllers);
|
||||
|
||||
ClassloaderResponsity.getInstance().addClassLoader(moduleName,classLoader);
|
||||
|
||||
|
||||
|
@ -0,0 +1,95 @@
|
||||
package io.dataease.plugins.loader;
|
||||
|
||||
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class ControllerLoader {
|
||||
|
||||
/**
|
||||
* 去掉Controller的Mapping
|
||||
* @param controllerBeanName
|
||||
*/
|
||||
private void unregisterController(String controllerBeanName){
|
||||
final RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping)SpringContextUtil.getBean("requestMappingHandlerMapping");
|
||||
|
||||
if(requestMappingHandlerMapping!=null){
|
||||
String handler=controllerBeanName;
|
||||
Object controller= SpringContextUtil.getBean(handler);
|
||||
if(controller==null){
|
||||
return;
|
||||
}
|
||||
final Class<?> targetClass=controller.getClass();
|
||||
ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
|
||||
try {
|
||||
Method createMappingMethod = RequestMappingHandlerMapping.class.
|
||||
getDeclaredMethod("getMappingForMethod", Method.class, Class.class);
|
||||
createMappingMethod.setAccessible(true);
|
||||
RequestMappingInfo requestMappingInfo =(RequestMappingInfo)
|
||||
createMappingMethod.invoke(requestMappingHandlerMapping,specificMethod,targetClass);
|
||||
if(requestMappingInfo != null) {
|
||||
requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, ReflectionUtils.USER_DECLARED_METHODS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册Controller
|
||||
* @param controllerBeanName
|
||||
* @throws Exception
|
||||
*/
|
||||
private void registerController(String controllerBeanName) throws Exception{
|
||||
final RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping) SpringContextUtil.getBean("requestMappingHandlerMapping");
|
||||
|
||||
if(requestMappingHandlerMapping!=null){
|
||||
String handler=controllerBeanName;
|
||||
Object controller= SpringContextUtil.getBean(handler);
|
||||
if(controller==null){
|
||||
return;
|
||||
}
|
||||
unregisterController(controllerBeanName);
|
||||
//注册Controller
|
||||
Method method=requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().getDeclaredMethod("detectHandlerMethods",Object.class);
|
||||
|
||||
method.setAccessible(true);
|
||||
method.invoke(requestMappingHandlerMapping,handler);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerController(List<String> beanNames) {
|
||||
beanNames.forEach(name -> {
|
||||
try {
|
||||
registerController(name);
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
LogUtil.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -7,10 +7,14 @@ import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.type.TypeAliasRegistry;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -35,6 +39,8 @@ public class ModuleClassLoader extends URLClassLoader {
|
||||
//需要注册的spring bean的name集合
|
||||
private List<String> registeredBean = new ArrayList<>();
|
||||
|
||||
private List<String> registeredController = new ArrayList<>();
|
||||
|
||||
|
||||
//构造
|
||||
public ModuleClassLoader(URL[] urls, ClassLoader parent) {
|
||||
@ -150,8 +156,12 @@ public class ModuleClassLoader extends URLClassLoader {
|
||||
beanName = StringUtils.uncapitalize(beanName);
|
||||
|
||||
SpringContextUtil.getBeanFactory().registerBeanDefinition(beanName,beanDefinition);
|
||||
|
||||
if (isHandler(cla)) {
|
||||
registeredController.add(beanName);
|
||||
}
|
||||
|
||||
registeredBean.add(beanName);
|
||||
// System.out.println("注册bean:"+beanName);
|
||||
}
|
||||
|
||||
}
|
||||
@ -164,6 +174,10 @@ public class ModuleClassLoader extends URLClassLoader {
|
||||
return registeredBean;
|
||||
}
|
||||
|
||||
public List<String> getRegisteredController() {
|
||||
return registeredController;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法描述 判断class对象是否带有spring的注解
|
||||
@ -184,6 +198,9 @@ public class ModuleClassLoader extends URLClassLoader {
|
||||
if( Modifier.isAbstract(cla.getModifiers())){
|
||||
return false;
|
||||
}
|
||||
if (isHandler(cla)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(cla.getAnnotation(Component.class)!=null){
|
||||
return true;
|
||||
@ -194,8 +211,15 @@ public class ModuleClassLoader extends URLClassLoader {
|
||||
if(cla.getAnnotation(Service.class)!=null){
|
||||
return true;
|
||||
}
|
||||
if(cla.getAnnotation(Service.class)!=null){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isHandler(Class<?> beanType) {
|
||||
return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package io.dataease.plugins.server;
|
||||
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import io.dataease.plugins.common.dto.PluginSysMenu;
|
||||
import io.dataease.plugins.common.service.PluginComponentService;
|
||||
import io.dataease.plugins.common.service.PluginMenuService;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -9,7 +10,6 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class PluginCommonServer {
|
||||
|
||||
@GetMapping("/async/{menuId}")
|
||||
public void componentInfo(@PathVariable Long menuId) {
|
||||
public void menuInfo(@PathVariable Long menuId) {
|
||||
Map<String, PluginMenuService> pluginMenuServiceMap = SpringContextUtil.getApplicationContext().getBeansOfType(PluginMenuService.class);
|
||||
pluginMenuServiceMap.values().stream().forEach(service -> {
|
||||
AtomicReference<PluginSysMenu> atomicReference = new AtomicReference<>();
|
||||
@ -65,4 +65,41 @@ public class PluginCommonServer {
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping("/component/{componentName}")
|
||||
public void componentInfo(@PathVariable String componentName) {
|
||||
Map<String, PluginComponentService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(PluginComponentService.class);
|
||||
beansOfType.values().stream().forEach(service -> {
|
||||
List<String> components = service.components();
|
||||
if (components.contains(componentName)) {
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
BufferedInputStream bis = null;
|
||||
InputStream inputStream = null;
|
||||
OutputStream os = null; //输出流
|
||||
try{
|
||||
inputStream = service.vueResource(componentName);
|
||||
byte[] buffer = new byte[1024];
|
||||
os = response.getOutputStream();
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
int i = bis.read(buffer);
|
||||
while(i != -1){
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
os.flush();
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
try {
|
||||
bis.close();
|
||||
inputStream.close();
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
package io.dataease.plugins.server;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import io.dataease.auth.entity.SysUserEntity;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.service.AuthUserService;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.utils.CodingUtil;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
|
||||
import io.dataease.plugins.xpack.oidc.dto.SSOToken;
|
||||
import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
import io.dataease.service.sys.SysUserService;
|
||||
|
||||
@RequestMapping("/sso")
|
||||
@Controller
|
||||
public class SSOServer {
|
||||
|
||||
@Autowired
|
||||
private AuthUserService authUserService;
|
||||
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@GetMapping("/callBack")
|
||||
public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) {
|
||||
Map<String, OidcXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((OidcXpackService.class));
|
||||
if(beansOfType.keySet().size() == 0) {
|
||||
DEException.throwException("缺少oidc插件");
|
||||
}
|
||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
||||
Boolean suuportOIDC = oidcXpackService.isSuuportOIDC();
|
||||
if (!suuportOIDC) {
|
||||
DEException.throwException("未开启oidc");
|
||||
}
|
||||
Map<String, String> config = config(oidcXpackService);
|
||||
SSOToken ssoToken = oidcXpackService.requestSsoToken(config, code, state);
|
||||
|
||||
SSOUserInfo ssoUserInfo = oidcXpackService.requestUserInfo(config, ssoToken.getAccessToken());
|
||||
SysUserEntity sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub());
|
||||
if(null == sysUserEntity){
|
||||
sysUserService.saveOIDCUser(ssoUserInfo);
|
||||
sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub());
|
||||
}
|
||||
TokenInfo tokenInfo = TokenInfo.builder().userId(sysUserEntity.getUserId()).username(sysUserEntity.getUsername()).build();
|
||||
String realPwd = CodingUtil.md5(sysUserService.defaultPWD());
|
||||
String token = JWTUtils.sign(tokenInfo, realPwd);
|
||||
ServletUtils.setToken(token);
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
|
||||
Cookie cookie_token = new Cookie("Authorization", token);cookie_token.setPath("/");
|
||||
Cookie cookie_id_token = new Cookie("IdToken", ssoToken.getIdToken());cookie_id_token.setPath("/");
|
||||
Cookie cookie_ac_token = new Cookie("AccessToken", ssoToken.getAccessToken());cookie_ac_token.setPath("/");
|
||||
|
||||
response.addCookie(cookie_token);
|
||||
response.addCookie(cookie_id_token);
|
||||
response.addCookie(cookie_ac_token);
|
||||
ModelAndView modelAndView = new ModelAndView("redirect:/");
|
||||
return modelAndView;
|
||||
}
|
||||
private Map<String, String> config(OidcXpackService oidcXpackService) {
|
||||
List<SysSettingDto> sysSettingDtos = oidcXpackService.oidcSettings();
|
||||
Map<String, String> config = sysSettingDtos.stream().collect(Collectors.toMap(SysSettingDto::getParamKey, SysSettingDto::getParamValue));
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RequestMapping("/api/ldap")
|
||||
@RequestMapping("/plugin/ldap")
|
||||
@RestController
|
||||
public class XLdapServer {
|
||||
|
||||
|
@ -0,0 +1,59 @@
|
||||
package io.dataease.plugins.server;
|
||||
|
||||
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RequestMapping("/plugin/oidc")
|
||||
@RestController
|
||||
public class XOidcServer {
|
||||
|
||||
|
||||
@PostMapping("/info")
|
||||
public List<SysSettingDto> getOidcInfo() {
|
||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
||||
return oidcXpackService.oidcSettings();
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public void save(@RequestBody List<SysSettingDto> settings) {
|
||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
||||
oidcXpackService.save(settings);
|
||||
}
|
||||
|
||||
@PostMapping(value="/authInfo")
|
||||
public Map<String, Object> authInfo() {
|
||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
List<SysSettingDto> oidcSettings = oidcXpackService.oidcSettings();
|
||||
|
||||
Map<String, String> authParam = new HashMap<>();
|
||||
authParam.put("response_type", "code");
|
||||
authParam.put("state", "state");
|
||||
// authParam.put("redirect_uri", "http://localhost:9528");
|
||||
|
||||
|
||||
oidcSettings.forEach(param -> {
|
||||
if(StringUtils.isNotBlank(param.getParamKey())) {
|
||||
if (StringUtils.equals(param.getParamKey(), "oidc.authEndpoint")) {
|
||||
result.put("authEndpoint", param.getParamValue());
|
||||
}
|
||||
if (StringUtils.equals(param.getParamKey(), "oidc.scope")) {
|
||||
authParam.put("scope", param.getParamValue());
|
||||
}
|
||||
if (StringUtils.equals(param.getParamKey(), "oidc.clientId")) {
|
||||
authParam.put("client_id", param.getParamValue());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
result.put("authParam", authParam);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -208,7 +208,9 @@ public class ChartViewService {
|
||||
customFilter.addAll(collect);
|
||||
}
|
||||
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) {
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType())
|
||||
|| StringUtils.equalsIgnoreCase("gauge", view.getType())
|
||||
|| StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
xAxis = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(yAxis)) {
|
||||
ChartViewDTO dto = new ChartViewDTO();
|
||||
@ -327,7 +329,7 @@ public class ChartViewService {
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
|
||||
if (StringUtils.equalsIgnoreCase(table.getType(), "db")) {
|
||||
datasourceRequest.setTable(dataTableInfoDTO.getTable());
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) {
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
datasourceRequest.setQuery(qp.getSQLSummary(dataTableInfoDTO.getTable(), yAxis, customFilter, extFilterList));
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
datasourceRequest.setQuery(qp.getSQLStack(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, extStack, ds));
|
||||
@ -339,7 +341,7 @@ public class ChartViewService {
|
||||
datasourceRequest.setQuery(qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList, ds));
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(table.getType(), "sql")) {
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) {
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(dataTableInfoDTO.getSql(), yAxis, customFilter, extFilterList));
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
datasourceRequest.setQuery(qp.getSQLAsTmpStack(dataTableInfoDTO.getSql(), xAxis, yAxis, customFilter, extFilterList, extStack));
|
||||
@ -354,7 +356,7 @@ public class ChartViewService {
|
||||
DataTableInfoDTO dt = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class);
|
||||
List<DataSetTableUnionDTO> list = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId());
|
||||
String sql = dataSetTableService.getCustomSQLDatasource(dt, list, ds);
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) {
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(sql, yAxis, customFilter, extFilterList));
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
datasourceRequest.setQuery(qp.getSQLAsTmpStack(sql, xAxis, yAxis, customFilter, extFilterList, extStack));
|
||||
@ -386,7 +388,7 @@ public class ChartViewService {
|
||||
String tableName = "ds_" + table.getId().replaceAll("-", "_");
|
||||
datasourceRequest.setTable(tableName);
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType())) {
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
datasourceRequest.setQuery(qp.getSQLSummary(tableName, yAxis, customFilter, extFilterList));
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
datasourceRequest.setQuery(qp.getSQLStack(tableName, xAxis, yAxis, customFilter, extFilterList, extStack, ds));
|
||||
@ -458,6 +460,9 @@ public class ChartViewService {
|
||||
map.putAll(mapChart);
|
||||
map.putAll(mapTableNormal);
|
||||
|
||||
List<DatasetTableField> sourceFields = dataSetTableFieldsService.getFieldsByTableId(view.getTableId());
|
||||
map.put("sourceFields",sourceFields);
|
||||
|
||||
ChartViewDTO dto = new ChartViewDTO();
|
||||
BeanUtils.copyBean(dto, view);
|
||||
dto.setData(map);
|
||||
|
@ -805,21 +805,35 @@ public class DataSetTableService {
|
||||
String f = field.substring(0, field.length() - 1);
|
||||
|
||||
StringBuilder join = new StringBuilder();
|
||||
List<DataSetTableUnionDTO> unions = new ArrayList<>();
|
||||
for (DataTableInfoCustomUnion dataTableInfoCustomUnion : dataTableInfoDTO.getList()) {
|
||||
for (DataSetTableUnionDTO dto : list) {
|
||||
// 被关联表和自助数据集的表相等
|
||||
if (StringUtils.equals(dto.getTargetTableId(), dataTableInfoCustomUnion.getTableId())) {
|
||||
DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId());
|
||||
DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId());
|
||||
if (ObjectUtils.isEmpty(sourceField) || ObjectUtils.isEmpty(targetField)) {
|
||||
DEException.throwException(Translator.get("i18n_dataset_field_delete"));
|
||||
}
|
||||
unions.add(dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(unions)) {
|
||||
for (int i = 0; i < unions.size(); i++) {
|
||||
DataSetTableUnionDTO dto = unions.get(i);
|
||||
DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId());
|
||||
DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId());
|
||||
if (ObjectUtils.isEmpty(sourceField) || ObjectUtils.isEmpty(targetField)) {
|
||||
DEException.throwException(Translator.get("i18n_dataset_field_delete"));
|
||||
}
|
||||
if (i == 0) {
|
||||
join.append(convertUnionTypeToSQL(dto.getSourceUnionRelation()))
|
||||
.append(DorisTableUtils.dorisName(dto.getTargetTableId()))
|
||||
.append(" ON ")
|
||||
.append(DorisTableUtils.dorisName(dto.getSourceTableId())).append(".").append(sourceField.getDataeaseName())
|
||||
.append(" = ")
|
||||
.append(DorisTableUtils.dorisName(dto.getTargetTableId())).append(".").append(targetField.getDataeaseName());
|
||||
} else {
|
||||
join.append(" AND ")
|
||||
.append(DorisTableUtils.dorisName(dto.getSourceTableId())).append(".").append(sourceField.getDataeaseName())
|
||||
.append(" = ")
|
||||
.append(DorisTableUtils.dorisName(dto.getTargetTableId())).append(".").append(targetField.getDataeaseName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -865,25 +879,39 @@ public class DataSetTableService {
|
||||
String f = field.substring(0, field.length() - 1);
|
||||
|
||||
StringBuilder join = new StringBuilder();
|
||||
List<DataSetTableUnionDTO> unions = new ArrayList<>();
|
||||
for (DataTableInfoCustomUnion dataTableInfoCustomUnion : dataTableInfoDTO.getList()) {
|
||||
for (DataSetTableUnionDTO dto : list) {
|
||||
// 被关联表和自助数据集的表相等
|
||||
if (StringUtils.equals(dto.getTargetTableId(), dataTableInfoCustomUnion.getTableId())) {
|
||||
DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId());
|
||||
DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId());
|
||||
if (ObjectUtils.isEmpty(sourceField) || ObjectUtils.isEmpty(targetField)) {
|
||||
DEException.throwException(Translator.get("i18n_dataset_field_delete"));
|
||||
}
|
||||
DatasetTable sourceTable = datasetTableMapper.selectByPrimaryKey(dto.getSourceTableId());
|
||||
String sourceTableName = new Gson().fromJson(sourceTable.getInfo(), DataTableInfoDTO.class).getTable();
|
||||
DatasetTable targetTable = datasetTableMapper.selectByPrimaryKey(dto.getTargetTableId());
|
||||
String targetTableName = new Gson().fromJson(targetTable.getInfo(), DataTableInfoDTO.class).getTable();
|
||||
unions.add(dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(unions)) {
|
||||
for (int i = 0; i < unions.size(); i++) {
|
||||
DataSetTableUnionDTO dto = unions.get(i);
|
||||
DatasetTableField sourceField = dataSetTableFieldsService.get(dto.getSourceTableFieldId());
|
||||
DatasetTableField targetField = dataSetTableFieldsService.get(dto.getTargetTableFieldId());
|
||||
if (ObjectUtils.isEmpty(sourceField) || ObjectUtils.isEmpty(targetField)) {
|
||||
DEException.throwException(Translator.get("i18n_dataset_field_delete"));
|
||||
}
|
||||
DatasetTable sourceTable = datasetTableMapper.selectByPrimaryKey(dto.getSourceTableId());
|
||||
String sourceTableName = new Gson().fromJson(sourceTable.getInfo(), DataTableInfoDTO.class).getTable();
|
||||
DatasetTable targetTable = datasetTableMapper.selectByPrimaryKey(dto.getTargetTableId());
|
||||
String targetTableName = new Gson().fromJson(targetTable.getInfo(), DataTableInfoDTO.class).getTable();
|
||||
if (i == 0) {
|
||||
join.append(convertUnionTypeToSQL(dto.getSourceUnionRelation()))
|
||||
.append(String.format(keyword, targetTableName))
|
||||
.append(" ON ")
|
||||
.append(String.format(keyword, sourceTableName)).append(".").append(String.format(keyword, sourceField.getOriginName()))
|
||||
.append(" = ")
|
||||
.append(String.format(keyword, targetTableName)).append(".").append(String.format(keyword, targetField.getOriginName()));
|
||||
} else {
|
||||
join.append(" AND ")
|
||||
.append(String.format(keyword, sourceTableName)).append(".").append(String.format(keyword, sourceField.getOriginName()))
|
||||
.append(" = ")
|
||||
.append(String.format(keyword, targetTableName)).append(".").append(String.format(keyword, targetField.getOriginName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import io.dataease.controller.sys.response.SysUserGridResponse;
|
||||
import io.dataease.controller.sys.response.SysUserRole;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.plugins.common.entity.XpackLdapUserEntity;
|
||||
import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -31,6 +33,8 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -82,6 +86,7 @@ public class SysUserService {
|
||||
@Transactional
|
||||
public int save(SysUserCreateRequest request) {
|
||||
checkUsername(request);
|
||||
checkEmail(request);
|
||||
SysUser user = BeanUtils.copyBean(new SysUser(), request);
|
||||
long now = System.currentTimeMillis();
|
||||
user.setCreateTime(now);
|
||||
@ -102,6 +107,34 @@ public class SysUserService {
|
||||
return insert;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveOIDCUser(SSOUserInfo ssoUserInfo) {
|
||||
long now = System.currentTimeMillis();
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUsername(ssoUserInfo.getUsername());
|
||||
sysUser.setNickName(ssoUserInfo.getNickName());
|
||||
sysUser.setEmail(ssoUserInfo.getEmail());
|
||||
sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD));
|
||||
sysUser.setCreateTime(now);
|
||||
sysUser.setUpdateTime(now);
|
||||
sysUser.setEnabled(1L);
|
||||
sysUser.setLanguage("zh_CN");
|
||||
sysUser.setFrom(2);
|
||||
sysUser.setSub(ssoUserInfo.getSub());
|
||||
sysUserMapper.insert(sysUser);
|
||||
SysUser dbUser = findOne(sysUser);
|
||||
if (null != dbUser && null != dbUser.getUserId()) {
|
||||
// oidc默认角色是普通员工
|
||||
List<Long> roleIds = new ArrayList<Long>();
|
||||
roleIds.add(2L);
|
||||
saveUserRoles( dbUser.getUserId(), roleIds);
|
||||
}
|
||||
}
|
||||
|
||||
public String defaultPWD() {
|
||||
return DEFAULT_PWD;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveLdapUsers(LdapAddRequest request) {
|
||||
long now = System.currentTimeMillis();
|
||||
@ -115,6 +148,7 @@ public class SysUserService {
|
||||
sysUser.setCreateTime(now);
|
||||
sysUser.setUpdateTime(now);
|
||||
sysUser.setEnabled(request.getEnabled());
|
||||
sysUser.setLanguage("zh_CN");
|
||||
sysUser.setFrom(1);
|
||||
return sysUser;
|
||||
}).collect(Collectors.toList());
|
||||
@ -145,6 +179,7 @@ public class SysUserService {
|
||||
@Transactional
|
||||
public int update(SysUserCreateRequest request) {
|
||||
checkUsername(request);
|
||||
checkEmail(request);
|
||||
if (StringUtils.isEmpty(request.getPassword())) {
|
||||
request.setPassword(null);
|
||||
}
|
||||
@ -287,4 +322,19 @@ public class SysUserService {
|
||||
throw new RuntimeException(Translator.get("i18n_username_exists"));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEmail(SysUserCreateRequest request) {
|
||||
SysUserExample sysUserExample = new SysUserExample();
|
||||
SysUserExample.Criteria criteria = sysUserExample.createCriteria();
|
||||
if (request.getUserId() != null) {
|
||||
criteria.andUserIdNotEqualTo(request.getUserId());
|
||||
}
|
||||
criteria.andEmailEqualTo(request.getEmail());
|
||||
List<SysUser> sysUsers = sysUserMapper.selectByExample(sysUserExample);
|
||||
if (CollectionUtils.isNotEmpty(sysUsers)) {
|
||||
throw new RuntimeException(Translator.get("i18n_email_exists"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -229,9 +229,9 @@ public class SystemParameterService {
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/* public static void main(String[] args) {
|
||||
String info="[{\"paramKey\":\"base.url\",\"paramValue\":null,\"type\":\"text\",\"sort\":1,\"file\":null,\"fileName\":null},{\"paramKey\":\"base.title\",\"paramValue\":\"DataEase Title\",\"type\":\"text\",\"sort\":3,\"file\":null,\"fileName\":null},{\"paramKey\":\"base.logo\",\"paramValue\":\"DataEase\",\"type\":\"text\",\"sort\":4,\"file\":null,\"fileName\":\"favicon.icon.png\"}]";
|
||||
List<SystemParameterDTO> temp = JSON.parseArray(info,SystemParameterDTO.class);
|
||||
// System.out.println("===>");
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
@ -31,3 +31,24 @@ INSERT INTO `sys_menu` VALUES (60, 1, 0, 1, '导入LDAP用户', 'system-user-imp
|
||||
|
||||
ALTER TABLE `datasource` ADD COLUMN `compute_type` VARCHAR(45) NULL DEFAULT 'ALL' COMMENT '数据计算模式' AFTER `status`;
|
||||
update datasource set compute_type='ALL';
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO `system_parameter` VALUES ('ldap.url', NULL, 'text', 1);
|
||||
INSERT INTO `system_parameter` VALUES ('ldap.dn', NULL, 'text', 2);
|
||||
INSERT INTO `system_parameter` VALUES ('ldap.password', NULL, 'password', 3);
|
||||
INSERT INTO `system_parameter` VALUES ('ldap.ou', NULL, 'text', 4);
|
||||
INSERT INTO `system_parameter` VALUES ('ldap.mapping', NULL, 'text', 6);
|
||||
INSERT INTO `system_parameter` VALUES ('ldap.open', NULL, 'text', 7);
|
||||
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.authEndpoint', NULL, 'text', 1);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.tokenEndpoint', NULL, 'text', 2);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.userinfoEndpoint', NULL, 'text', 3);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.logoutEndpoint', NULL, 'text', 4);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.clientId', NULL, 'text', 5);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.secret', NULL, 'password', 6);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.scope', NULL, 'text', 7);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.redirectUrl', NULL, 'text', 8);
|
||||
INSERT INTO `system_parameter` VALUES ('oidc.open', NULL, 'text', 9);
|
||||
COMMIT;
|
||||
|
||||
ALTER TABLE `sys_user` ADD COLUMN `sub` varchar(255) COMMENT 'oidc用户ID' AFTER `from`;
|
||||
|
@ -198,6 +198,7 @@ authsource_configuration_is_null=Authentication source configuration cannot be e
|
||||
删除角色=Delete Role
|
||||
删除连接=Delete Connection
|
||||
显示设置=Display
|
||||
系统参数=System Param
|
||||
参数管理=Parameter
|
||||
数据源=Data Source
|
||||
数据源表单=Data source form
|
||||
@ -243,6 +244,7 @@ i18n_union_field_exists=The same field can't in two dataset
|
||||
i18n_cron_time_error=Start time can't greater then end time
|
||||
i18n_auth_source_be_canceled=This Auth Resource Already Be Canceled,Please Connect Admin
|
||||
i18n_username_exists=ID is already exists
|
||||
i18n_email_exists=Email is already exists
|
||||
i18n_ds_name_exists=Datasource name used
|
||||
i18n_sync_job_exists=There is already a synchronization task running, please try again later
|
||||
i18n_datasource_check_fail=Invalid,please check config
|
||||
|
@ -198,6 +198,7 @@ authsource_configuration_is_null=认证源配置不能为空
|
||||
删除角色=删除角色
|
||||
删除连接=删除连接
|
||||
显示设置=显示设置
|
||||
系统参数=系统参数
|
||||
数据源=数据源
|
||||
数据源表单=数据源表单
|
||||
数据集=数据集
|
||||
@ -233,7 +234,7 @@ i18n_chart_count=记录数*
|
||||
i18n_excel_have_merge_region=Excel 存在合并单元格
|
||||
i18n_cron_expression_error=Cron 表达式校验错误
|
||||
i18n_same_folder_can_not_repeat=同一目录下该名称已被使用
|
||||
i18n_select_diff_folder= 请选择不通的目录
|
||||
i18n_select_diff_folder= 请选择不同的目录
|
||||
i18n_default_panel=默认仪表板
|
||||
i18n_panel_list=仪表板
|
||||
i18n_processing_data=正在处理数据,稍后刷新
|
||||
@ -242,6 +243,7 @@ i18n_union_field_exists=两个数据集之间关联不能出现多次相同字
|
||||
i18n_cron_time_error=开始时间不能大于结束时间
|
||||
i18n_auth_source_be_canceled=本用户当前资源所有授权权限已经被取消,如需再次开通,请联系管理员
|
||||
i18n_username_exists=用户 ID 已存在
|
||||
i18n_email_exists=邮箱已存在
|
||||
i18n_ds_name_exists=数据源名称已被使用
|
||||
i18n_sync_job_exists=已经有同步任务在运行,稍后重试
|
||||
i18n_datasource_check_fail=校验失败,请检查配置信息
|
||||
|
@ -200,6 +200,7 @@ authsource_configuration_is_null=認證源配置不能為空
|
||||
删除角色=刪除角色
|
||||
刪除连接=刪除鏈接
|
||||
显示设置=顯示設置
|
||||
系统参数=系統參數
|
||||
参数管理=參數管理
|
||||
数据源=數據源
|
||||
数据源表单=數據源表單
|
||||
@ -236,7 +237,7 @@ i18n_chart_count=記錄數*
|
||||
i18n_excel_have_merge_region=Excel存在合並單元格
|
||||
i18n_cron_expression_error=Cron表達式校驗錯誤
|
||||
i18n_same_folder_can_not_repeat=同一目錄下該名稱已被使用
|
||||
i18n_select_diff_folder= 请选择不通的目录
|
||||
i18n_select_diff_folder= 请选择不同的目录
|
||||
i18n_default_panel=默認儀表板
|
||||
i18n_panel_list=儀表板
|
||||
i18n_processing_data=正在處理數據,稍後刷新
|
||||
@ -245,6 +246,7 @@ i18n_union_field_exists=兩個數據集之間關聯不能出現多次相同字
|
||||
i18n_cron_time_error=開始時間不能大於結束時間
|
||||
i18n_auth_source_be_canceled=本用户当前资源所有授权权限已经被取消,如需再次开通,请联系管理员
|
||||
i18n_username_exists=用戶ID已存在
|
||||
i18n_email_exists=郵箱已存在
|
||||
i18n_ds_name_exists=數據源名稱已被使用
|
||||
i18n_sync_job_exists=已經有同步任務在運行,稍後重試
|
||||
i18n_datasource_check_fail=校驗失敗,請檢查配置信息
|
||||
|
@ -15,6 +15,7 @@
|
||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g2plot": "^2.3.32",
|
||||
"@riophae/vue-treeselect": "0.4.0",
|
||||
"@tinymce/tinymce-vue": "^3.2.8",
|
||||
"axios": "^0.21.1",
|
||||
|
@ -100,7 +100,7 @@ export function roleGrid(pageIndex, pageSize, data) {
|
||||
|
||||
export function ldapUsers(data) {
|
||||
return request({
|
||||
url: '/api/ldap/users',
|
||||
url: '/plugin/ldap/users',
|
||||
method: 'post',
|
||||
loading: true
|
||||
})
|
||||
|
@ -57,3 +57,10 @@ export function ldapStatus() {
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function oidcStatus() {
|
||||
return request({
|
||||
url: '/api/auth/isOpenOidc',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ export default {
|
||||
const rect = this.$el.parentNode.getBoundingClientRect()
|
||||
this.parentX = rect.x
|
||||
this.parentY = rect.y
|
||||
return [Math.round(parseFloat(style.getPropertyValue('width'), 10)), Math.round(parseFloat(style.getPropertyValue('height'), 10))]
|
||||
return [Math.round(parseFloat(style.getPropertyValue('width'), 10)), 100000]
|
||||
}
|
||||
if (typeof this.parent === 'string') {
|
||||
const parentNode = document.querySelector(this.parent)
|
||||
|
@ -199,6 +199,7 @@ export default {
|
||||
query(currentPage, pageSize, param).then(response => {
|
||||
this.data = response.data.listObject
|
||||
this.paginationConfig.total = response.data.itemCount
|
||||
this.count = this.paginationConfig.total
|
||||
}).catch(() => {
|
||||
const token = getToken()
|
||||
if (!token || token === 'null' || token === 'undefined') {
|
||||
@ -232,7 +233,7 @@ export default {
|
||||
right: 178px;
|
||||
top: 8px;
|
||||
background: red;
|
||||
// color: #fff;
|
||||
color: #fff;
|
||||
border-radius: 17px;
|
||||
padding: 4px 7px;
|
||||
font-size: 16px;
|
||||
|
@ -110,12 +110,16 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.canvasStyleData.selfAdaption) {
|
||||
style = {
|
||||
overflow: 'hidden',
|
||||
...style
|
||||
}
|
||||
}
|
||||
// if (this.canvasStyleData.selfAdaption) {
|
||||
// style = {
|
||||
// overflow: 'hidden',
|
||||
// ...style
|
||||
// }
|
||||
// }
|
||||
// style = {
|
||||
// overflow-x :'hidden',
|
||||
// ...style
|
||||
// }
|
||||
return style
|
||||
},
|
||||
// 此处单独计算componentData的值 不放入全局mapState中
|
||||
@ -168,10 +172,13 @@ export default {
|
||||
const canvasWidth = document.getElementById('canvasInfoTemp').offsetWidth
|
||||
this.scaleWidth = canvasWidth * 100 / parseInt(this.canvasStyleData.width)// 获取宽度比
|
||||
this.scaleHeight = canvasHeight * 100 / parseInt(this.canvasStyleData.height)// 获取高度比
|
||||
if (this.showType === 'width') {
|
||||
this.scaleHeight = this.scaleWidth
|
||||
this.mainHeight = this.canvasStyleData.height * this.scaleHeight / 100 + 'px'
|
||||
}
|
||||
|
||||
this.scaleHeight = this.scaleWidth
|
||||
// this.mainHeight = this.canvasStyleData.height * this.scaleHeight / 100 + 'px'
|
||||
// if (this.showType === 'width') {
|
||||
// this.scaleHeight = this.scaleWidth
|
||||
// this.mainHeight = this.canvasStyleData.height * this.scaleHeight / 100 + 'px'
|
||||
// }
|
||||
this.handleScaleChange()
|
||||
},
|
||||
resetID(data) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="showDrag"
|
||||
id="editor"
|
||||
class="editor"
|
||||
:class="[
|
||||
@ -13,7 +12,7 @@
|
||||
@mousedown="handleMouseDown"
|
||||
>
|
||||
<!-- 网格线 -->
|
||||
<Grid v-if="canvasStyleData.auxiliaryMatrix&&!linkageSettingStatus" :matrix-style="matrixStyle" />
|
||||
<!-- <Grid v-if="canvasStyleData.auxiliaryMatrix&&!linkageSettingStatus" :matrix-style="matrixStyle" />-->
|
||||
|
||||
<!-- 仪表板联动清除按钮-->
|
||||
<canvas-opt-bar />
|
||||
@ -217,10 +216,10 @@ export default {
|
||||
width: 80,
|
||||
height: 20
|
||||
},
|
||||
// 矩阵数量 默认 12 * 24
|
||||
// 矩阵数量 默认 128 * 72
|
||||
matrixCount: {
|
||||
x: 24,
|
||||
y: 72
|
||||
x: 80,
|
||||
y: 45
|
||||
},
|
||||
customStyleHistory: null,
|
||||
showDrag: true,
|
||||
@ -556,6 +555,9 @@ export default {
|
||||
if (this.canvasStyleData.matrixCount) {
|
||||
this.matrixCount = this.canvasStyleData.matrixCount
|
||||
}
|
||||
// 1.3 版本重新设计仪表板定位方式,基准画布宽高为 1600*900 宽度自适应当前画布获取缩放比例scaleWidth
|
||||
// 高度缩放比例scaleHeight = scaleWidth 基础矩阵为128*72 矩阵原始宽度12.5*12.5 矩阵高度可以调整
|
||||
|
||||
if (this.outStyle.width && this.outStyle.height) {
|
||||
// 矩阵计算
|
||||
if (!this.canvasStyleData.selfAdaption) {
|
||||
@ -643,6 +645,7 @@ export default {
|
||||
position: relative;
|
||||
/*background: #fff;*/
|
||||
margin: auto;
|
||||
overflow-x: hidden;
|
||||
background-size:100% 100% !important;
|
||||
/*transform-style:preserve-3d;*/
|
||||
.lock {
|
||||
|
@ -49,6 +49,14 @@
|
||||
<el-input v-model="innerOpacity" type="number" size="mini" min="0" max="100" step="10" @change="styleChange" />
|
||||
</div>
|
||||
|
||||
<el-tooltip :content="$t('panel.borderRadius')">
|
||||
<i style="float: left;margin-top: 3px;margin-left: 2px;" class="icon iconfont icon-fangxing-" />
|
||||
</el-tooltip>
|
||||
|
||||
<div style="width: 70px;float: left;margin-top: 2px;margin-left: 2px;">
|
||||
<el-input v-model="styleInfo.borderRadius" type="number" size="mini" min="0" max="100" step="1" @change="styleChange" />
|
||||
</div>
|
||||
|
||||
<div style="width: 20px;float: left;margin-top: 2px;margin-left: 10px;">
|
||||
<div style="width: 16px;height: 18px">
|
||||
<el-tooltip :content="$t('panel.color')">
|
||||
@ -173,7 +181,7 @@ export default {
|
||||
ps = x + 60
|
||||
}
|
||||
// 防止toolbar超出边界
|
||||
const xGap = ps + 495 - this.canvasWidth
|
||||
const xGap = ps + 565 - this.canvasWidth
|
||||
// console.log('canvasWidth:' + this.canvasWidth + ';xGap:' + xGap)
|
||||
if (xGap > 0) {
|
||||
return ps - xGap
|
||||
@ -205,7 +213,7 @@ export default {
|
||||
.el-card-main {
|
||||
height: 34px;
|
||||
z-index: 10;
|
||||
width: 550px;
|
||||
width: 620px;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
|
@ -17,18 +17,6 @@
|
||||
<el-switch v-model="canvasStyleData.auxiliaryMatrix" :width="35" name="auxiliaryMatrix" />
|
||||
<span>{{ $t('panel.matrix_design') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="canvas-config" style="margin-right: 10px">
|
||||
<el-switch v-model="canvasStyleData.selfAdaption" :width="35" name="selfAdaption" />
|
||||
<span>{{ $t('panel.canvas_self_adaption') }} </span>
|
||||
</div>
|
||||
|
||||
<div class="canvas-config" style="margin-right: 55px">
|
||||
<span> {{ $t('panel.canvas_size') }} </span>
|
||||
<input v-model="canvasStyleData.width" :disabled="canvasStyleData.selfAdaption">
|
||||
<span>*</span>
|
||||
<input v-model="canvasStyleData.height" :disabled="canvasStyleData.selfAdaption">
|
||||
</div>
|
||||
<!-- <div class="canvas-config" style="margin-right: 10px">-->
|
||||
<!-- <span> {{ $t('panel.canvas_scale') }} </span>-->
|
||||
<!-- <input v-model="scale" @input="handleScaleChange"> %-->
|
||||
@ -383,7 +371,7 @@ export default {
|
||||
float: right;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
min-width: 900px;
|
||||
min-width: 500px;
|
||||
/*background: #fff;*/
|
||||
/*border-bottom: 1px solid #ddd;*/
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
{{ $t('chart.chart_error_tips') }}
|
||||
</div>
|
||||
</div>
|
||||
<chart-component v-if="httpRequest.status &&chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :ref="element.propValue.id" class="chart-class" :chart="chart" :track-menu="trackMenu" @onChartClick="chartClick" />
|
||||
<chart-component v-if="httpRequest.status &&chart.type && !chart.type.includes('table') && !chart.type.includes('text') && renderComponent() === 'echarts'" :ref="element.propValue.id" class="chart-class" :chart="chart" :track-menu="trackMenu" @onChartClick="chartClick" />
|
||||
<chart-component-g2 v-if="httpRequest.status &&chart.type && !chart.type.includes('table') && !chart.type.includes('text') && renderComponent() === 'g2'" :ref="element.propValue.id" class="chart-class" :chart="chart" :track-menu="trackMenu" @onChartClick="chartClick" />
|
||||
<!-- <chart-component :ref="element.propValue.id" class="chart-class" :chart="chart" :track-menu="trackMenu" @onChartClick="chartClick" />-->
|
||||
<table-normal v-if="httpRequest.status &&chart.type && chart.type.includes('table')" :ref="element.propValue.id" :show-summary="chart.type === 'table-normal'" :chart="chart" class="table-class" />
|
||||
<label-normal v-if="httpRequest.status && chart.type && chart.type.includes('text')" :ref="element.propValue.id" :chart="chart" class="table-class" />
|
||||
@ -43,9 +44,10 @@ import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import { getToken, getLinkToken } from '@/utils/auth'
|
||||
import DrillPath from '@/views/chart/view/DrillPath'
|
||||
import { areaMapping } from '@/api/map/map'
|
||||
import ChartComponentG2 from '@/views/chart/components/ChartComponentG2'
|
||||
export default {
|
||||
name: 'UserView',
|
||||
components: { ChartComponent, TableNormal, LabelNormal, DrillPath },
|
||||
components: { ChartComponent, TableNormal, LabelNormal, DrillPath, ChartComponentG2 },
|
||||
props: {
|
||||
element: {
|
||||
type: Object,
|
||||
@ -119,7 +121,7 @@ export default {
|
||||
trackMenu() {
|
||||
const trackMenuInfo = []
|
||||
let linkageCount = 0
|
||||
this.chart.data && this.chart.data.fields && this.chart.data.fields.forEach(item => {
|
||||
this.chart.data && this.chart.data.sourceFields && this.chart.data.sourceFields.forEach(item => {
|
||||
const sourceInfo = this.chart.id + '#' + item.id
|
||||
if (this.nowPanelTrackInfo[sourceInfo]) {
|
||||
linkageCount++
|
||||
@ -262,6 +264,7 @@ export default {
|
||||
this.chart.drillFields = this.chart.drillFields ? JSON.parse(this.chart.drillFields) : []
|
||||
if (!response.data.drill) {
|
||||
this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1)
|
||||
this.resetDrill()
|
||||
}
|
||||
this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters))
|
||||
this.drillFields = JSON.parse(JSON.stringify(response.data.drillFields))
|
||||
@ -434,6 +437,14 @@ export default {
|
||||
this.destroyTimeMachine()
|
||||
}, 200)
|
||||
}
|
||||
},
|
||||
|
||||
renderComponent() {
|
||||
if (this.chart.type === 'liquid') {
|
||||
return 'g2'
|
||||
} else {
|
||||
return 'echarts'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,8 +57,11 @@ const list = [
|
||||
fontWeight: 400,
|
||||
lineHeight: '',
|
||||
letterSpacing: 0,
|
||||
textAlign: 'left',
|
||||
color: '#000000'
|
||||
textAlign: 'center',
|
||||
color: '#000000',
|
||||
verticalAlign: 'middle',
|
||||
backgroundColor: '#ffffff',
|
||||
borderRadius: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
|
1
frontend/src/icons/svg/liquid.svg
Normal file
1
frontend/src/icons/svg/liquid.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg t="1631072907294" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3122" width="200" height="200"><path d="M512 51.2C257.504 51.2 51.2 257.504 51.2 512S257.504 972.8 512 972.8 972.8 766.496 972.8 512 766.496 51.2 512 51.2m0 42.624c230.592 0 418.176 187.584 418.176 418.176 0 230.592-187.584 418.176-418.176 418.176-230.592 0-418.176-187.584-418.176-418.176C93.824 281.408 281.408 93.824 512 93.824" p-id="3123"></path><path d="M757.92 598.88c-56.704 0-113.856-13.6-164.352-39.296-37.408-19.04-70.016-46.016-100.224-74.848-29.536-28.16-58.944-52.8-98.944-64.992-17.472-5.312-69.76-20.448-129.472 1.024a190.624 190.624 0 0 0-75.872 50.304A187.264 187.264 0 0 0 153.6 528.96c10.88 190.304 168.32 341.44 361.536 341.44 175.328 0 321.568-124.32 355.264-289.504a362.048 362.048 0 0 1-112.48 17.984" p-id="3124"></path></svg>
|
After Width: | Height: | Size: 867 B |
@ -130,6 +130,8 @@ export default {
|
||||
re_login: 'Login again'
|
||||
},
|
||||
commons: {
|
||||
search: 'Search',
|
||||
folder: 'Folder',
|
||||
no_target_permission: 'No permission',
|
||||
success: 'Success',
|
||||
switch_lang: 'Switch Language Success',
|
||||
@ -431,6 +433,11 @@ export default {
|
||||
fixedHeader: 'Fixed Header',
|
||||
sidebarLogo: 'Sidebar Logo'
|
||||
},
|
||||
sysParams: {
|
||||
display: 'Display Setting',
|
||||
ldap: 'LDAP Setting',
|
||||
oidc: 'OIDC Setting'
|
||||
},
|
||||
license: {
|
||||
i18n_no_license_record: 'No License Record',
|
||||
i18n_license_is_empty: 'License is empty.',
|
||||
@ -498,6 +505,47 @@ export default {
|
||||
change_password: 'Change Password',
|
||||
search_by_name: 'Search by name'
|
||||
},
|
||||
ldap: {
|
||||
url: 'LDAP url',
|
||||
dn: 'LDAP DN',
|
||||
password: 'Password',
|
||||
ou: 'OU',
|
||||
filter: 'filter',
|
||||
mapping: 'LDAP mapping',
|
||||
open: 'Enable LDAP Authentication',
|
||||
input_url: 'Please key LDAP url',
|
||||
input_dn: 'Please key DN',
|
||||
input_password: 'Please key password',
|
||||
input_ou: 'Please key OU',
|
||||
input_filter: 'Please key filter',
|
||||
input_mapping: 'Please key LDAP mapping',
|
||||
input_username: 'Please key username',
|
||||
input_url_placeholder: 'Please key url (like ldap://localhost:389)',
|
||||
input_ou_placeholder: 'Please key OU ',
|
||||
input_filter_placeholder: 'Please key filter',
|
||||
input_mapping_placeholder: 'like:{"username":"uid","name":"sn","email":"mail"}',
|
||||
test_connect: 'Test connect',
|
||||
edit: 'Edit',
|
||||
login_success: 'Login success',
|
||||
url_cannot_be_empty: 'LDAP url can not be empty',
|
||||
dn_cannot_be_empty: 'LDAP DN can not be empty',
|
||||
ou_cannot_be_empty: 'LDAP OU can not be empty',
|
||||
filter_cannot_be_empty: 'LDAP filter can not be empty',
|
||||
mapping_cannot_be_empty: 'LDAP mapping can not be empty',
|
||||
password_cannot_be_empty: 'LDAP password can not be empty',
|
||||
import_ldap: 'Import LDAP User'
|
||||
},
|
||||
oidc: {
|
||||
auth_endpoint: 'Please key AuthEndpoint',
|
||||
token_endpoint: 'Please key TokenEndpoint',
|
||||
userinfo_endpoint: 'Please key UserinfoEndpoint',
|
||||
logout_endpoint: 'Please key logoutEndpoint',
|
||||
clientId: 'Please key ClientId',
|
||||
secret: 'Please key Secret',
|
||||
scope: 'Please key scope',
|
||||
redirectUrl: 'Please key redirectUrl',
|
||||
open: 'Enable OIDC Authentication'
|
||||
},
|
||||
role: {
|
||||
menu_authorization: 'Menu Authorization',
|
||||
data_authorization: 'Data Authorization',
|
||||
@ -862,7 +910,20 @@ export default {
|
||||
yAxis_main: 'Main Vertical Axis',
|
||||
yAxis_ext: 'Ext Vertical Axis',
|
||||
total: 'Total',
|
||||
items: 'Items'
|
||||
items: 'Items',
|
||||
chart_liquid: 'Liquid',
|
||||
drag_block_progress: 'Progress',
|
||||
liquid_max: 'End Value',
|
||||
liquid_outline_border: 'Border Width',
|
||||
liquid_outline_distance: 'Border Distance',
|
||||
liquid_wave_length: 'Wave Length',
|
||||
liquid_wave_count: 'Wave Count',
|
||||
liquid_shape: 'Shape',
|
||||
liquid_shape_circle: 'Circle',
|
||||
liquid_shape_diamond: 'Diamond',
|
||||
liquid_shape_triangle: 'Triangle',
|
||||
liquid_shape_pin: 'Pin',
|
||||
liquid_shape_rect: 'Rect'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
|
||||
|
@ -45,7 +45,7 @@ export default {
|
||||
dashboard: '首頁',
|
||||
documentation: '文檔',
|
||||
guide: '引導頁',
|
||||
permission: '全縣測試頁',
|
||||
permission: '權限測試頁',
|
||||
rolePermission: '角色權限',
|
||||
pagePermission: '頁面權限',
|
||||
directivePermission: '指令權限',
|
||||
@ -91,7 +91,7 @@ export default {
|
||||
errorPages: '錯誤頁面',
|
||||
page401: '401',
|
||||
page404: '404',
|
||||
errorLog: '錯誤日誌',
|
||||
errorLog: '錯誤日志',
|
||||
excel: 'Excel',
|
||||
exportExcel: '導出 Excel',
|
||||
selectExcel: '導出 已選擇項',
|
||||
@ -109,34 +109,36 @@ export default {
|
||||
navbar: {
|
||||
dashboard: '首頁',
|
||||
github: '項目地址',
|
||||
logOut: '退出登陸',
|
||||
logOut: '退出登錄',
|
||||
profile: '個人中心',
|
||||
theme: '換膚',
|
||||
size: '佈局大小'
|
||||
size: '布局大小'
|
||||
},
|
||||
login: {
|
||||
title: '系統登陸',
|
||||
title: '系統登錄',
|
||||
welcome: '歡迎使用',
|
||||
logIn: '登陸',
|
||||
username: '帳號',
|
||||
logIn: '登錄',
|
||||
username: '賬號',
|
||||
password: '密碼',
|
||||
any: '任意字符',
|
||||
thirdparty: '第三方登陸',
|
||||
any: '隨便填',
|
||||
thirdparty: '第三方登錄',
|
||||
thirdpartyTips: '本地不能模擬,請結合自己業務進行模擬!!!',
|
||||
expires: '登陸信息過期,請重新登陸',
|
||||
tokenError: '信息錯誤,請重新登陸',
|
||||
expires: '登錄信息過期,請重新登錄',
|
||||
tokenError: '登陸信息錯誤,請重新登錄',
|
||||
username_error: '請輸入正確的 ID',
|
||||
password_error: '密碼不小於 8 位',
|
||||
re_login: '重新登陸'
|
||||
password_error: '密碼不小于 8 位',
|
||||
re_login: '重新登錄'
|
||||
},
|
||||
commons: {
|
||||
search: '搜索',
|
||||
folder: '目錄',
|
||||
no_target_permission: '沒有權限',
|
||||
success: '成功',
|
||||
switch_lang: '切換語言成功',
|
||||
close: '關閉',
|
||||
icon: '圖標',
|
||||
all: '全部',
|
||||
enable: '啟用',
|
||||
enable: '啓用',
|
||||
disable: '禁用',
|
||||
yes: '是',
|
||||
no: '否',
|
||||
@ -153,30 +155,30 @@ export default {
|
||||
not_cover: '不覆蓋',
|
||||
import_mode: '導入模式',
|
||||
import_module: '導入模塊',
|
||||
please_fill_in_the_template: '請填寫模板內容',
|
||||
cut_back_old_version: '切匯舊版',
|
||||
cut_back_new_version: '切匯新版',
|
||||
please_fill_in_the_template: '請填寫模版內容',
|
||||
cut_back_old_version: '切回舊版',
|
||||
cut_back_new_version: '切回新版',
|
||||
comment: '評論',
|
||||
examples: '示例',
|
||||
help_documentation: '幫助文檔',
|
||||
api_help_documentation: 'API文檔',
|
||||
delete_cancelled: '已取消刪除',
|
||||
workspace: '工作空開你',
|
||||
workspace: '工作空間',
|
||||
organization: '組織',
|
||||
menu: '菜單',
|
||||
setting: '設置',
|
||||
project: '項目',
|
||||
about_us: '關於',
|
||||
about_us: '關于',
|
||||
current_project: '當前項目',
|
||||
name: '名稱',
|
||||
description: '描述',
|
||||
annotation: '註釋',
|
||||
annotation: '注釋',
|
||||
clear: '清空',
|
||||
save: '保存',
|
||||
update: '更新',
|
||||
save_success: '保存成功',
|
||||
delete_success: '刪除成功',
|
||||
copy_success: '複製成功',
|
||||
copy_success: '複制成功',
|
||||
modify_success: '修改成功',
|
||||
delete_cancel: '已取消刪除',
|
||||
confirm: '確定',
|
||||
@ -184,8 +186,8 @@ export default {
|
||||
prompt: '提示',
|
||||
operating: '操作',
|
||||
input_limit: '長度在 {0} 到 {1} 個字符',
|
||||
login: '登陸',
|
||||
welcome: '一站式開源數據分析平臺',
|
||||
login: '登錄',
|
||||
welcome: '一站式開源數據分析平台',
|
||||
username: '姓名',
|
||||
password: '密碼',
|
||||
input_username: '請輸入用戶姓名',
|
||||
@ -213,11 +215,11 @@ export default {
|
||||
input_content: '請輸入內容',
|
||||
create: '新建',
|
||||
edit: '編輯',
|
||||
copy: '複製',
|
||||
copy: '複制',
|
||||
refresh: '刷新',
|
||||
remark: '備註',
|
||||
remark: '備注',
|
||||
delete: '刪除',
|
||||
reduction: '恢復',
|
||||
reduction: '恢複',
|
||||
not_filled: '未填寫',
|
||||
please_select: '請選擇',
|
||||
search_by_name: '根據名稱搜索',
|
||||
@ -225,7 +227,7 @@ export default {
|
||||
exit_system: '退出系統',
|
||||
verification: '驗證',
|
||||
title: '標題',
|
||||
custom: '自動義',
|
||||
custom: '自定義',
|
||||
select_date: '選擇日期',
|
||||
months_1: '一月',
|
||||
months_2: '二月',
|
||||
@ -250,13 +252,13 @@ export default {
|
||||
connection_successful: '連接成功',
|
||||
connection_failed: '連接失敗',
|
||||
save_failed: '保存失敗',
|
||||
host_cannot_be_empty: '主機不能為空',
|
||||
port_cannot_be_empty: '端口號不能為空',
|
||||
account_cannot_be_empty: '帳戶不能為空',
|
||||
host_cannot_be_empty: '主機不能爲空',
|
||||
port_cannot_be_empty: '端口號不能爲空',
|
||||
account_cannot_be_empty: '帳戶不能爲空',
|
||||
remove: '移除',
|
||||
remove_cancel: '移除取消',
|
||||
remove_success: '移除成功',
|
||||
tips: '認證信息已過期,請重新登陸',
|
||||
tips: '認證信息已過期,請重新登錄',
|
||||
not_performed_yet: '尚未執行',
|
||||
incorrect_input: '輸入內容不正確',
|
||||
delete_confirm: '請輸入以下內容,確認刪除:',
|
||||
@ -264,13 +266,13 @@ export default {
|
||||
input_login_username: '請輸入用戶 ID 或 郵箱',
|
||||
input_name: '請輸入名稱',
|
||||
please_upload: '請上傳文件',
|
||||
please_fill_path: '請填寫url 路徑',
|
||||
please_fill_path: '請填寫ur路徑',
|
||||
formatErr: '格式錯誤',
|
||||
please_save: '請先保存',
|
||||
reference_documentation: '參考文檔',
|
||||
id: 'ID',
|
||||
millisecond: '毫秒',
|
||||
cannot_be_null: '不能為空',
|
||||
cannot_be_null: '不能爲空',
|
||||
required: '{0}是必填的',
|
||||
already_exists: '名稱不能重複',
|
||||
modifier: '修改人',
|
||||
@ -288,7 +290,7 @@ export default {
|
||||
start_date_time: '開始日期時間',
|
||||
end_date_time: '結束日期時間',
|
||||
range_separator: '至',
|
||||
data_time_error: '開始日期不能大與結束日期'
|
||||
data_time_error: '開始日期不能大于結束日期'
|
||||
},
|
||||
adv_search: {
|
||||
title: '高級搜索',
|
||||
@ -304,14 +306,14 @@ export default {
|
||||
is_not_empty: '非空',
|
||||
like: '包含',
|
||||
not_like: '不包含',
|
||||
in: '屬與',
|
||||
not_in: '不屬與',
|
||||
gt: '大與',
|
||||
ge: '大與等與',
|
||||
lt: '小與',
|
||||
le: '小與等與',
|
||||
equals: '等與',
|
||||
not_equals: '不等與',
|
||||
in: '屬于',
|
||||
not_in: '不屬于',
|
||||
gt: '大于',
|
||||
ge: '大于等于',
|
||||
lt: '小于',
|
||||
le: '小于等于',
|
||||
equals: '等于',
|
||||
not_equals: '不等于',
|
||||
between: '之間',
|
||||
current_user: '是當前用戶'
|
||||
},
|
||||
@ -355,23 +357,23 @@ export default {
|
||||
cancel: '取消'
|
||||
},
|
||||
guide: {
|
||||
description: '引導頁對與一些第一次進入項目的人很有用,你可以簡單介紹下項目的功能。本 Demo 是基與',
|
||||
description: '引導頁對于一些第一次進入項目的人很有用,你可以簡單介紹下項目的功能。本 Demo 是基于',
|
||||
button: '打開引導'
|
||||
},
|
||||
components: {
|
||||
documentation: '文檔',
|
||||
tinymceTips: '富文本是管理後臺一個核心的功能,但同時又是一個有很多坑的地方。在選擇富文本的過程中我也走了不少的彎路,市面上常見的富文本都基本用過了,最終權衡了一下選擇了Tinymce。更詳細的富文本比較和介紹見',
|
||||
dropzoneTips: '由與我司業務有特殊需求,而且要傳七牛 所以沒用第三方,選擇了自己封裝。代碼非常的簡單,具體代碼你可以在這裏看到 @/components/Dropzone',
|
||||
tinymceTips: '富文本是管理後台一個核心的功能,但同時又是一個有很多坑的地方。在選擇富文本的過程中我也走了不少的彎路,市面上常見的富文本都基本用過了,最終權衡了一下選擇了Tinymce。更詳細的富文本比較和介紹見',
|
||||
dropzoneTips: '由于我司業務有特殊需求,而且要傳七牛 所以沒用第三方,選擇了自己封裝。代碼非常的簡單,具體代碼你可以在這裏看到 @/components/Dropzone',
|
||||
stickyTips: '當頁面滾動到預設的位置會吸附在頂部',
|
||||
backToTopTips1: '頁面滾動到指定位置會在右下角出現返回頂部按鈕',
|
||||
backToTopTips2: '可自定義按鈕的樣式、show/hide、出現的高度、返回的位置 如需文字提示,可在外部使用Element的el-tooltip元素',
|
||||
imageUploadTips: '由與我在使用時它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的話,優先還是使用官方版本。'
|
||||
imageUploadTips: '由于我在使用時它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的話,優先還是使用官方版本。'
|
||||
},
|
||||
table: {
|
||||
dynamicTips1: '固定標頭,按照表頭順序排序',
|
||||
dynamicTips2: '不固定標頭, 按照點擊順序排序',
|
||||
dragTips1: '默認排序',
|
||||
dragTips2: '拖拽後排序',
|
||||
dynamicTips1: '固定表頭, 按照表頭順序排序',
|
||||
dynamicTips2: '不固定表頭, 按照點擊順序排序',
|
||||
dragTips1: '默認順序',
|
||||
dragTips2: '拖拽後順序',
|
||||
title: '標題',
|
||||
importance: '重要性',
|
||||
type: '類型',
|
||||
@ -390,15 +392,15 @@ export default {
|
||||
publish: '發布',
|
||||
draft: '草稿',
|
||||
delete: '刪除',
|
||||
cancel: '取消',
|
||||
confirm: '確定'
|
||||
cancel: '取 消',
|
||||
confirm: '確 定'
|
||||
},
|
||||
example: {
|
||||
warning: '創建和編輯頁面是不能被 keep-alive 緩存的,因為keep-alive 的 include 目前不支持根據路由來緩存,所以目前都是基與 component name 來進行緩存的。如果你想類似的實現緩存效果,可以使用 localStorage 等瀏覽器緩存方案。或者不要使用 keep-alive 的 include,直接緩存所有頁面。詳情見'
|
||||
warning: '創建和編輯頁面是不能被 keep-alive 緩存的,因爲keep-alive 的 include 目前不支持根據路由來緩存,所以目前都是基于 component name 來進行緩存的。如果你想類似的實現緩存效果,可以使用 localStorage 等浏覽器緩存方案。或者不要使用 keep-alive 的 include,直接緩存所有頁面。詳情見'
|
||||
},
|
||||
errorLog: {
|
||||
tips: '請點擊右上角bug小圖標',
|
||||
description: '現在的管理後臺基本都是spa的形式了,它增強了用戶體驗,但同時也會增加頁面出問題的可能性,可能一個小小的疏忽就導致整個頁面的死鎖。好在 Vue 官網提供了一個方法來捕獲處理異常,你可以在其中進行錯誤處理或者異常上報。',
|
||||
description: '現在的管理後台基本都是spa的形式了,它增強了用戶體驗,但同時也會增加頁面出問題的可能性,可能一個小小的疏忽就導致整個頁面的死鎖。好在 Vue 官網提供了一個方法來捕獲處理異常,你可以在其中進行錯誤處理或者異常上報。',
|
||||
documentation: '文檔介紹'
|
||||
},
|
||||
excel: {
|
||||
@ -411,34 +413,39 @@ export default {
|
||||
placeholder: '請輸入文件名(默認file)'
|
||||
},
|
||||
pdf: {
|
||||
tips: '這裏使用 window.print() 來實現下載pdf的功能'
|
||||
tips: '這裏使用 window.print() 來實現下載pdf的功能'
|
||||
},
|
||||
theme: {
|
||||
change: '換膚',
|
||||
documentation: '換膚文檔',
|
||||
tips: 'Tips: 它區別於 navbar 上的 theme-pick, 是兩種不同的換膚方法,各自有不同的應用場景,具體請參考文檔。'
|
||||
tips: 'Tips: 它區別于 navbar 上的 theme-pick, 是兩種不同的換膚方法,各自有不同的應用場景,具體請參考文檔。'
|
||||
},
|
||||
tagsView: {
|
||||
refresh: '刷新',
|
||||
close: '關閉',
|
||||
closeOthers: '關閉其他',
|
||||
closeOthers: '關閉其它',
|
||||
closeAll: '關閉所有'
|
||||
},
|
||||
settings: {
|
||||
title: '系統佈局配置',
|
||||
title: '系統布局配置',
|
||||
theme: '主題色',
|
||||
tagsView: '開啟 Tags-View',
|
||||
tagsView: '開啓 Tags-View',
|
||||
fixedHeader: '固定 Header',
|
||||
sidebarLogo: '側邊欄 Logo'
|
||||
},
|
||||
sysParams: {
|
||||
display: '顯示設置',
|
||||
ldap: 'LDAP設置',
|
||||
oidc: 'OIDC設置'
|
||||
},
|
||||
license: {
|
||||
i18n_no_license_record: '沒有 License 紀錄',
|
||||
i18n_license_is_empty: 'License 為空',
|
||||
i18n_no_license_record: '沒有 License 記錄',
|
||||
i18n_license_is_empty: 'License 爲空',
|
||||
title: '授權管理',
|
||||
corporation: '客戶名稱',
|
||||
time: '授權時間',
|
||||
product: '產品名稱',
|
||||
edition: '產品版本',
|
||||
product: '産品名稱',
|
||||
edition: '産品版本',
|
||||
licenseVersion: '授權版本',
|
||||
count: '授權數量',
|
||||
valid_license: '授權驗證',
|
||||
@ -469,7 +476,7 @@ export default {
|
||||
repeat_password: '確認密碼',
|
||||
inconsistent_passwords: '兩次輸入的密碼不一致',
|
||||
remove_member: '確定要移除該成員嗎',
|
||||
org_remove_member: '確定要移除該成員嗎?',
|
||||
org_remove_member: '將該用戶從組織中移除,將同時移除該組織下所有工作空間的權限,確定要移除該成員嗎?',
|
||||
input_id_or_email: '請輸入用戶 ID, 或者 用戶郵箱',
|
||||
no_such_user: '無此用戶信息, 請輸入正確的用戶 ID 或者 用戶郵箱!'
|
||||
},
|
||||
@ -482,6 +489,7 @@ export default {
|
||||
input_password: '請輸入密碼',
|
||||
input_phone: '請輸入電話號碼',
|
||||
input_roles: '請選擇角色',
|
||||
select_users: '請選擇用戶',
|
||||
special_characters_are_not_supported: '不支持特殊字符',
|
||||
mobile_number_format_is_incorrect: '手機號碼格式不正確',
|
||||
email_format_is_incorrect: '郵箱格式不正確',
|
||||
@ -496,7 +504,49 @@ export default {
|
||||
new_passwd: '新密碼',
|
||||
confirm_passwd: '確認密碼',
|
||||
change_password: '修改密碼',
|
||||
search_by_name: '按姓名搜索'
|
||||
search_by_name: '按姓名搜索',
|
||||
import_ldap: '導入LDAP用戶'
|
||||
},
|
||||
ldap: {
|
||||
url: 'LDAP地址',
|
||||
dn: '綁定DN',
|
||||
password: '密碼',
|
||||
ou: '用戶OU',
|
||||
filter: '用戶過濾器',
|
||||
mapping: 'LDAP屬性映射',
|
||||
open: '啓用LDAP認證',
|
||||
input_url: '請輸入LDAP地址',
|
||||
input_dn: '請輸入DN',
|
||||
input_password: '請輸入密碼',
|
||||
input_ou: '請輸入用戶OU',
|
||||
input_filter: '請輸入用戶過濾器',
|
||||
input_mapping: '請輸入LDAP屬性映射',
|
||||
input_username: '請輸入用戶名',
|
||||
input_url_placeholder: '請輸入LDAP地址 (如 ldap://localhost:389)',
|
||||
input_ou_placeholder: '輸入用戶OU (使用|分隔各OU)',
|
||||
input_filter_placeholder: '輸入過濾器 [可能的選項是cn或uid或sAMAccountName={0}, 如:(uid={0})]',
|
||||
input_mapping_placeholder: '如:{"username":"uid","name":"sn","email":"mail"}, username映射的選項可能是cn或uid或sAMAccountName',
|
||||
test_connect: '測試連接',
|
||||
test_login: '測試登錄',
|
||||
edit: '編輯',
|
||||
login_success: '登錄成功',
|
||||
url_cannot_be_empty: 'LDAP 地址不能爲空',
|
||||
dn_cannot_be_empty: 'LDAP DN不能爲空',
|
||||
ou_cannot_be_empty: 'LDAP OU不能爲空',
|
||||
filter_cannot_be_empty: 'LDAP 用戶過濾器不能爲空',
|
||||
mapping_cannot_be_empty: 'LDAP 用戶屬性映射不能爲空',
|
||||
password_cannot_be_empty: 'LDAP 密碼不能爲空'
|
||||
},
|
||||
oidc: {
|
||||
auth_endpoint: '請輸入AuthEndpoint',
|
||||
token_endpoint: '請輸入TokenEndpoint',
|
||||
userinfo_endpoint: '請輸入UserinfoEndpoint',
|
||||
logout_endpoint: '請輸入logoutEndpoint',
|
||||
clientId: '請輸入ClientId',
|
||||
secret: '請輸入Secret',
|
||||
scope: '請輸入scope',
|
||||
redirectUrl: '請輸入redirectUrl',
|
||||
open: '啓用OIDC認證'
|
||||
},
|
||||
role: {
|
||||
menu_authorization: '菜單授權',
|
||||
@ -528,7 +578,7 @@ export default {
|
||||
create: '創建菜單',
|
||||
modify: '修改菜單',
|
||||
delete: '刪除菜單',
|
||||
delete_confirm: '確定刪除菜單嗎?',
|
||||
delete_confirm: '確定刪除菜單嗎',
|
||||
menu_type: '菜單類型'
|
||||
},
|
||||
organization: {
|
||||
@ -551,19 +601,19 @@ export default {
|
||||
},
|
||||
system_parameter_setting: {
|
||||
mailbox_service_settings: '郵件設置',
|
||||
test_connection: '測試鏈接',
|
||||
test_connection: '測試連接',
|
||||
SMTP_host: 'SMTP主機',
|
||||
SMTP_port: 'SMTP端口',
|
||||
SMTP_account: 'SMTP帳號',
|
||||
SMTP_account: 'SMTP賬戶',
|
||||
SMTP_password: 'SMTP密碼',
|
||||
SSL: '開啟SSL(如果SMTP端口是465,通常需要啟用SSL)',
|
||||
TLS: '開啟TLS(如果SMTP端口是587,通常需要啟用TLS)',
|
||||
SSL: '開啓SSL(如果SMTP端口是465,通常需要啓用SSL)',
|
||||
TLS: '開啓TLS(如果SMTP端口是587,通常需要啓用TLS)',
|
||||
SMTP: '是否免密 SMTP',
|
||||
host: '主機不能為空',
|
||||
port: '端口號不能為空',
|
||||
account: '帳戶不能為空',
|
||||
host: '主機號不能爲空',
|
||||
port: '端口號不能爲空',
|
||||
account: '賬戶不能爲空',
|
||||
test_recipients: '測試收件人',
|
||||
tip: ' 提示: 僅用來作為測試郵件收件人'
|
||||
tip: '提示:僅用來作爲測試郵件收件人'
|
||||
},
|
||||
chart: {
|
||||
save_snapshot: '保存縮略圖',
|
||||
@ -589,14 +639,14 @@ export default {
|
||||
sql_data: 'SQL數據集',
|
||||
excel_data: 'Excel數據集',
|
||||
custom_data: '自定義數據集',
|
||||
pls_slc_tbl_left: '請從左側選擇視圖',
|
||||
add_db_table: '添加數據庫表',
|
||||
pls_slc_tbl_left: '請從左側選視圖',
|
||||
add_db_table: '添加數據庫數據集',
|
||||
pls_slc_data_source: '請選擇數據源',
|
||||
table: '表',
|
||||
edit: '編輯',
|
||||
create_view: '創建視圖',
|
||||
create_view: '創建試圖',
|
||||
data_preview: '數據預覽',
|
||||
dimension: '緯度',
|
||||
dimension: '維度',
|
||||
quota: '指標',
|
||||
title: '標題',
|
||||
show: '顯示',
|
||||
@ -608,22 +658,22 @@ export default {
|
||||
y_axis: '縱軸',
|
||||
chart: '視圖',
|
||||
close: '關閉',
|
||||
summary: '匯總方式',
|
||||
summary: '彙總方式',
|
||||
fast_calc: '快速計算',
|
||||
sum: '求和',
|
||||
count: '記數',
|
||||
count: '計數',
|
||||
avg: '平均',
|
||||
max: '最大值',
|
||||
min: '最小值',
|
||||
stddev_pop: '標準差',
|
||||
stddev_pop: '標准差',
|
||||
var_pop: '方差',
|
||||
quick_calc: '快速計算',
|
||||
show_name_set: '顯示名設置',
|
||||
color: '顏色',
|
||||
color: '顔色',
|
||||
color_case: '配色方案',
|
||||
pls_slc_color_case: '請選餓配色方案',
|
||||
pls_slc_color_case: '請選擇配色方案',
|
||||
color_default: '默認',
|
||||
color_retro: '復古',
|
||||
color_retro: '複古',
|
||||
color_future: '未來',
|
||||
color_gradual: '漸變',
|
||||
color_business: '商務',
|
||||
@ -640,7 +690,7 @@ export default {
|
||||
line_type: '線型',
|
||||
line_symbol: '折點',
|
||||
line_symbol_size: '折點大小',
|
||||
line_type_solid: '實現',
|
||||
line_type_solid: '實線',
|
||||
line_type_dashed: '虛線',
|
||||
line_symbol_circle: '圓形',
|
||||
line_symbol_emptyCircle: '空心圓',
|
||||
@ -652,13 +702,13 @@ export default {
|
||||
line_symbol_arrow: '箭頭',
|
||||
line_symbol_none: '無',
|
||||
line_area: '面積',
|
||||
pie_inner_radius: '內經',
|
||||
pie_outer_radius: '外經',
|
||||
pie_inner_radius: '內徑',
|
||||
pie_outer_radius: '外徑',
|
||||
funnel_width: '寬度',
|
||||
line_smooth: '平滑折線',
|
||||
title_style: '標題格式',
|
||||
title_style: '標題樣式',
|
||||
text_fontsize: '字體大小',
|
||||
text_color: '字體顏色',
|
||||
text_color: '字體顔色',
|
||||
text_h_position: '水平位置',
|
||||
text_v_position: '垂直位置',
|
||||
text_pos_left: '左',
|
||||
@ -674,23 +724,23 @@ export default {
|
||||
legend: '圖例',
|
||||
shape: '形狀',
|
||||
polygon: '多邊形',
|
||||
circle: '圖形',
|
||||
label: '標籤',
|
||||
label_position: '標籤位置',
|
||||
circle: '圓形',
|
||||
label: '標簽',
|
||||
label_position: '標簽位置',
|
||||
content_formatter: '內容格式',
|
||||
inside: '內',
|
||||
tooltip: '提示',
|
||||
tooltip_item: '數據項',
|
||||
tooltip_axis: '座標軸',
|
||||
formatter_plc: '內痛格式為空時,顯示默認格式',
|
||||
xAxis: '橫洲',
|
||||
tooltip_axis: '坐標軸',
|
||||
formatter_plc: '內容格式爲空時,顯示默認格式',
|
||||
xAxis: '橫軸',
|
||||
yAxis: '縱軸',
|
||||
position: '位置',
|
||||
rotate: '角度',
|
||||
name: '名稱',
|
||||
icon: '國際',
|
||||
icon: '圖標',
|
||||
trigger_position: '觸發位置',
|
||||
asc: '昇序',
|
||||
asc: '升序',
|
||||
desc: '降序',
|
||||
sort: '排序',
|
||||
filter: '過濾',
|
||||
@ -701,39 +751,39 @@ export default {
|
||||
border_radius: '邊框半徑',
|
||||
alpha: '透明度',
|
||||
add_filter: '添加過濾',
|
||||
no_limit: '無顯示',
|
||||
filter_eq: '等於',
|
||||
filter_not_eq: '不等於',
|
||||
filter_lt: '小於',
|
||||
filter_le: '小於等於',
|
||||
filter_gt: '大於',
|
||||
filter_ge: '大於等於',
|
||||
filter_null: '為空',
|
||||
filter_not_null: '不為空',
|
||||
no_limit: '無限制',
|
||||
filter_eq: '等于',
|
||||
filter_not_eq: '不等于',
|
||||
filter_lt: '小于',
|
||||
filter_le: '小于等于',
|
||||
filter_gt: '大于',
|
||||
filter_ge: '大于等于',
|
||||
filter_null: '爲空',
|
||||
filter_not_null: '不爲空',
|
||||
filter_include: '包含',
|
||||
filter_not_include: '不包含',
|
||||
rose_type: '玫瑰圖模式',
|
||||
radius_mode: '半徑',
|
||||
area_mode: '面積',
|
||||
rose_radius: '園角',
|
||||
rose_radius: '圓角',
|
||||
view_name: '視圖標題',
|
||||
belong_group: '所屬分組',
|
||||
select_group: '選擇分組',
|
||||
name_can_not_empty: '名稱不能為空',
|
||||
template_can_not_empty: '請選擇儀表板',
|
||||
name_can_not_empty: '名稱不能爲空',
|
||||
template_can_not_empty: '請選擇儀表版',
|
||||
custom_count: '記錄數',
|
||||
table_title_fontsize: '表頭字體大小',
|
||||
table_item_fontsize: '表格字體大小',
|
||||
table_header_bg: '表頭背景',
|
||||
table_item_bg: '表格背景',
|
||||
table_item_font_color: '字體顏色',
|
||||
table_item_font_color: '字體顔色',
|
||||
stripe: '斑馬紋',
|
||||
start_angle: '起始角度',
|
||||
end_angle: '結束角度',
|
||||
style_priority: '樣式優先級',
|
||||
dashboard: '儀表板',
|
||||
dimension_color: '名稱顏色',
|
||||
quota_color: '值顏色',
|
||||
dimension_color: '名稱顔色',
|
||||
quota_color: '值顔色',
|
||||
dimension_font_size: '名稱字體大小',
|
||||
quota_font_size: '值字體大小',
|
||||
space_split: '名稱/值間隔',
|
||||
@ -741,11 +791,11 @@ export default {
|
||||
only_one_result: '僅顯示第1個計算結果',
|
||||
dimension_show: '名稱顯示',
|
||||
quota_show: '值顯示',
|
||||
title_limit: '標題不能大於50個字符',
|
||||
title_limit: '標題不能大于50個字符',
|
||||
filter_condition: '過濾條件',
|
||||
filter_field_can_null: '過濾字段必填',
|
||||
preview_100_data: '預覽前100條記錄',
|
||||
chart_table_normal: '匯總表',
|
||||
chart_table_normal: '彙總表',
|
||||
chart_table_info: '明細表',
|
||||
chart_card: '指標卡',
|
||||
chart_bar: '基礎柱狀圖',
|
||||
@ -773,24 +823,24 @@ export default {
|
||||
chartName: '新建視圖',
|
||||
chart_show_error: '無法正常顯示',
|
||||
chart_error_tips: '如有疑問請聯系管理員',
|
||||
title_cannot_empty: '標題不能為空',
|
||||
title_cannot_empty: '標題不能爲空',
|
||||
table_title_height: '表頭行高',
|
||||
table_item_height: '表格行高',
|
||||
axis_show: '軸線顯示',
|
||||
axis_color: '軸線顏色',
|
||||
axis_color: '軸線顔色',
|
||||
axis_width: '軸線寬度',
|
||||
axis_type: '軸線類型',
|
||||
axis_type_solid: '實線',
|
||||
axis_type_dashed: '虛線',
|
||||
axis_type_dotted: '點',
|
||||
axis_label_show: '標簽顯示',
|
||||
axis_label_color: '標簽顏色',
|
||||
axis_label_color: '標簽顔色',
|
||||
axis_label_fontsize: '標簽大小',
|
||||
text_style: '字體樣式',
|
||||
bolder: '加粗',
|
||||
change_ds: '更換數據集',
|
||||
change_ds_tip: '提示:更換數據集將導致字段發生變化,需重新製作視圖',
|
||||
axis_name_color: '名稱顏色',
|
||||
change_ds_tip: '提示:更換數據集將導致字段發生變化,需重新制作視圖',
|
||||
axis_name_color: '名稱顔色',
|
||||
axis_name_fontsize: '名稱字體',
|
||||
pie_label_line_show: '引導線',
|
||||
outside: '外',
|
||||
@ -800,10 +850,10 @@ export default {
|
||||
axis_label: '軸標簽',
|
||||
label_fontsize: '標簽大小',
|
||||
split_line: '分割線',
|
||||
split_color: '分割顏色',
|
||||
split_color: '分割顔色',
|
||||
shadow: '陰影',
|
||||
condition: '過濾值',
|
||||
filter_value_can_null: '過濾值不能為空',
|
||||
filter_value_can_null: '過濾值不能爲空',
|
||||
filter_like: '包含',
|
||||
filter_not_like: '不包含',
|
||||
color_light: '明亮',
|
||||
@ -838,7 +888,7 @@ export default {
|
||||
chart_scatter: '散點圖',
|
||||
bubble_size: '氣泡大小',
|
||||
chart_treemap: '矩形樹圖',
|
||||
drill: '鉆取',
|
||||
drill: '鑽取',
|
||||
drag_block_treemap_label: '色塊標簽',
|
||||
drag_block_treemap_size: '色塊大小',
|
||||
bubble_symbol: '圖形',
|
||||
@ -861,10 +911,23 @@ export default {
|
||||
yAxis_main: '主縱軸',
|
||||
yAxis_ext: '副縱軸',
|
||||
total: '共',
|
||||
items: '條數據'
|
||||
items: '條數據',
|
||||
chart_liquid: '水波圖',
|
||||
drag_block_progress: '進度指示',
|
||||
liquid_max: '目標值',
|
||||
liquid_outline_border: '邊框粗細',
|
||||
liquid_outline_distance: '邊框間隔',
|
||||
liquid_wave_length: '水波長度',
|
||||
liquid_wave_count: '水波數量',
|
||||
liquid_shape: '形狀',
|
||||
liquid_shape_circle: '圓形',
|
||||
liquid_shape_diamond: '菱形',
|
||||
liquid_shape_triangle: '三角形',
|
||||
liquid_shape_pin: '氣球',
|
||||
liquid_shape_rect: '矩形'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多個sheet頁面,默認抽取第一個',
|
||||
sheet_warn: '有多個 Sheet 頁,默認抽取第一個',
|
||||
datalist: '數據集',
|
||||
name: '數據集名稱',
|
||||
add_group: '添加分組',
|
||||
@ -905,7 +968,7 @@ export default {
|
||||
time: '時間',
|
||||
value: '數值',
|
||||
mode: '模式',
|
||||
direct_connect: '直鏈',
|
||||
direct_connect: '直連',
|
||||
sync_data: '定時同步',
|
||||
update_setting: '更新設置',
|
||||
sync_now: '立即更新',
|
||||
@ -924,10 +987,10 @@ export default {
|
||||
add_scope: '增量更新',
|
||||
select_data_time: '選擇日期時間',
|
||||
execute_rate: '執行頻率',
|
||||
simple_cron: '簡單重複',
|
||||
execute_once: '立即執行',
|
||||
cron_config: '表達時設定',
|
||||
no_limit: '無限製',
|
||||
simple_cron: '簡單重複',
|
||||
cron_config: '表達式設定',
|
||||
no_limit: '無限制',
|
||||
set_end_time: '設定結束時間',
|
||||
operate: '操作',
|
||||
save_success: '保存成功',
|
||||
@ -937,7 +1000,7 @@ export default {
|
||||
add_sql_table: '添加 SQL 數據集',
|
||||
preview: '預覽',
|
||||
pls_input_name: '請輸入名稱',
|
||||
connect_mode: '鏈接模式',
|
||||
connect_mode: '連接模式',
|
||||
incremental_update_type: '增量更新方式',
|
||||
incremental_add: '增量添加',
|
||||
incremental_delete: '增量刪除',
|
||||
@ -946,7 +1009,7 @@ export default {
|
||||
param: '參數',
|
||||
edit_sql: '編輯 SQL 數據集',
|
||||
showRow: '顯示行',
|
||||
add_excel_table: ' 添加 Excel 數據集',
|
||||
add_excel_table: '添加Excel數據集',
|
||||
add_custom_table: '添加自定義數據集',
|
||||
upload_file: '上傳文件',
|
||||
detail: '詳情',
|
||||
@ -968,14 +1031,14 @@ export default {
|
||||
source_field: '關聯字段',
|
||||
target_table: '被關聯表',
|
||||
target_field: '被關聯字段',
|
||||
union_relation: '關聯關係',
|
||||
pls_setting_union_success: '請正確設置關聯關係',
|
||||
invalid_dataset: ' Kettle 未運行,無效數據集',
|
||||
check_all: '銓選',
|
||||
union_relation: '關聯關系',
|
||||
pls_setting_union_success: '請正確設置關聯關系',
|
||||
invalid_dataset: 'Kettle未運行,無效數據集',
|
||||
check_all: '全選',
|
||||
can_not_union_self: '被關聯表不能與關聯表相同',
|
||||
float: '小數',
|
||||
edit_custom_table: '編輯自助數據集',
|
||||
edit_field: '編輯自斷',
|
||||
edit_custom_table: '編輯自定義數據集',
|
||||
edit_field: '編輯字段',
|
||||
preview_100_data: '顯示前100行數據',
|
||||
invalid_table_check: '非直連數據集請先完成數據同步',
|
||||
parse_error: 'Excel解析失敗,請檢查格式、字段等信息。具體參考:https://dataease.io/docs/faq/dataset_faq/',
|
||||
@ -993,7 +1056,7 @@ export default {
|
||||
sync_latter: '稍後同步',
|
||||
task: {
|
||||
list: '任務列表',
|
||||
record: '執行紀錄',
|
||||
record: '執行記錄',
|
||||
create: '新建任務',
|
||||
name: '任務名稱',
|
||||
last_exec_time: '上次執行時間',
|
||||
@ -1029,10 +1092,10 @@ export default {
|
||||
calc_field: '計算字段',
|
||||
show_sql: '顯示SQL',
|
||||
ple_select_excel: '請選擇要導入的 Excel',
|
||||
merge: '合併',
|
||||
no_merge: '不合併',
|
||||
merge_msg: '數據表中存在自斷一直的情況,是否合併到一個數據集中?',
|
||||
merge_title: '合併數據',
|
||||
merge: '合並',
|
||||
no_merge: '不合並',
|
||||
merge_msg: '數據表中存在字段一致的情況,是否合並到一個數據集中?',
|
||||
merge_title: '合並數據',
|
||||
field_name_less_50: '字段名不能超過50個字符'
|
||||
},
|
||||
datasource: {
|
||||
@ -1050,16 +1113,17 @@ export default {
|
||||
datasource_url: '地址',
|
||||
please_input_datasource_url: '請輸入 Elasticsearch 地址,如: http://es_host:es_port',
|
||||
please_input_data_base: '請輸入數據庫名稱',
|
||||
please_select_oracle_type: '選擇連接類型',
|
||||
please_input_user_name: '請輸入用戶名',
|
||||
please_input_password: '請輸入密碼',
|
||||
please_input_host: '請輸入主機',
|
||||
please_input_url: '請輸入URL地址',
|
||||
please_input_port: '請輸入',
|
||||
please_input_port: '請輸入端口',
|
||||
modify: '編輯數據源',
|
||||
validate_success: '校驗成功',
|
||||
validate: '校驗',
|
||||
search_by_name: '根據名稱搜索',
|
||||
delete_warning: '確認刪除?',
|
||||
delete_warning: '確定要刪除嗎?',
|
||||
input_name: '請輸入名稱',
|
||||
input_limit_2_25: '2-25字符',
|
||||
input_limit_0_50: '0-50字符',
|
||||
@ -1069,20 +1133,21 @@ export default {
|
||||
get_schema: '獲取 Schema',
|
||||
schema: '數據庫 Schema',
|
||||
please_choose_schema: '請選擇數據庫 Schema',
|
||||
edit_datasource_msg: '修改數據源信息,可能會導致改數據源下的數據集不可用,確認修改?',
|
||||
in_valid: '無效數據源',
|
||||
initial_pool_size: '初始連結數',
|
||||
min_pool_size: '最小連結數',
|
||||
max_pool_size: '最大連結數',
|
||||
max_idle_time: '最大空閒(秒)',
|
||||
initial_pool_size: '初始連接數',
|
||||
min_pool_size: '最小連接數',
|
||||
max_pool_size: '最大連接數',
|
||||
max_idle_time: '最大空閑(秒)',
|
||||
acquire_increment: '增長數',
|
||||
connect_timeout: '連接超時(秒)',
|
||||
please_input_initial_pool_size: '請輸入初始連結數',
|
||||
please_input_min_pool_size: '請輸入最小連結數',
|
||||
please_input_max_pool_size: '請輸入最大連結數',
|
||||
please_input_max_idle_time: '請輸入最大空閒(秒)',
|
||||
please_input_initial_pool_size: '請輸入初始連接數',
|
||||
please_input_min_pool_size: '請輸入最小連接數',
|
||||
please_input_max_pool_size: '請輸入最大連接數',
|
||||
please_input_max_idle_time: '請輸入最大空閑(秒)',
|
||||
please_input_acquire_increment: '請輸入增長數',
|
||||
please_input_connect_timeout: '請輸入連接超時(秒)',
|
||||
no_less_then_0: '高級設置中的參數不能小於零',
|
||||
no_less_then_0: '高級設置中的參數不能小于零',
|
||||
priority: '高級設置'
|
||||
},
|
||||
pblink: {
|
||||
@ -1097,14 +1162,14 @@ export default {
|
||||
auth_role: '已分享角色',
|
||||
picture_limit: '只能插入圖片',
|
||||
drag_here: '請將左側字段拖至此處',
|
||||
copy_link_passwd: '複製鏈接及密碼',
|
||||
copy_link: '複製鏈接',
|
||||
copy_short_link: '複製短鏈接',
|
||||
copy_short_link_passwd: '複製短鏈接及密碼',
|
||||
copy_link_passwd: '複制鏈接及密碼',
|
||||
copy_link: '複制鏈接',
|
||||
copy_short_link: '複制短鏈接',
|
||||
copy_short_link_passwd: '複制短鏈接及密碼',
|
||||
passwd_protect: '密碼保護',
|
||||
link: '鏈接',
|
||||
link_share: '鏈接分享',
|
||||
link_share_desc: '開啟鏈接後,任何人可通過此鏈接訪問儀表板。',
|
||||
link_share_desc: '開啓鏈接後,任何人可通過此鏈接訪問儀表板。',
|
||||
share: '分享',
|
||||
datalist: '視圖列表',
|
||||
group: '目錄',
|
||||
@ -1126,7 +1191,7 @@ export default {
|
||||
view: '視圖',
|
||||
module: '組件',
|
||||
filter_module: '過濾組件',
|
||||
select_by_module: '安組件選擇',
|
||||
select_by_module: '按組件選擇',
|
||||
edit: '編輯',
|
||||
sys_template: '系統模板',
|
||||
user_template: '用戶模板',
|
||||
@ -1140,12 +1205,12 @@ export default {
|
||||
photo: '圖片',
|
||||
default_panel: '默認儀表板',
|
||||
create_public_links: '創建公共鏈接',
|
||||
to_default: '另存為默認',
|
||||
to_default_panel: '另存為默認儀表板',
|
||||
to_default: '另存爲默認',
|
||||
to_default_panel: '另存爲默認儀表板',
|
||||
store: '收藏',
|
||||
save_to_panel: '保存為模板',
|
||||
export_to_panel: '導出為模板',
|
||||
export_to_pdf: '導出為PDF',
|
||||
save_to_panel: '保存爲模板',
|
||||
export_to_panel: '導出爲模板',
|
||||
export_to_pdf: '導出爲PDF',
|
||||
preview: '預覽',
|
||||
fullscreen_preview: '全屏預覽',
|
||||
new_tab_preview: '新Tab頁預覽',
|
||||
@ -1156,21 +1221,21 @@ export default {
|
||||
all_org: '所有組織',
|
||||
custom: '自定義',
|
||||
import_template: '導入模板',
|
||||
copy_template: '復用模板',
|
||||
copy_template: '複用模板',
|
||||
upload_template: '上傳模板',
|
||||
belong_to_category: '所屬類別',
|
||||
pls_select_belong_to_category: '請選擇所屬類別',
|
||||
template_name_cannot_be_empty: '模板名稱不能為空',
|
||||
select_by_table: '列表選擇',
|
||||
template_name_cannot_be_empty: '模板名稱不能爲空',
|
||||
select_by_table: '按表選擇',
|
||||
data_list: '數據列表',
|
||||
component_list: '組件列表',
|
||||
custom_scope: '自定義控製範圍',
|
||||
custom_scope: '自定義控制範圍',
|
||||
multiple_choice: '多選',
|
||||
single_choice: '單選',
|
||||
field: '字段',
|
||||
unshared_people: '未分享人員',
|
||||
shared_people: '已分享人員',
|
||||
error_data: '獲取數據出錯,請聯繫管理員',
|
||||
error_data: '獲取數據出錯,請聯系管理員',
|
||||
canvas_size: '畫布大小',
|
||||
canvas_scale: '畫布比例',
|
||||
style: '樣式',
|
||||
@ -1179,7 +1244,7 @@ export default {
|
||||
redo: '重做',
|
||||
undo: '撤銷',
|
||||
panelNull: '這是個空的儀表板,可以通過編輯來豐富內容',
|
||||
copy: '復製',
|
||||
copy: '複制',
|
||||
paste: '粘貼',
|
||||
cut: '剪切',
|
||||
lock: '鎖定',
|
||||
@ -1197,11 +1262,11 @@ export default {
|
||||
top: 'y 坐標',
|
||||
height: '高',
|
||||
width: '寬',
|
||||
color: '顏色',
|
||||
color: '顔色',
|
||||
backgroundColor: '背景色',
|
||||
borderStyle: '邊框風格',
|
||||
borderWidth: '邊框寬度',
|
||||
borderColor: '邊框顏色',
|
||||
borderColor: '邊框顔色',
|
||||
borderRadius: '邊框半徑',
|
||||
fontSize: '字體大小',
|
||||
fontWeight: '字體粗細',
|
||||
@ -1254,12 +1319,21 @@ export default {
|
||||
uninstall_cancel: '取消卸載插件'
|
||||
},
|
||||
display: {
|
||||
logo: '頭部系統 Logo',
|
||||
loginLogo: '登陸頁面頭部 Logo',
|
||||
loginImage: '登陸頁面右側圖片',
|
||||
loginTitle: '登陸頁面標題',
|
||||
logo: '頭部系統logo',
|
||||
loginLogo: '登錄頁面頭部logo',
|
||||
loginImage: '登錄頁面右側圖片',
|
||||
loginTitle: '登錄頁面標題',
|
||||
title: '系統名稱',
|
||||
advice_size: '建議圖片大小'
|
||||
advice_size: '建議圖片大小',
|
||||
theme: '主題顔色',
|
||||
|
||||
topMenuColor: '頭部背景',
|
||||
topMenuActiveColor: '頭部選中背景',
|
||||
|
||||
topMenuTextColor: '頭部字體顔色',
|
||||
|
||||
topMenuTextActiveColor: '頭部字體選中顔色'
|
||||
|
||||
},
|
||||
auth: {
|
||||
authConfig: '權限配置',
|
||||
@ -1279,6 +1353,7 @@ export default {
|
||||
datasetAuthHead: '所有數據集',
|
||||
chartAuthHead: '所有視圖',
|
||||
panelAuthHead: '所有儀表板',
|
||||
menuAuthHead: '所有菜單和操作',
|
||||
view: '查看',
|
||||
use: '使用',
|
||||
export: '導出',
|
||||
@ -1293,13 +1368,13 @@ export default {
|
||||
auth_num: '授權數量',
|
||||
version: '版本',
|
||||
version_num: '版本號',
|
||||
standard: '標準版',
|
||||
standard: '標准版',
|
||||
enterprise: '企業版',
|
||||
suport: '獲取技術支持',
|
||||
update_success: '更新成功'
|
||||
},
|
||||
template: {
|
||||
exit_same_template_check: '當前存在相同名稱模板,是否覆蓋?',
|
||||
exit_same_template_check: '當前分類存在相同名稱模板,是否覆蓋?',
|
||||
override: '覆蓋',
|
||||
cancel: '取消',
|
||||
confirm_upload: '上傳確認'
|
||||
@ -1315,8 +1390,8 @@ export default {
|
||||
month: '月',
|
||||
week: '周',
|
||||
year: '年',
|
||||
d_w_cant_not_set: '日期與星期不可以同時為“不指定”',
|
||||
d_w_must_one_set: '日期與星期必須有一個為“不指定”',
|
||||
d_w_cant_not_set: '日期與星期不可以同時爲“不指定”',
|
||||
d_w_must_one_set: '日期與星期必須有一個爲“不指定”',
|
||||
every_day: '每日',
|
||||
cycle: '周期',
|
||||
not_set: '不指定',
|
||||
@ -1344,15 +1419,15 @@ export default {
|
||||
week_end: '至星期',
|
||||
every_year: '每年',
|
||||
week_tips: '說明:1-7 分別對應 周日-周六',
|
||||
minute_limit: '分鐘不能小於1,大於59',
|
||||
hour_limit: '小時不能小於1,大於523',
|
||||
day_limit: '天不能小於1,大於531'
|
||||
minute_limit: '分鍾不能小于1,大于59',
|
||||
hour_limit: '小時不能小于1,大于23',
|
||||
day_limit: '天不能小于1,大于31'
|
||||
},
|
||||
dept: {
|
||||
can_not_move_change_sort: '不能移動以改變排序',
|
||||
can_not_move_parent_to_children: '父組織不能移動到自己的子節點下',
|
||||
move_success: '移動成功',
|
||||
name_exist_pre: '下已存在名稱為【',
|
||||
name_exist_pre: '下已存在名稱爲【',
|
||||
name_exist_suf: '】的組織',
|
||||
root_org: '頂層組織'
|
||||
},
|
||||
|
@ -130,6 +130,8 @@ export default {
|
||||
re_login: '重新登录'
|
||||
},
|
||||
commons: {
|
||||
search: '搜索',
|
||||
folder: '目录',
|
||||
no_target_permission: '没有权限',
|
||||
success: '成功',
|
||||
switch_lang: '切换语言成功',
|
||||
@ -431,6 +433,11 @@ export default {
|
||||
fixedHeader: '固定 Header',
|
||||
sidebarLogo: '侧边栏 Logo'
|
||||
},
|
||||
sysParams: {
|
||||
display: '显示设置',
|
||||
ldap: 'LDAP设置',
|
||||
oidc: 'OIDC设置'
|
||||
},
|
||||
license: {
|
||||
i18n_no_license_record: '没有 License 记录',
|
||||
i18n_license_is_empty: 'License 为空',
|
||||
@ -530,6 +537,17 @@ export default {
|
||||
mapping_cannot_be_empty: 'LDAP 用户属性映射不能为空',
|
||||
password_cannot_be_empty: 'LDAP 密码不能为空'
|
||||
},
|
||||
oidc: {
|
||||
auth_endpoint: '请输入AuthEndpoint',
|
||||
token_endpoint: '请输入TokenEndpoint',
|
||||
userinfo_endpoint: '请输入UserinfoEndpoint',
|
||||
logout_endpoint: '请输入logoutEndpoint',
|
||||
clientId: '请输入ClientId',
|
||||
secret: '请输入Secret',
|
||||
scope: '请输入scope',
|
||||
redirectUrl: '请输入redirectUrl',
|
||||
open: '启用OIDC认证'
|
||||
},
|
||||
role: {
|
||||
menu_authorization: '菜单授权',
|
||||
data_authorization: '数据授权',
|
||||
@ -893,7 +911,20 @@ export default {
|
||||
yAxis_main: '主纵轴',
|
||||
yAxis_ext: '副纵轴',
|
||||
total: '共',
|
||||
items: '条数据'
|
||||
items: '条数据',
|
||||
chart_liquid: '水波图',
|
||||
drag_block_progress: '进度指示',
|
||||
liquid_max: '目标值',
|
||||
liquid_outline_border: '边框粗细',
|
||||
liquid_outline_distance: '边框间隔',
|
||||
liquid_wave_length: '水波长度',
|
||||
liquid_wave_count: '水波数量',
|
||||
liquid_shape: '形状',
|
||||
liquid_shape_circle: '圆形',
|
||||
liquid_shape_diamond: '菱形',
|
||||
liquid_shape_triangle: '三角形',
|
||||
liquid_shape_pin: '气球',
|
||||
liquid_shape_rect: '矩形'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多个 Sheet 页,默认抽取第一个',
|
||||
|
@ -3,6 +3,9 @@ module.exports = {
|
||||
RefreshTokenKey: 'refreshauthorization',
|
||||
LinkTokenKey: 'LINK-PWD-TOKEN',
|
||||
title: 'DataEase',
|
||||
/* for sso */
|
||||
IdTokenKey: 'IdToken',
|
||||
AccessTokenKey: 'AccessToken',
|
||||
|
||||
/**
|
||||
* @type {boolean} true | false
|
||||
|
@ -79,6 +79,9 @@ const data = {
|
||||
},
|
||||
|
||||
setCanvasStyle(state, style) {
|
||||
if (style) {
|
||||
style['selfAdaption'] = true
|
||||
}
|
||||
state.canvasStyleData = style
|
||||
},
|
||||
|
||||
|
@ -3,8 +3,16 @@ import Config from '@/settings'
|
||||
|
||||
const TokenKey = Config.TokenKey
|
||||
|
||||
const IdTokenKey = Config.IdTokenKey
|
||||
|
||||
const AccessTokenKey = Config.AccessTokenKey
|
||||
|
||||
const linkTokenKey = Config.LinkTokenKey
|
||||
|
||||
export function getIdToken() {
|
||||
return Cookies.get(IdTokenKey)
|
||||
}
|
||||
|
||||
export function getToken() {
|
||||
return Cookies.get(TokenKey)
|
||||
}
|
||||
@ -14,6 +22,8 @@ export function setToken(token) {
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
Cookies.remove(IdTokenKey)
|
||||
Cookies.remove(AccessTokenKey)
|
||||
return Cookies.remove(TokenKey)
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import axios from 'axios'
|
||||
// import { MessageBox, Message } from 'element-ui'
|
||||
import store from '@/store'
|
||||
import { $alert, $error } from './message'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { getToken, getIdToken } from '@/utils/auth'
|
||||
import Config from '@/settings'
|
||||
import i18n from '@/lang'
|
||||
import { tryShowLoading, tryHideLoading } from './loading'
|
||||
@ -23,6 +23,10 @@ const service = axios.create({
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
// do something before request is sent
|
||||
const idToken = getIdToken()
|
||||
if (idToken) {
|
||||
config.headers[Config.IdTokenKey] = idToken
|
||||
}
|
||||
|
||||
if (store.getters.token) {
|
||||
// let each request carry token
|
||||
|
@ -42,7 +42,14 @@ export const DEFAULT_SIZE = {
|
||||
scatterSymbol: 'circle',
|
||||
scatterSymbolSize: 20,
|
||||
treemapWidth: 80,
|
||||
treemapHeight: 80
|
||||
treemapHeight: 80,
|
||||
liquidMax: 100,
|
||||
liquidSize: 80,
|
||||
liquidOutlineBorder: 4,
|
||||
liquidOutlineDistance: 8,
|
||||
liquidWaveLength: 128,
|
||||
liquidWaveCount: 3,
|
||||
liquidShape: 'circle'
|
||||
}
|
||||
export const DEFAULT_LABEL = {
|
||||
show: false,
|
||||
|
104
frontend/src/views/chart/chart/liquid/liquid.js
Normal file
104
frontend/src/views/chart/chart/liquid/liquid.js
Normal file
@ -0,0 +1,104 @@
|
||||
import { Liquid } from '@antv/g2plot'
|
||||
import { digToHex } from '@/views/chart/chart/util'
|
||||
import { DEFAULT_SIZE } from '@/views/chart/chart/chart'
|
||||
|
||||
export function baseLiquid(plot, container, chart) {
|
||||
let value = 0
|
||||
const colors = []
|
||||
let max, radius, outlineBorder, outlineDistance, waveLength, waveCount, bgColor, shape, labelContent, title
|
||||
if (chart.data) {
|
||||
if (chart.data.series.length > 0) {
|
||||
value = chart.data.series[0].data[0].value
|
||||
}
|
||||
}
|
||||
let customAttr = {}
|
||||
if (chart.customAttr) {
|
||||
customAttr = JSON.parse(chart.customAttr)
|
||||
// color
|
||||
if (customAttr.color) {
|
||||
const c = JSON.parse(JSON.stringify(customAttr.color))
|
||||
const alpha = digToHex(parseInt(c.alpha))
|
||||
c.colors.forEach(ele => {
|
||||
colors.push(ele.concat(alpha))
|
||||
})
|
||||
}
|
||||
// size
|
||||
if (customAttr.size) {
|
||||
const size = JSON.parse(JSON.stringify(customAttr.size))
|
||||
max = size.liquidMax ? size.liquidMax : DEFAULT_SIZE.liquidMax
|
||||
radius = parseFloat((size.liquidSize ? size.liquidSize : DEFAULT_SIZE.liquidSize) / 100)
|
||||
outlineBorder = parseInt(size.liquidOutlineBorder ? size.liquidOutlineBorder : DEFAULT_SIZE.liquidOutlineBorder)
|
||||
outlineDistance = parseInt((size.liquidOutlineDistance || size.liquidOutlineDistance === 0) ? size.liquidOutlineDistance : DEFAULT_SIZE.liquidOutlineDistance)
|
||||
waveLength = parseInt(size.liquidWaveLength ? size.liquidWaveLength : DEFAULT_SIZE.liquidWaveLength)
|
||||
waveCount = parseInt(size.liquidWaveCount ? size.liquidWaveCount : DEFAULT_SIZE.liquidWaveCount)
|
||||
shape = size.liquidShape ? size.liquidShape : DEFAULT_SIZE.liquidShape
|
||||
}
|
||||
// label
|
||||
if (customAttr.label) {
|
||||
const label = JSON.parse(JSON.stringify(customAttr.label))
|
||||
if (label.show) {
|
||||
labelContent = {
|
||||
style: ({ percent }) => ({
|
||||
fontSize: parseInt(label.fontSize),
|
||||
color: label.color
|
||||
})
|
||||
}
|
||||
} else {
|
||||
labelContent = false
|
||||
}
|
||||
}
|
||||
}
|
||||
let customStyle
|
||||
if (chart.customStyle) {
|
||||
customStyle = JSON.parse(chart.customStyle)
|
||||
if (customStyle.background) {
|
||||
bgColor = customStyle.background.color.concat(digToHex(parseInt(customStyle.background.alpha)))
|
||||
}
|
||||
if (customStyle.text) {
|
||||
const t = JSON.parse(JSON.stringify(customStyle.text))
|
||||
if (t.show) {
|
||||
title = {
|
||||
formatter: () => { return chart.title },
|
||||
style: ({ percent }) => ({
|
||||
fontSize: parseInt(t.fontSize),
|
||||
color: t.color,
|
||||
fontWeight: t.isBolder ? 'bold' : 'normal',
|
||||
fontStyle: t.isItalic ? 'italic' : 'normal'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
title = false
|
||||
}
|
||||
}
|
||||
}
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Liquid(container, {
|
||||
theme: {
|
||||
styleSheet: {
|
||||
brandColor: colors[0],
|
||||
paletteQualitative10: colors,
|
||||
backgroundColor: bgColor
|
||||
}
|
||||
},
|
||||
percent: (parseFloat(value) / parseFloat(max)),
|
||||
radius: radius,
|
||||
shape: shape,
|
||||
outline: {
|
||||
border: outlineBorder,
|
||||
distance: outlineDistance
|
||||
},
|
||||
wave: {
|
||||
length: waveLength,
|
||||
count: waveCount
|
||||
},
|
||||
statistic: {
|
||||
title: title,
|
||||
content: labelContent
|
||||
}
|
||||
})
|
||||
plot.render()
|
||||
return plot
|
||||
}
|
@ -17,3 +17,12 @@ export function hexColorToRGBA(hex, alpha) {
|
||||
return 'rgb(0,0,0)'
|
||||
}
|
||||
}
|
||||
|
||||
export function digToHex(dig) {
|
||||
let prefix = ''
|
||||
const num = parseInt(dig * 2.55)
|
||||
if (num < 16) {
|
||||
prefix = '0'
|
||||
}
|
||||
return prefix.concat(num.toString(16).toUpperCase())
|
||||
}
|
||||
|
162
frontend/src/views/chart/components/ChartComponentG2.vue
Normal file
162
frontend/src/views/chart/components/ChartComponentG2.vue
Normal file
@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div style="display: flex;">
|
||||
<view-track-bar ref="viewTrack" :track-menu="trackMenu" class="track-bar" :style="trackBarStyleTime" @trackClick="trackClick" />
|
||||
<div :id="chartId" style="width: 100%;height: 100%;overflow: hidden;" :style="{ borderRadius: borderRadius}" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { baseLiquid } from '@/views/chart/chart/liquid/liquid'
|
||||
// import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import ViewTrackBar from '@/components/canvas/components/Editor/ViewTrackBar'
|
||||
|
||||
export default {
|
||||
name: 'ChartComponentG2',
|
||||
components: { ViewTrackBar },
|
||||
props: {
|
||||
chart: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
filter: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
trackMenu: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: function() {
|
||||
return ['drill']
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myChart: null,
|
||||
chartId: uuid.v1(),
|
||||
showTrackBar: true,
|
||||
trackBarStyle: {
|
||||
position: 'absolute',
|
||||
left: '0px',
|
||||
top: '0px'
|
||||
},
|
||||
pointParam: null,
|
||||
|
||||
dynamicAreaCode: null,
|
||||
borderRadius: '0px'
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
trackBarStyleTime() {
|
||||
return this.trackBarStyle
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chart: {
|
||||
handler(newVal, oldVla) {
|
||||
this.preDraw()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
resize() {
|
||||
this.drawEcharts()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.preDraw()
|
||||
},
|
||||
methods: {
|
||||
preDraw() {
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
// 渲染echart等待dom加载完毕,渲染之前先尝试销毁具有相同id的echart 放置多次切换仪表板有重复id情况
|
||||
new Promise((resolve) => { resolve() }).then(() => {
|
||||
// 此dom为echarts图标展示dom
|
||||
// this.myChart = this.$echarts.getInstanceByDom(document.getElementById(this.chartId))
|
||||
// if (!this.myChart) {
|
||||
// this.myChart = this.$echarts.init(document.getElementById(this.chartId))
|
||||
// }
|
||||
this.drawEcharts()
|
||||
|
||||
// this.myChart.off('click')
|
||||
// this.myChart.on('click', function(param) {
|
||||
// that.pointParam = param
|
||||
// if (that.trackMenu.length < 2) { // 只有一个事件直接调用
|
||||
// that.trackClick(that.trackMenu[0])
|
||||
// } else { // 视图关联多个事件
|
||||
// that.trackBarStyle.left = param.event.offsetX + 'px'
|
||||
// that.trackBarStyle.top = (param.event.offsetY - 15) + 'px'
|
||||
// that.$refs.viewTrack.trackButtonClick()
|
||||
// }
|
||||
// })
|
||||
})
|
||||
},
|
||||
drawEcharts() {
|
||||
const chart = this.chart
|
||||
// type
|
||||
if (chart.type === 'liquid') {
|
||||
this.myChart = baseLiquid(this.myChart, this.chartId, chart)
|
||||
}
|
||||
|
||||
this.setBackGroundBorder()
|
||||
// console.log(JSON.stringify(chart_option))
|
||||
},
|
||||
|
||||
// myEcharts(option) {
|
||||
// // 指定图表的配置项和数据
|
||||
// const chart = this.myChart
|
||||
// this.setBackGroundBorder()
|
||||
// setTimeout(chart.setOption(option, true), 500)
|
||||
// window.onresize = function() {
|
||||
// chart.resize()
|
||||
// }
|
||||
// },
|
||||
setBackGroundBorder() {
|
||||
if (this.chart.customStyle) {
|
||||
const customStyle = JSON.parse(this.chart.customStyle)
|
||||
if (customStyle.background) {
|
||||
this.borderRadius = (customStyle.background.borderRadius || 0) + 'px'
|
||||
}
|
||||
}
|
||||
},
|
||||
chartResize() {
|
||||
// 指定图表的配置项和数据
|
||||
// const chart = this.myChart
|
||||
// chart.resize()
|
||||
},
|
||||
trackClick(trackAction) {
|
||||
const param = this.pointParam
|
||||
if (!param || !param.data || !param.data.dimensionList) {
|
||||
// 地图提示没有关联字段 其他没有维度信息的 直接返回
|
||||
if (this.chart.type === 'map') {
|
||||
this.$warning(this.$t('panel.no_drill_field'))
|
||||
}
|
||||
return
|
||||
}
|
||||
const linkageParam = {
|
||||
viewId: this.chart.id,
|
||||
dimensionList: this.pointParam.data.dimensionList,
|
||||
quotaList: this.pointParam.data.quotaList
|
||||
}
|
||||
switch (trackAction) {
|
||||
case 'drill':
|
||||
this.$emit('onChartClick', this.pointParam)
|
||||
break
|
||||
case 'linkage':
|
||||
this.$store.commit('addViewTrackFilter', linkageParam)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -24,14 +24,14 @@
|
||||
<el-form-item :label="$t('chart.text_color')" class="form-item">
|
||||
<el-color-picker v-model="titleForm.color" class="color-picker-style" @change="changeTitleStyle" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.text_h_position')" class="form-item">
|
||||
<el-form-item v-show="chart.type && chart.type !== 'liquid'" :label="$t('chart.text_h_position')" class="form-item">
|
||||
<el-radio-group v-model="titleForm.hPosition" size="mini" @change="changeTitleStyle">
|
||||
<el-radio-button label="left">{{ $t('chart.text_pos_left') }}</el-radio-button>
|
||||
<el-radio-button label="center">{{ $t('chart.text_pos_center') }}</el-radio-button>
|
||||
<el-radio-button label="right">{{ $t('chart.text_pos_right') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-show="chart.type && !chart.type.includes('table')" :label="$t('chart.text_v_position')" class="form-item">
|
||||
<el-form-item v-show="chart.type && !chart.type.includes('table') && chart.type !== 'liquid'" :label="$t('chart.text_v_position')" class="form-item">
|
||||
<el-radio-group v-model="titleForm.vPosition" size="mini" @change="changeTitleStyle">
|
||||
<el-radio-button label="top">{{ $t('chart.text_pos_top') }}</el-radio-button>
|
||||
<el-radio-button label="center">{{ $t('chart.text_pos_center') }}</el-radio-button>
|
||||
|
@ -49,7 +49,45 @@
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-show="conf && conf.includes('sort')">
|
||||
|
||||
<el-dropdown-item v-show="item.deType === 1">
|
||||
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="dateStyle">
|
||||
<span class="el-dropdown-link inner-dropdown-menu">
|
||||
<span>
|
||||
<i class="el-icon-c-scale-to-original" />
|
||||
<span>{{ $t('chart.dateStyle') }}</span>
|
||||
<span class="summary-span-item">({{ $t('chart.'+item.dateStyle) }})</span>
|
||||
</span>
|
||||
<i class="el-icon-arrow-right el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="beforeDateStyle('y')">{{ $t('chart.y') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeDateStyle('y_M')">{{ $t('chart.y_M') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeDateStyle('y_M_d')">{{ $t('chart.y_M_d') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeDateStyle('H_m_s')">{{ $t('chart.H_m_s') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeDateStyle('y_M_d_H_m')">{{ $t('chart.y_M_d_H_m') }}</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeDateStyle('y_M_d_H_m_s')">{{ $t('chart.y_M_d_H_m_s') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-show="item.deType === 1">
|
||||
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="datePattern">
|
||||
<span class="el-dropdown-link inner-dropdown-menu">
|
||||
<span>
|
||||
<i class="el-icon-timer" />
|
||||
<span>{{ $t('chart.datePattern') }}</span>
|
||||
<span class="summary-span-item">({{ $t('chart.'+item.datePattern) }})</span>
|
||||
</span>
|
||||
<i class="el-icon-arrow-right el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="beforeDatePattern('date_sub')">{{ $t('chart.date_sub') }}(1990-01-01)</el-dropdown-item>
|
||||
<el-dropdown-item :command="beforeDatePattern('date_split')">{{ $t('chart.date_split') }}(1990/01/01)</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-show="conf && conf.includes('sort')" :divided="item.deType === 1">
|
||||
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="sort">
|
||||
<span class="el-dropdown-link inner-dropdown-menu">
|
||||
<span>
|
||||
@ -143,6 +181,27 @@ export default {
|
||||
removeItem() {
|
||||
this.item.index = this.index
|
||||
this.$emit('onItemRemove', this.item)
|
||||
},
|
||||
|
||||
dateStyle(param) {
|
||||
// console.log(param)
|
||||
this.item.dateStyle = param.type
|
||||
this.$emit('onItemChange', this.item)
|
||||
},
|
||||
beforeDateStyle(type) {
|
||||
return {
|
||||
type: type
|
||||
}
|
||||
},
|
||||
datePattern(param) {
|
||||
// console.log(param)
|
||||
this.item.datePattern = param.type
|
||||
this.$emit('onItemChange', this.item)
|
||||
},
|
||||
beforeDatePattern(type) {
|
||||
return {
|
||||
type: type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,12 @@
|
||||
<el-form-item :label="$t('chart.text_color')" class="form-item">
|
||||
<el-color-picker v-model="labelForm.color" class="color-picker-style" @change="changeLabelAttr" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.label_position')" class="form-item">
|
||||
<el-form-item v-show="chart.type && chart.type !== 'liquid'" :label="$t('chart.label_position')" class="form-item">
|
||||
<el-select v-model="labelForm.position" :placeholder="$t('chart.label_position')" @change="changeLabelAttr">
|
||||
<el-option v-for="option in labelPosition" :key="option.value" :label="option.name" :value="option.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="form-item">
|
||||
<el-form-item v-show="chart.type && chart.type !== 'liquid'" class="form-item">
|
||||
<span slot="label">
|
||||
<span class="span-box">
|
||||
<span>{{ $t('chart.content_formatter') }}</span>
|
||||
@ -126,7 +126,7 @@ export default {
|
||||
},
|
||||
init() {
|
||||
const arr = []
|
||||
for (let i = 10; i <= 20; i = i + 2) {
|
||||
for (let i = 10; i <= 40; i = i + 2) {
|
||||
arr.push({
|
||||
name: i + '',
|
||||
value: i + ''
|
||||
|
@ -165,6 +165,7 @@
|
||||
</el-form>
|
||||
|
||||
<el-form v-show="chart.type && chart.type === 'chart-mix'" ref="sizeFormBar" :disabled="param && !hasDataPermission('manage',param.privileges)" :model="sizeForm" label-width="80px" size="mini">
|
||||
<el-divider content-position="center" class="divider-style">{{ $t('chart.chart_bar') }}</el-divider>
|
||||
<el-form-item :label="$t('chart.adapt')" class="form-item">
|
||||
<el-checkbox v-model="sizeForm.barDefault" @change="changeBarSizeCase">{{ $t('chart.adapt') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
@ -174,7 +175,7 @@
|
||||
<el-form-item :label="$t('chart.bar_gap')" class="form-item form-item-slider">
|
||||
<el-slider v-model="sizeForm.barGap" :disabled="sizeForm.barDefault" show-input :show-input-controls="false" input-size="mini" :min="0" :max="5" :step="0.1" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
<el-divider />
|
||||
<el-divider content-position="center" class="divider-style">{{ $t('chart.chart_line') }}</el-divider>
|
||||
<el-form-item :label="$t('chart.line_width')" class="form-item form-item-slider">
|
||||
<el-slider v-model="sizeForm.lineWidth" show-input :show-input-controls="false" input-size="mini" :min="0" :max="10" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
@ -203,7 +204,7 @@
|
||||
<el-form-item :label="$t('chart.line_area')" class="form-item">
|
||||
<el-checkbox v-model="sizeForm.lineArea" @change="changeBarSizeCase">{{ $t('chart.show') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-divider />
|
||||
<el-divider content-position="center" class="divider-style">{{ $t('chart.chart_scatter') }}</el-divider>
|
||||
<el-form-item :label="$t('chart.bubble_symbol')" class="form-item">
|
||||
<el-select v-model="sizeForm.scatterSymbol" :placeholder="$t('chart.line_symbol')" @change="changeBarSizeCase">
|
||||
<el-option
|
||||
@ -218,6 +219,37 @@
|
||||
<el-slider v-model="sizeForm.scatterSymbolSize" show-input :show-input-controls="false" input-size="mini" :min="1" :max="40" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-form v-show="chart.type && chart.type === 'liquid'" ref="sizeFormLine" :disabled="param && !hasDataPermission('manage',param.privileges)" :model="sizeForm" label-width="80px" size="mini">
|
||||
<el-form-item :label="$t('chart.liquid_shape')" class="form-item">
|
||||
<el-select v-model="sizeForm.liquidShape" :placeholder="$t('chart.liquid_shape')" @change="changeBarSizeCase">
|
||||
<el-option
|
||||
v-for="item in liquidShapeOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.liquid_max')" class="form-item form-item-slider">
|
||||
<el-input-number v-model="sizeForm.liquidMax" :min="1" size="mini" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.radar_size')" class="form-item form-item-slider">
|
||||
<el-slider v-model="sizeForm.liquidSize" show-input :show-input-controls="false" input-size="mini" :min="1" :max="100" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.liquid_outline_border')" class="form-item form-item-slider">
|
||||
<el-slider v-model="sizeForm.liquidOutlineBorder" show-input :show-input-controls="false" input-size="mini" :min="1" :max="20" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.liquid_outline_distance')" class="form-item form-item-slider">
|
||||
<el-slider v-model="sizeForm.liquidOutlineDistance" show-input :show-input-controls="false" input-size="mini" :min="0" :max="20" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.liquid_wave_length')" class="form-item form-item-slider">
|
||||
<el-slider v-model="sizeForm.liquidWaveLength" show-input :show-input-controls="false" input-size="mini" :min="10" :max="500" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('chart.liquid_wave_count')" class="form-item form-item-slider">
|
||||
<el-slider v-model="sizeForm.liquidWaveCount" show-input :show-input-controls="false" input-size="mini" :min="2" :max="10" @change="changeBarSizeCase" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</div>
|
||||
</template>
|
||||
@ -250,6 +282,13 @@ export default {
|
||||
{ name: this.$t('chart.line_symbol_pin'), value: 'pin' },
|
||||
{ name: this.$t('chart.line_symbol_arrow'), value: 'arrow' }
|
||||
],
|
||||
liquidShapeOptions: [
|
||||
{ name: this.$t('chart.liquid_shape_circle'), value: 'circle' },
|
||||
{ name: this.$t('chart.liquid_shape_diamond'), value: 'diamond' },
|
||||
{ name: this.$t('chart.liquid_shape_triangle'), value: 'triangle' },
|
||||
{ name: this.$t('chart.liquid_shape_pin'), value: 'pin' },
|
||||
{ name: this.$t('chart.liquid_shape_rect'), value: 'rect' }
|
||||
],
|
||||
fontSize: []
|
||||
}
|
||||
},
|
||||
@ -279,6 +318,14 @@ export default {
|
||||
this.sizeForm.treemapWidth = this.sizeForm.treemapWidth ? this.sizeForm.treemapWidth : 80
|
||||
this.sizeForm.treemapHeight = this.sizeForm.treemapHeight ? this.sizeForm.treemapHeight : 80
|
||||
this.sizeForm.radarSize = this.sizeForm.radarSize ? this.sizeForm.radarSize : 80
|
||||
|
||||
this.sizeForm.liquidShape = this.sizeForm.liquidShape ? this.sizeForm.liquidShape : DEFAULT_SIZE.liquidShape
|
||||
this.sizeForm.liquidMax = this.sizeForm.liquidMax ? this.sizeForm.liquidMax : DEFAULT_SIZE.liquidMax
|
||||
this.sizeForm.liquidSize = this.sizeForm.liquidSize ? this.sizeForm.liquidSize : DEFAULT_SIZE.liquidSize
|
||||
this.sizeForm.liquidOutlineBorder = this.sizeForm.liquidOutlineBorder ? this.sizeForm.liquidOutlineBorder : DEFAULT_SIZE.liquidOutlineBorder
|
||||
this.sizeForm.liquidOutlineDistance = (this.sizeForm.liquidOutlineDistance || this.sizeForm.liquidOutlineDistance === 0) ? this.sizeForm.liquidOutlineDistance : DEFAULT_SIZE.liquidOutlineDistance
|
||||
this.sizeForm.liquidWaveLength = this.sizeForm.liquidWaveLength ? this.sizeForm.liquidWaveLength : DEFAULT_SIZE.liquidWaveLength
|
||||
this.sizeForm.liquidWaveCount = this.sizeForm.liquidWaveCount ? this.sizeForm.liquidWaveCount : DEFAULT_SIZE.liquidWaveCount
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -326,4 +373,10 @@ export default {
|
||||
.el-divider--horizontal {
|
||||
margin: 10px 0
|
||||
}
|
||||
.divider-style>>>.el-divider__text{
|
||||
color: #606266;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
padding: 0 10px;
|
||||
}
|
||||
</style>
|
||||
|
@ -33,7 +33,7 @@
|
||||
<el-row v-show="chart.type === 'table-info'" class="table-page">
|
||||
<span class="total-style">
|
||||
{{ $t('chart.total') }}
|
||||
<span>{{ chart.data.tableRow.length }}</span>
|
||||
<span>{{ (chart.data && chart.data.tableRow)?chart.data.tableRow.length:0 }}</span>
|
||||
{{ $t('chart.items') }}
|
||||
</span>
|
||||
<el-pagination
|
||||
|
@ -189,18 +189,23 @@
|
||||
<svg-icon icon-class="radar" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="liquid" label="liquid">
|
||||
<span :title="$t('chart.chart_liquid')">
|
||||
<svg-icon icon-class="liquid" 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>
|
||||
</div>
|
||||
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
|
||||
<el-radio value="pie" label="pie">
|
||||
<span :title="$t('chart.chart_pie')">
|
||||
<svg-icon icon-class="pie" 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-radio value="pie-rose" label="pie-rose">
|
||||
<span :title="$t('chart.chart_pie_rose')">
|
||||
<svg-icon icon-class="pie-rose" class="chart-icon" />
|
||||
@ -217,8 +222,14 @@
|
||||
</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>
|
||||
<!-- <div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">-->
|
||||
<!-- <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>-->
|
||||
<!-- <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>-->
|
||||
<!-- <el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>-->
|
||||
<!-- </div>-->
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</el-row>
|
||||
@ -254,7 +265,7 @@
|
||||
/>
|
||||
</span>
|
||||
</el-row>
|
||||
<el-row v-if="view.type !=='text' && view.type !== 'gauge'" class="padding-lr">
|
||||
<el-row v-if="view.type !=='text' && view.type !== 'gauge' && view.type !== 'liquid'" class="padding-lr">
|
||||
<span style="width: 80px;text-align: right;">
|
||||
<span v-if="view.type && view.type.includes('table')">{{ $t('chart.drag_block_table_data_column') }}</span>
|
||||
<span v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('scatter') || view.type === 'chart-mix')">{{ $t('chart.drag_block_type_axis') }}</span>
|
||||
@ -296,6 +307,7 @@
|
||||
<span v-else-if="view.type && view.type === 'map'">{{ $t('chart.chart_data') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('tree')">{{ $t('chart.drag_block_treemap_size') }}</span>
|
||||
<span v-else-if="view.type && view.type === 'chart-mix'">{{ $t('chart.drag_block_value_axis_main') }}</span>
|
||||
<span v-else-if="view.type && view.type === 'liquid'">{{ $t('chart.drag_block_progress') }}</span>
|
||||
/
|
||||
<span>{{ $t('chart.quota') }}</span>
|
||||
</span>
|
||||
@ -418,7 +430,7 @@
|
||||
<span class="drag-placeholder-style-span">{{ $t('chart.placeholder_field') }}</span>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row v-if="view.type && view.type !== 'treemap' && !view.type.includes('table') && !view.type.includes('text') && !view.type.includes('radar') && !view.type.includes('gauge')" class="padding-lr" style="margin-top: 6px;">
|
||||
<el-row v-if="view.type && view.type !== 'treemap' && !view.type.includes('table') && !view.type.includes('text') && !view.type.includes('radar') && !view.type.includes('gauge') && view.type !== 'liquid'" class="padding-lr" style="margin-top: 6px;">
|
||||
<span style="width: 80px;text-align: right;">
|
||||
<span>{{ $t('chart.drill') }}</span>
|
||||
/
|
||||
@ -471,7 +483,7 @@
|
||||
<el-collapse-item v-show="!view.type.includes('table') && !view.type.includes('text')" name="label" :title="$t('chart.label')">
|
||||
<label-selector :param="param" class="attr-selector" :chart="chart" @onLabelChange="onLabelChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-show="!view.type.includes('table') && !view.type.includes('text')" name="tooltip" :title="$t('chart.tooltip')">
|
||||
<el-collapse-item v-show="!view.type.includes('table') && !view.type.includes('text') && view.type !== 'liquid'" name="tooltip" :title="$t('chart.tooltip')">
|
||||
<tooltip-selector :param="param" class="attr-selector" :chart="chart" @onTooltipChange="onTooltipChange" />
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
@ -491,10 +503,10 @@
|
||||
<el-collapse-item v-show="view.type && view.type.includes('radar')" name="split" :title="$t('chart.split')">
|
||||
<split-selector :param="param" class="attr-selector" :chart="chart" @onChangeSplitForm="onChangeSplitForm" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="title" :title="$t('chart.title')">
|
||||
<el-collapse-item v-show="view.type" name="title" :title="$t('chart.title')">
|
||||
<title-selector :param="param" class="attr-selector" :chart="chart" @onTextChange="onTextChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-show="view.type && view.type !== 'map' && !view.type.includes('table') && !view.type.includes('text') && chart.type !== 'treemap'" name="legend" :title="$t('chart.legend')">
|
||||
<el-collapse-item v-show="view.type && view.type !== 'map' && !view.type.includes('table') && !view.type.includes('text') && chart.type !== 'treemap' && view.type !== 'liquid'" name="legend" :title="$t('chart.legend')">
|
||||
<legend-selector :param="param" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="background" :title="$t('chart.background')">
|
||||
@ -510,7 +522,8 @@
|
||||
<el-col style="height: 100%;min-width: 500px;border-top: 1px solid #E6E6E6;">
|
||||
<el-row style="width: 100%;height: 100%;" class="padding-lr">
|
||||
<div ref="imageWrapper" style="height: 100%">
|
||||
<chart-component v-if="httpRequest.status && chart.type && !chart.type.includes('table') && !chart.type.includes('text')" ref="dynamicChart" :chart-id="chart.id" :chart="chart" class="chart-class" @onChartClick="chartClick" />
|
||||
<chart-component v-if="httpRequest.status && chart.type && !chart.type.includes('table') && !chart.type.includes('text') && renderComponent() === 'echarts'" ref="dynamicChart" :chart-id="chart.id" :chart="chart" class="chart-class" @onChartClick="chartClick" />
|
||||
<chart-component-g2 v-if="httpRequest.status && chart.type && !chart.type.includes('table') && !chart.type.includes('text') && renderComponent() === 'g2'" ref="dynamicChart" :chart-id="chart.id" :chart="chart" class="chart-class" />
|
||||
<table-normal v-if="httpRequest.status && chart.type && chart.type.includes('table')" :show-summary="chart.type === 'table-normal'" :chart="chart" class="table-class" />
|
||||
<label-normal v-if="httpRequest.status && chart.type && chart.type.includes('text')" :chart="chart" class="table-class" />
|
||||
<div v-if="!httpRequest.status" class="chart-error-class">
|
||||
@ -670,9 +683,11 @@ import FieldEdit from '../../dataset/data/FieldEdit'
|
||||
import { areaMapping } from '@/api/map/map'
|
||||
import QuotaExtItem from '@/views/chart/components/drag-item/QuotaExtItem'
|
||||
import YAxisExtSelector from '@/views/chart/components/component-style/YAxisExtSelector'
|
||||
import ChartComponentG2 from '@/views/chart/components/ChartComponentG2'
|
||||
export default {
|
||||
name: 'ChartEdit',
|
||||
components: {
|
||||
ChartComponentG2,
|
||||
YAxisExtSelector,
|
||||
QuotaExtItem,
|
||||
FilterItem,
|
||||
@ -934,6 +949,12 @@ export default {
|
||||
})
|
||||
}
|
||||
view.extStack.forEach(function(ele) {
|
||||
if (!ele.dateStyle || ele.dateStyle === '') {
|
||||
ele.dateStyle = 'y_M_d'
|
||||
}
|
||||
if (!ele.datePattern || ele.datePattern === '') {
|
||||
ele.datePattern = 'date_sub'
|
||||
}
|
||||
if (!ele.sort || ele.sort === '') {
|
||||
ele.sort = 'none'
|
||||
}
|
||||
@ -1043,6 +1064,8 @@ export default {
|
||||
}
|
||||
if (!response.data.drill) {
|
||||
this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1)
|
||||
|
||||
this.resetDrill()
|
||||
}
|
||||
this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters ? response.data.drillFilters : []))
|
||||
}).catch(err => {
|
||||
@ -1593,6 +1616,14 @@ export default {
|
||||
if (temp) return temp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
renderComponent() {
|
||||
if (this.chart.type === 'liquid') {
|
||||
return 'g2'
|
||||
} else {
|
||||
return 'echarts'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,11 +15,11 @@
|
||||
{{ $t('login.welcome') + (uiInfo && uiInfo['ui.title'] && uiInfo['ui.title'].paramValue || ' DataEase') }}
|
||||
</div>
|
||||
<div class="login-form">
|
||||
<el-form-item>
|
||||
<el-radio-group v-model="loginForm.loginType">
|
||||
<el-radio v-if="openLdap" :label="0" size="mini">普通登录</el-radio>
|
||||
<el-radio v-if="openLdap" :label="1" size="mini">LDAP</el-radio>
|
||||
|
||||
<el-form-item v-if="loginTypes.length > 1">
|
||||
<el-radio-group v-if="loginTypes.length > 1" v-model="loginForm.loginType" @change="changeLoginType">
|
||||
<el-radio :label="0" size="mini">普通登录</el-radio>
|
||||
<el-radio v-if="loginTypes.includes(1)" :label="1" size="mini">LDAP</el-radio>
|
||||
<el-radio v-if="loginTypes.includes(2)" :label="2" size="mini">OIDC</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
@ -56,41 +56,20 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<plugin-com v-if="loginTypes.includes(2) && loginForm.loginType === 2" ref="SSOComponent" component-name="SSOComponent" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { encrypt } from '@/utils/rsaEncrypt'
|
||||
import { ldapStatus } from '@/api/user'
|
||||
import { ldapStatus, oidcStatus } from '@/api/user'
|
||||
import { getSysUI } from '@/utils/auth'
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
export default {
|
||||
name: 'Login',
|
||||
components: { PluginCom },
|
||||
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'))
|
||||
// // } else {
|
||||
// // callback()
|
||||
// // }
|
||||
// }
|
||||
// const validatePassword = (rule, value, callback) => {
|
||||
// if (value.length < 8) {
|
||||
// callback(this.$t('login.password_error'))
|
||||
// } else {
|
||||
// callback()
|
||||
// }
|
||||
// }
|
||||
return {
|
||||
loginForm: {
|
||||
loginType: 0,
|
||||
@ -108,7 +87,7 @@ export default {
|
||||
loginImageUrl: null,
|
||||
loginLogoUrl: null,
|
||||
axiosFinished: false,
|
||||
openLdap: true
|
||||
loginTypes: [0]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -126,7 +105,15 @@ export default {
|
||||
},
|
||||
beforeCreate() {
|
||||
ldapStatus().then(res => {
|
||||
this.openLdap = res.success && res.data
|
||||
if (res.success && res.data) {
|
||||
this.loginTypes.push(1)
|
||||
}
|
||||
})
|
||||
|
||||
oidcStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
this.loginTypes.push(2)
|
||||
}
|
||||
})
|
||||
},
|
||||
created() {
|
||||
@ -169,6 +156,12 @@ export default {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
changeLoginType(val) {
|
||||
if (val !== 2) return
|
||||
this.$nextTick(() => {
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,6 @@
|
||||
|
||||
<div
|
||||
id="canvasInfo"
|
||||
:class="{'style-hidden':canvasStyleData.selfAdaption}"
|
||||
class="content this_canvas"
|
||||
@drop="handleDrop"
|
||||
@dragover="handleDragOver"
|
||||
@ -839,7 +838,7 @@ export default {
|
||||
}
|
||||
}
|
||||
.style-hidden{
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,6 +1,41 @@
|
||||
<template xmlns:el-col="http://www.w3.org/1999/html">
|
||||
<el-col style="padding: 0 5px 0 5px;">
|
||||
<el-col>
|
||||
<el-row style="margin-bottom: 10px">
|
||||
<el-col :span="16">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
size="mini"
|
||||
:placeholder="$t('commons.search')"
|
||||
prefix-icon="el-icon-search"
|
||||
clearable
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-dropdown>
|
||||
<el-button size="mini" type="primary">
|
||||
{{ searchMap[searchType] }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="searchTypeClick('all')">全部</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="searchTypeClick('folder')">目录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<!-- <el-select-->
|
||||
<!-- v-model="searchType"-->
|
||||
<!-- default-first-option-->
|
||||
<!-- size="mini"-->
|
||||
<!-- >-->
|
||||
<!-- <el-option-->
|
||||
<!-- v-for="item in searchTypeList"-->
|
||||
<!-- :key="item.value"-->
|
||||
<!-- :label="item.label"-->
|
||||
<!-- :value="item.value"-->
|
||||
<!-- />-->
|
||||
<!-- </el-select>-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<span class="header-title">{{ $t('panel.default_panel') }}</span>
|
||||
<div class="block">
|
||||
@ -11,6 +46,7 @@
|
||||
node-key="id"
|
||||
:highlight-current="activeTree==='system'"
|
||||
:expand-on-click-node="true"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<span slot-scope="{ node, data }" class="custom-tree-node father">
|
||||
@ -59,6 +95,7 @@
|
||||
node-key="id"
|
||||
:highlight-current="activeTree==='self'"
|
||||
:expand-on-click-node="true"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<span slot-scope="{ node, data }" class="custom-tree-node-list father">
|
||||
@ -294,7 +331,14 @@ export default {
|
||||
moveDialogTitle: '',
|
||||
moveInfo: {},
|
||||
tGroup: {},
|
||||
tGroupData: [] // 所有目录
|
||||
tGroupData: [], // 所有目录
|
||||
searchPids: [], // 查询命中的pid
|
||||
filterText: '',
|
||||
searchType: 'all',
|
||||
searchMap: {
|
||||
all: this.$t('commons.all'),
|
||||
folder: this.$t('commons.folder')
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -311,6 +355,16 @@ export default {
|
||||
if (newVal === 'PanelMain' && this.lastActiveNode && this.lastActiveNodeData) {
|
||||
this.activeNodeAndClickOnly(this.lastActiveNodeData)
|
||||
}
|
||||
},
|
||||
filterText(val) {
|
||||
this.searchPids = []
|
||||
this.$refs.default_panel_tree.filter(val)
|
||||
this.$refs.panel_list_tree.filter(val)
|
||||
},
|
||||
searchType(val) {
|
||||
this.searchPids = []
|
||||
this.$refs.default_panel_tree.filter(this.filterText)
|
||||
this.$refs.panel_list_tree.filter(this.filterText)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -710,6 +764,27 @@ export default {
|
||||
targetGroup(val) {
|
||||
this.tGroup = val
|
||||
this.groupMoveConfirmDisabled = false
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
if (this.searchType === 'folder') {
|
||||
if (data.nodeType === 'folder' && data.label.indexOf(value) !== -1) {
|
||||
this.searchPids.push(data.id)
|
||||
return true
|
||||
}
|
||||
if (this.searchPids.indexOf(data.pid) !== -1) {
|
||||
if (data.nodeType === 'folder') {
|
||||
this.searchPids.push(data.id)
|
||||
}
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return data.label.indexOf(value) !== -1
|
||||
}
|
||||
return false
|
||||
},
|
||||
searchTypeClick(searchTypeInfo) {
|
||||
this.searchType = searchTypeInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@
|
||||
<el-row class="panel-design-preview">
|
||||
<div id="imageWrapper" ref="imageWrapper" style="width: 100%;height: 100%">
|
||||
<fullscreen style="height: 100%;background: #f7f8fa;overflow-y: auto" :fullscreen.sync="fullscreen">
|
||||
<Preview v-if="showMain" :in-screen="!fullscreen" :show-type="canvasStyleData.selfAdaption?'full':'width'" />
|
||||
<Preview v-if="showMain" :in-screen="!fullscreen" :show-type="'width'" />
|
||||
</fullscreen>
|
||||
</div>
|
||||
</el-row>
|
||||
|
69
frontend/src/views/system/plugin/PluginCom.vue
Normal file
69
frontend/src/views/system/plugin/PluginCom.vue
Normal file
@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div>
|
||||
<async-component v-if="showAsync" :url="url" @execute-axios="executeAxios" @on-add-languanges="addLanguages" @plugin-call-back="pluginCallBack" />
|
||||
<div v-else>
|
||||
<h1>未知组件无法展示</h1>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AsyncComponent from '@/components/AsyncComponent'
|
||||
import i18n from '@/lang'
|
||||
import bus from '@/utils/bus'
|
||||
import { execute } from '@/api/system/dynamic'
|
||||
export default {
|
||||
name: 'PluginCom',
|
||||
components: {
|
||||
AsyncComponent
|
||||
},
|
||||
props: {
|
||||
componentName: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAsync: false,
|
||||
baseUrl: '/api/pluginCommon/component/',
|
||||
url: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.componentName) {
|
||||
this.showAsync = true
|
||||
this.url = this.baseUrl + this.componentName
|
||||
} else {
|
||||
this.showAsync = false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// hasLicense
|
||||
executeAxios(options) {
|
||||
execute(options).then(res => {
|
||||
if (options.callBack) {
|
||||
options.callBack(res)
|
||||
}
|
||||
}).catch(e => {
|
||||
if (options.callBack) {
|
||||
options.callBack(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
addLanguages(options) {
|
||||
for (const key in i18n.messages) {
|
||||
if (Object.hasOwnProperty.call(i18n.messages, key)) {
|
||||
const element = options[key]
|
||||
i18n.mergeLocaleMessage(key, element)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
pluginCallBack(param) {
|
||||
const { eventName, eventParam } = param
|
||||
bus.$emit(eventName, eventParam)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -22,7 +22,7 @@
|
||||
<!-- <el-table-column prop="gender" :label="$t('commons.gender')" width="60" /> -->
|
||||
<el-table-column prop="from" :label="$t('user.source')" width="80">
|
||||
<template slot-scope="scope">
|
||||
<div>{{ scope.row.from === 0 ? 'LOCAL' : 'LDAP' }}</div>
|
||||
<div>{{ scope.row.from === 0 ? 'LOCAL' : scope.row.from === 1 ? 'LDAP' : 'OIDC' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user