forked from github/dataease
Merge branch 'dev' into pr@dev_memory_component
This commit is contained in:
commit
45a5909682
@ -1,10 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<artifactId>dataease-server</artifactId>
|
||||
<groupId>io.dataease</groupId>
|
||||
<version>1.17.0</version>
|
||||
<version>1.18.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -203,7 +204,7 @@
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dataease-plugin-interface</artifactId>
|
||||
<version>1.17.0</version>
|
||||
<version>1.18.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>guava</artifactId>
|
||||
@ -214,12 +215,12 @@
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dataease-plugin-view</artifactId>
|
||||
<version>1.17.0</version>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dataease-plugin-datasource</artifactId>
|
||||
<version>1.17.0</version>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
<!-- kettle及数据源依赖 -->
|
||||
<dependency>
|
||||
@ -502,7 +503,8 @@
|
||||
<exclude name="*.html"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy file="../mobile/dist/index.html" tofile="src/main/resources/templates/app.html"/>
|
||||
<copy file="../mobile/dist/index.html"
|
||||
tofile="src/main/resources/templates/app.html"/>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
@ -538,4 +540,4 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@ -0,0 +1,24 @@
|
||||
package io.dataease.auth.annotation;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DeRateLimiter {
|
||||
|
||||
long DEFAULT_REQUEST = 2;
|
||||
|
||||
@AliasFor("max") long value() default DEFAULT_REQUEST;
|
||||
|
||||
@AliasFor("value") long max() default DEFAULT_REQUEST;
|
||||
|
||||
String key() default "";
|
||||
|
||||
long timeout() default 500;
|
||||
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package io.dataease.auth.aop;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.dataease.auth.annotation.DeRateLimiter;
|
||||
import io.dataease.auth.service.DeLimitService;
|
||||
import io.dataease.commons.utils.IPUtils;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class DeRateLimiterHandler {
|
||||
|
||||
private final static String SEPARATOR = ":";
|
||||
|
||||
|
||||
@Resource
|
||||
private DeLimitService deLimitService;
|
||||
|
||||
|
||||
@Around(value = "@annotation(io.dataease.auth.annotation.DeRateLimiter)")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
DeRateLimiter rateLimiter = AnnotationUtils.findAnnotation(method, DeRateLimiter.class);
|
||||
if (rateLimiter != null) {
|
||||
String key = rateLimiter.key();
|
||||
if (StrUtil.isBlank(key)) {
|
||||
key = method.getDeclaringClass().getName() + StrUtil.DOT + method.getName();
|
||||
}
|
||||
key = key + SEPARATOR + IPUtils.get();
|
||||
|
||||
long max = rateLimiter.max();
|
||||
long timeout = rateLimiter.timeout();
|
||||
TimeUnit timeUnit = rateLimiter.timeUnit();
|
||||
Boolean limited = deLimitService.checkRestricted(key, max, timeout, timeUnit);
|
||||
if (limited) {
|
||||
String msg = "The current API [%s] is limited, please try again later!";
|
||||
String requestURI = ServletUtils.request().getRequestURI();
|
||||
throw new RuntimeException(String.format(msg, requestURI));
|
||||
}
|
||||
}
|
||||
|
||||
return point.proceed();
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package io.dataease.auth.service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public interface DeLimitService {
|
||||
|
||||
Boolean checkRestricted(String key, long max, long timeout, TimeUnit timeUnit);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package io.dataease.auth.service.impl;
|
||||
|
||||
import io.dataease.auth.service.DeLimitService;
|
||||
import io.dataease.commons.condition.RedisStatusCondition;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.script.RedisScript;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Conditional({RedisStatusCondition.class})
|
||||
@Component
|
||||
@Primary
|
||||
public class RedisLimitServiceImpl implements DeLimitService {
|
||||
|
||||
Logger log = LogUtil.getLogger();
|
||||
private final static String REDIS_LIMIT_KEY_PREFIX = "limit:";
|
||||
@Resource
|
||||
private RedisScript<Long> limitRedisScript;
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Override
|
||||
public Boolean checkRestricted(String key, long max, long timeout, TimeUnit timeUnit) {
|
||||
key = REDIS_LIMIT_KEY_PREFIX + key;
|
||||
long ttl = timeUnit.toMillis(timeout);
|
||||
long now = Instant.now().toEpochMilli();
|
||||
long expired = now - ttl;
|
||||
|
||||
Long executeTimes = stringRedisTemplate.execute(limitRedisScript, Collections.singletonList(key), now + "", ttl + "", expired + "", max + "");
|
||||
if (executeTimes != null) {
|
||||
if (executeTimes == 0) {
|
||||
|
||||
log.error("【{}】在单位时间 {} 毫秒内已达到访问上限,当前接口上限 {}", key, ttl, max);
|
||||
return true;
|
||||
} else {
|
||||
log.info("【{}】在单位时间 {} 毫秒内访问 {} 次", key, ttl, executeTimes);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -107,6 +107,7 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
filterChainDefinitionMap.put("/plugin/lark/callBack*", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/lark/bind*", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/lark/getQrParam", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/lark/appId", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/larksuite/callBack*", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/larksuite/bind*", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/larksuite/getQrParam", ANON);
|
||||
|
@ -0,0 +1,26 @@
|
||||
package io.dataease.auth.service.impl;
|
||||
|
||||
|
||||
import com.google.common.util.concurrent.RateLimiter;
|
||||
import io.dataease.auth.service.DeLimitService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
@Service
|
||||
public class StandaloneLimitServiceImpl implements DeLimitService {
|
||||
|
||||
private static ConcurrentHashMap<String, RateLimiter> RATE_LIMITER = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public Boolean checkRestricted(String key, long max, long timeout, TimeUnit timeUnit) {
|
||||
RateLimiter rateLimiter = null;
|
||||
if (!RATE_LIMITER.containsKey(key)) {
|
||||
RATE_LIMITER.put(key, RateLimiter.create(max));
|
||||
}
|
||||
rateLimiter = RATE_LIMITER.get(key);
|
||||
return !rateLimiter.tryAcquire(timeout, timeUnit);
|
||||
}
|
||||
}
|
@ -12,10 +12,13 @@ import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SqlFilter implements Filter {
|
||||
|
||||
private List<String> excludedUris = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
@ -34,38 +37,43 @@ public class SqlFilter implements Filter {
|
||||
return;
|
||||
}
|
||||
|
||||
String method = "GET";
|
||||
String param;
|
||||
XssAndSqlHttpServletRequestWrapper xssRequest = null;
|
||||
if (request instanceof HttpServletRequest) {
|
||||
method = ((HttpServletRequest) request).getMethod();
|
||||
xssRequest = new XssAndSqlHttpServletRequestWrapper((HttpServletRequest) request);
|
||||
}
|
||||
if ("POST".equalsIgnoreCase(method)) {
|
||||
param = this.getBodyString(xssRequest.getReader());
|
||||
if (StringUtils.isNotBlank(param)) {
|
||||
if (xssRequest.checkXSSAndSql(param)) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
String msg = ThreadLocalContextHolder.getData().toString();
|
||||
DEException.throwException(msg);
|
||||
return;
|
||||
if(excludedUris.contains(((HttpServletRequest) request).getRequestURI())){
|
||||
chain.doFilter(request, response);
|
||||
}else {
|
||||
String method = "GET";
|
||||
String param;
|
||||
XssAndSqlHttpServletRequestWrapper xssRequest = null;
|
||||
if (request instanceof HttpServletRequest) {
|
||||
method = ((HttpServletRequest) request).getMethod();
|
||||
xssRequest = new XssAndSqlHttpServletRequestWrapper((HttpServletRequest) request);
|
||||
}
|
||||
if ("POST".equalsIgnoreCase(method)) {
|
||||
param = this.getBodyString(xssRequest.getReader());
|
||||
if (StringUtils.isNotBlank(param)) {
|
||||
if (xssRequest.checkXSSAndSql(param)) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
String msg = ThreadLocalContextHolder.getData().toString();
|
||||
DEException.throwException(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xssRequest.checkParameter()) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
String msg = ThreadLocalContextHolder.getData().toString();
|
||||
DEException.throwException(msg);
|
||||
return;
|
||||
}
|
||||
chain.doFilter(xssRequest, response);
|
||||
}
|
||||
if (xssRequest.checkParameter()) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
String msg = ThreadLocalContextHolder.getData().toString();
|
||||
DEException.throwException(msg);
|
||||
return;
|
||||
}
|
||||
chain.doFilter(xssRequest, response);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
excludedUris.add("/dataset/table/excel/upload");
|
||||
}
|
||||
|
||||
// 获取request请求body中参数
|
||||
|
@ -6,10 +6,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.data.redis.core.script.RedisScript;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.scripting.support.ResourceScriptSource;
|
||||
|
||||
|
||||
@Conditional({RedisStatusCondition.class})
|
||||
@ -36,4 +40,12 @@ public class RedisConfig {
|
||||
return container;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisScript<Long> limitRedisScript() {
|
||||
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
|
||||
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("scripts/limit.lua")));
|
||||
redisScript.setResultType(Long.class);
|
||||
return redisScript;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -149,7 +149,7 @@
|
||||
</select>
|
||||
|
||||
<select id="findByTableIds" resultMap="BaseResultMapDTO">
|
||||
select dataset_table.*
|
||||
select distinct dataset_table.*
|
||||
from dataset_table
|
||||
where dataset_table.id in
|
||||
<foreach collection="tableIds" item="item" open="(" separator="," close=")">
|
||||
|
@ -80,8 +80,7 @@ public class XDingtalkServer {
|
||||
return dingtalkXpackService.getQrParam();
|
||||
}
|
||||
|
||||
@GetMapping("/callBack")
|
||||
public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) {
|
||||
private ModelAndView privateCallBack(String code, Boolean withoutLogin) {
|
||||
ModelAndView modelAndView = new ModelAndView("redirect:/");
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
DingtalkXpackService dingtalkXpackService = null;
|
||||
@ -95,7 +94,7 @@ public class XDingtalkServer {
|
||||
if (!isOpen) {
|
||||
DEException.throwException("未开启钉钉");
|
||||
}
|
||||
DingUserEntity dingUserEntity = dingtalkXpackService.userInfo(code);
|
||||
DingUserEntity dingUserEntity = withoutLogin ? dingtalkXpackService.userInfoWithoutLogin(code) : dingtalkXpackService.userInfo(code);
|
||||
String username = dingUserEntity.getUserid();
|
||||
SysUserEntity sysUserEntity = authUserService.getUserByDingtalkId(username);
|
||||
if (null == sysUserEntity) {
|
||||
@ -139,6 +138,16 @@ public class XDingtalkServer {
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("/callBackWithoutLogin")
|
||||
public ModelAndView callBackWithoutLogin(@RequestParam("code") String code) {
|
||||
return privateCallBack(code, true);
|
||||
}
|
||||
|
||||
@GetMapping("/callBack")
|
||||
public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) {
|
||||
return privateCallBack(code, false);
|
||||
}
|
||||
|
||||
private void bindError(HttpServletResponse response, String url, String errorMsg) {
|
||||
Cookie cookie_error = new Cookie("DingtalkError", errorMsg);
|
||||
cookie_error.setPath("/");
|
||||
|
@ -1,8 +1,10 @@
|
||||
package io.dataease.plugins.server;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.dataease.auth.annotation.DeRateLimiter;
|
||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.model.excel.ExcelSheetModel;
|
||||
@ -27,6 +29,9 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
@ -150,7 +155,45 @@ public class XEmailTaskServer {
|
||||
return xpackEmailCreate;
|
||||
}
|
||||
|
||||
@PostMapping("/preview")
|
||||
@DeRateLimiter
|
||||
@PostMapping(value = "/screenshot", produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
|
||||
public ResponseEntity<ByteArrayResource> screenshot(@RequestBody XpackEmailViewRequest request) {
|
||||
EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class);
|
||||
String url = ServletUtils.domain() + "/#/previewScreenShot/" + request.getPanelId() + "/true";
|
||||
byte[] bytes = null;
|
||||
try {
|
||||
String currentToken = ServletUtils.getToken();
|
||||
Future<?> future = priorityExecutor.submit(() -> {
|
||||
try {
|
||||
return emailXpackService.print(url, currentToken, buildPixel(request.getPixel()));
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
DEException.throwException("预览失败,请联系管理员");
|
||||
}
|
||||
return null;
|
||||
}, 0);
|
||||
Object object = future.get();
|
||||
if (ObjectUtils.isNotEmpty(object)) {
|
||||
bytes = (byte[]) object;
|
||||
if (ArrayUtil.isNotEmpty(bytes)) {
|
||||
String fileName = request.getPanelId() + ".jpeg";
|
||||
ByteArrayResource bar = new ByteArrayResource(bytes);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
ContentDisposition contentDisposition = ContentDisposition.parse("attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
||||
headers.setContentDisposition(contentDisposition);
|
||||
return new ResponseEntity(bar, headers, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
DEException.throwException("预览失败,请联系管理员");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/preview")
|
||||
public String preview(@RequestBody XpackEmailViewRequest request) {
|
||||
EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class);
|
||||
String panelId = request.getPanelId();
|
||||
@ -159,7 +202,6 @@ public class XEmailTaskServer {
|
||||
String url = ServletUtils.domain() + "/#/previewScreenShot/" + panelId + "/true";
|
||||
|
||||
String token = ServletUtils.getToken();
|
||||
String fileId = null;
|
||||
try {
|
||||
Future<?> future = priorityExecutor.submit(() -> {
|
||||
try {
|
||||
@ -172,19 +214,21 @@ public class XEmailTaskServer {
|
||||
}, 0);
|
||||
Object object = future.get();
|
||||
if (ObjectUtils.isNotEmpty(object)) {
|
||||
fileId = object.toString();
|
||||
byte[] bytes = (byte[]) object;
|
||||
String baseCode = Base64Utils.encodeToString(bytes);
|
||||
String imageUrl = "data:image/jpeg;base64," + baseCode;
|
||||
String html = "<div>" +
|
||||
content +
|
||||
"<img style='width: 100%;' id='" + panelId + "' src='" + imageUrl + "' />" +
|
||||
"</div>";
|
||||
|
||||
return html;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
DEException.throwException("预览失败,请联系管理员");
|
||||
}
|
||||
String imageUrl = "/system/ui/image/" + fileId;
|
||||
String html = "<div>" +
|
||||
content +
|
||||
"<img style='width: 100%;' id='" + panelId + "' src='" + imageUrl + "' />" +
|
||||
"</div>";
|
||||
|
||||
return html;
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import io.dataease.auth.service.AuthUserService;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.commons.constants.SysLogConstants;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.utils.BeanUtils;
|
||||
import io.dataease.commons.utils.DeLogUtils;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
@ -15,8 +16,10 @@ import io.dataease.plugins.common.base.domain.SysUserAssist;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
|
||||
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
|
||||
import io.dataease.plugins.xpack.lark.dto.entity.LarkAppUserEntity;
|
||||
import io.dataease.plugins.xpack.lark.dto.entity.LarkQrResult;
|
||||
import io.dataease.plugins.xpack.lark.dto.entity.LarkUserInfo;
|
||||
import io.dataease.plugins.xpack.lark.dto.response.LarkAppUserResult;
|
||||
import io.dataease.plugins.xpack.lark.dto.response.LarkInfo;
|
||||
import io.dataease.plugins.xpack.lark.service.LarkXpackService;
|
||||
import io.dataease.service.sys.SysUserService;
|
||||
@ -48,6 +51,13 @@ public class XLarkServer {
|
||||
@Resource
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/appId")
|
||||
public String getAppId() {
|
||||
LarkXpackService larkXpackService = SpringContextUtil.getBean(LarkXpackService.class);
|
||||
return larkXpackService.appId();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/info")
|
||||
public LarkInfo getLarkInfo() {
|
||||
@ -81,8 +91,12 @@ public class XLarkServer {
|
||||
return larkXpackService.getQrParam();
|
||||
}
|
||||
|
||||
@GetMapping("/callBack")
|
||||
public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) {
|
||||
@GetMapping("/callBackWithoutLogin")
|
||||
public ModelAndView callBackWithoutLogin(@RequestParam("code") String code) {
|
||||
return privateCallBack(code, null, true);
|
||||
}
|
||||
|
||||
private ModelAndView privateCallBack(String code, String state, Boolean withoutLogin) {
|
||||
ModelAndView modelAndView = new ModelAndView("redirect:/");
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
LarkXpackService larkXpackService = null;
|
||||
@ -96,7 +110,14 @@ public class XLarkServer {
|
||||
if (!isOpen) {
|
||||
DEException.throwException("未开启飞书");
|
||||
}
|
||||
LarkUserInfo larkUserInfo = larkXpackService.userInfo(code, state, false);
|
||||
LarkUserInfo larkUserInfo = null;
|
||||
if (withoutLogin) {
|
||||
LarkAppUserResult larkAppUserResult = larkXpackService.userInfoWithoutLogin(code);
|
||||
LarkAppUserEntity userResultData = larkAppUserResult.getData();
|
||||
larkUserInfo = BeanUtils.copyBean(new LarkUserInfo(), userResultData);
|
||||
} else {
|
||||
larkUserInfo = larkXpackService.userInfo(code, state, false);
|
||||
}
|
||||
String username = larkUserInfo.getUser_id();
|
||||
SysUserEntity sysUserEntity = authUserService.getUserByLarkId(username);
|
||||
if (null == sysUserEntity) {
|
||||
@ -140,6 +161,11 @@ public class XLarkServer {
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("/callBack")
|
||||
public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) {
|
||||
return privateCallBack(code, state, false);
|
||||
}
|
||||
|
||||
private void bindError(HttpServletResponse response, String url, String errorMsg) {
|
||||
Cookie cookie_error = new Cookie("LarkError", errorMsg);
|
||||
cookie_error.setPath("/");
|
||||
|
@ -390,7 +390,11 @@ public class DorisQueryProvider extends QueryProvider {
|
||||
originField = String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
} else {
|
||||
if (x.getDeType() == 2 || x.getDeType() == 3) {
|
||||
originField = String.format(DorisConstants.CAST, String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getDataeaseName()), DorisConstants.DEFAULT_FLOAT_FORMAT);
|
||||
if (x.getDeExtractType() == 1) {
|
||||
originField = String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
} else {
|
||||
originField = String.format(DorisConstants.CAST, String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getDataeaseName()), DorisConstants.DEFAULT_FLOAT_FORMAT);
|
||||
}
|
||||
} else {
|
||||
originField = String.format(DorisConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
}
|
||||
|
@ -1338,8 +1338,9 @@ public class SqlserverQueryProvider extends QueryProvider {
|
||||
public List<Dateformat> dateformat() {
|
||||
return JSONArray.parseArray("[\n" +
|
||||
"{\"dateformat\": \"102\", \"desc\": \"yyyy.mm.dd\"},\n" +
|
||||
"{\"dateformat\": \"23\", \"desc\": \"yyyy-mm-dd\"},\n" +
|
||||
"{\"dateformat\": \"120\", \"desc\": \"yyyy-mm-dd\"},\n" +
|
||||
"{\"dateformat\": \"111\", \"desc\": \"yyyy/mm/dd\"},\n" +
|
||||
"{\"dateformat\": \"112\", \"desc\": \"yyyymmdd\"},\n" +
|
||||
"{\"dateformat\": \"120\", \"desc\": \"yyyy-mm-dd hh:mi:ss\"}\n" +
|
||||
"]", Dateformat.class);
|
||||
}
|
||||
|
@ -982,7 +982,8 @@ public class ChartViewService {
|
||||
}
|
||||
if (StringUtils.isNotEmpty(totalPageSql) && StringUtils.equalsIgnoreCase((String) mapSize.get("tablePageMode"), "page")) {
|
||||
datasourceRequest.setQuery(totalPageSql);
|
||||
totalItems = Long.valueOf(datasourceProvider.getData(datasourceRequest).get(0)[0]);
|
||||
java.util.List<java.lang.String[]> tmpData = datasourceProvider.getData(datasourceRequest);
|
||||
totalItems = CollectionUtils.isEmpty(tmpData) ? 0 : Long.valueOf(tmpData.get(0)[0]);
|
||||
totalPage = (totalItems / pageInfo.getPageSize()) + (totalItems % pageInfo.getPageSize() > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,16 @@ package io.dataease.service.dataset;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.dataease.ext.ExtChartViewMapper;
|
||||
import io.dataease.commons.constants.*;
|
||||
import io.dataease.commons.model.AuthURD;
|
||||
import io.dataease.commons.utils.*;
|
||||
import io.dataease.controller.request.datasource.ApiDefinition;
|
||||
import io.dataease.dto.dataset.DataTableInfoDTO;
|
||||
import io.dataease.dto.dataset.ExcelSheetData;
|
||||
import io.dataease.dto.datasource.*;
|
||||
import io.dataease.exception.DataEaseException;
|
||||
import io.dataease.ext.ExtChartViewMapper;
|
||||
import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.plugins.common.base.domain.*;
|
||||
import io.dataease.plugins.common.constants.DatasetType;
|
||||
import io.dataease.plugins.common.constants.DatasourceTypes;
|
||||
@ -17,14 +22,9 @@ import io.dataease.plugins.datasource.entity.JdbcConfiguration;
|
||||
import io.dataease.plugins.datasource.provider.Provider;
|
||||
import io.dataease.plugins.datasource.query.QueryProvider;
|
||||
import io.dataease.provider.DDLProvider;
|
||||
import io.dataease.provider.datasource.JdbcProvider;
|
||||
import io.dataease.provider.ProviderFactory;
|
||||
import io.dataease.dto.datasource.*;
|
||||
import io.dataease.provider.datasource.JdbcProvider;
|
||||
import io.dataease.service.datasource.DatasourceService;
|
||||
import io.dataease.dto.dataset.DataTableInfoDTO;
|
||||
import io.dataease.dto.dataset.ExcelSheetData;
|
||||
import io.dataease.exception.DataEaseException;
|
||||
import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.service.engine.EngineService;
|
||||
import io.dataease.service.kettle.KettleService;
|
||||
import io.dataease.service.message.DeMsgutil;
|
||||
@ -413,7 +413,7 @@ public class ExtractDataService {
|
||||
|
||||
}
|
||||
|
||||
private List<DatasetTableField> getDatasetTableFields(String datasetTableId) {
|
||||
public List<DatasetTableField> getDatasetTableFields(String datasetTableId) {
|
||||
List<DatasetTableField> datasetTableFields = dataSetTableFieldsService.list(DatasetTableField.builder().tableId(datasetTableId).build());
|
||||
datasetTableFields = datasetTableFields.stream().filter(datasetTableField -> datasetTableField.getExtField() == 0).collect(Collectors.toList());
|
||||
datasetTableFields.sort((o1, o2) -> {
|
||||
@ -617,7 +617,7 @@ public class ExtractDataService {
|
||||
dataSetTableTaskLogService.save(datasetTableTaskLog, hasTask);
|
||||
}
|
||||
|
||||
private void createEngineTable(String tableName, List<DatasetTableField> datasetTableFields) throws Exception {
|
||||
public void createEngineTable(String tableName, List<DatasetTableField> datasetTableFields) throws Exception {
|
||||
Datasource engine = engineService.getDeEngine();
|
||||
JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
@ -793,7 +793,7 @@ public class ExtractDataService {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
if (jobStatus.getStatusDescription().equals("Finished")) {
|
||||
LogUtil.info(datasetTable.getId()+ ": " + jobStatus.getLoggingString());
|
||||
LogUtil.info(datasetTable.getId() + ": " + jobStatus.getLoggingString());
|
||||
return;
|
||||
} else {
|
||||
DataEaseException.throwException(jobStatus.getLoggingString());
|
||||
@ -1029,7 +1029,7 @@ public class ExtractDataService {
|
||||
if (extractType.equalsIgnoreCase("all_scope") && datasetTable.getType().equalsIgnoreCase(DatasetType.SQL.name())) {
|
||||
DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class);
|
||||
selectSQL = dataTableInfoDTO.getSql();
|
||||
if(dataTableInfoDTO.isBase64Encryption()){
|
||||
if (dataTableInfoDTO.isBase64Encryption()) {
|
||||
selectSQL = new String(java.util.Base64.getDecoder().decode(selectSQL));
|
||||
}
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(datasource.getType());
|
||||
@ -1056,13 +1056,13 @@ public class ExtractDataService {
|
||||
}
|
||||
|
||||
private List<StepMeta> excelInputStep(String Info, List<DatasetTableField> datasetTableFields) {
|
||||
List<StepMeta>inputSteps = new ArrayList<>();
|
||||
List<StepMeta> inputSteps = new ArrayList<>();
|
||||
DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(Info, DataTableInfoDTO.class);
|
||||
List<ExcelSheetData> excelSheetDataList = dataTableInfoDTO.getExcelSheetDataList();
|
||||
|
||||
List<String> sheetNames = new ArrayList<>();
|
||||
|
||||
int size =1;
|
||||
int size = 1;
|
||||
for (ExcelSheetData excelSheetData : excelSheetDataList) {
|
||||
StepMeta fromStep = null;
|
||||
String suffix = excelSheetData.getPath().substring(excelSheetDataList.get(0).getPath().lastIndexOf(".") + 1);
|
||||
@ -1090,7 +1090,7 @@ public class ExtractDataService {
|
||||
fromStep.setDraw(true);
|
||||
fromStep.setLocation(100, 100 * size);
|
||||
inputSteps.add(fromStep);
|
||||
}else {
|
||||
} else {
|
||||
List<String> files = new ArrayList<>();
|
||||
files.add(excelSheetData.getPath());
|
||||
|
||||
@ -1240,7 +1240,7 @@ public class ExtractDataService {
|
||||
if (StringUtils.isNotEmpty(charset)) {
|
||||
String varcharFields = datasetTableFields.stream().filter(datasetTableField -> datasetTableField.getDeExtractType() == 0).map(DatasetTableField::getOriginName).collect(Collectors.joining(","));
|
||||
tmp_code = tmp_code.replace("handleCharset", handleCharset.replace("Datasource_Charset", charset).replace("Target_Charset", targetCharset).replace("varcharFields", varcharFields));
|
||||
}else {
|
||||
} else {
|
||||
tmp_code = tmp_code.replace("handleCharset", "");
|
||||
}
|
||||
} else {
|
||||
|
@ -20,6 +20,7 @@ import io.dataease.service.chart.ChartViewService;
|
||||
import io.dataease.service.dataset.DataSetGroupService;
|
||||
import io.dataease.service.dataset.DataSetTableFieldsService;
|
||||
import io.dataease.service.dataset.DataSetTableService;
|
||||
import io.dataease.service.dataset.ExtractDataService;
|
||||
import io.dataease.service.datasource.DatasourceService;
|
||||
import io.dataease.service.staticResource.StaticResourceService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -68,6 +69,8 @@ public class PanelAppTemplateService {
|
||||
private DataSetGroupService dataSetGroupService;
|
||||
@Resource
|
||||
private StaticResourceService staticResourceService;
|
||||
@Resource
|
||||
private ExtractDataService extractDataService;
|
||||
|
||||
public List<PanelAppTemplateWithBLOBs> list(PanelAppTemplateRequest request) {
|
||||
return extPanelAppTemplateMapper.queryBaseInfo(request.getNodeType(), request.getPid());
|
||||
@ -209,6 +212,7 @@ public class PanelAppTemplateService {
|
||||
DatasetTableField newTableField = dataSetTableFieldsService.save(datasetTableField);
|
||||
datasetFieldsRealMap.put(oldId, newTableField.getId());
|
||||
datasetFieldsMd5FormatRealMap.put(TableUtils.fieldNameShort(oldTableId + "_" + datasetTableField.getOriginName()), TableUtils.fieldNameShort(newTableField.getTableId() + "_" + datasetTableField.getOriginName()));
|
||||
datasetFieldsMd5FormatRealMap.put(TableUtils.fieldName(oldTableId + "_" + datasetTableField.getDataeaseName()), TableUtils.fieldName(newTableField.getTableId() + "_" + datasetTableField.getDataeaseName()));
|
||||
}
|
||||
}
|
||||
//数据集计算字段替换
|
||||
@ -225,6 +229,8 @@ public class PanelAppTemplateService {
|
||||
DatasetTableField newTableField = dataSetTableFieldsService.save(datasetTableField);
|
||||
datasetFieldsRealMap.put(oldId, newTableField.getId());
|
||||
datasetFieldsMd5FormatRealMap.put(TableUtils.fieldNameShort(oldTableId + "_" + oldOriginName), TableUtils.fieldNameShort(newTableField.getTableId() + "_" + datasetTableField.getOriginName()));
|
||||
datasetFieldsMd5FormatRealMap.put(TableUtils.fieldName(oldTableId + "_" + datasetTableField.getDataeaseName()), TableUtils.fieldName(newTableField.getTableId() + "_" + datasetTableField.getDataeaseName()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,13 +239,28 @@ public class PanelAppTemplateService {
|
||||
if (DatasetType.UNION.name().equalsIgnoreCase(datasetTypeRealMap.get(datasetTableField.getTableId())) || DatasetType.CUSTOM.name().equalsIgnoreCase(datasetTypeRealMap.get(datasetTableField.getTableId()))) {
|
||||
DatasetTableField updateField = new DatasetTableField();
|
||||
updateField.setId(datasetTableField.getId());
|
||||
updateField.setOriginName(datasetFieldsMd5FormatRealMap.get(datasetTableField.getOriginName()));
|
||||
dataSetTableFieldsService.updateByPrimaryKeySelective(updateField);
|
||||
String newOriginName = datasetFieldsMd5FormatRealMap.get(datasetTableField.getOriginName());
|
||||
String dataeaseName = datasetFieldsMd5FormatRealMap.get(datasetTableField.getDataeaseName());
|
||||
if (StringUtils.isNotEmpty(newOriginName) || StringUtils.isNotEmpty(dataeaseName)) {
|
||||
updateField.setOriginName(datasetFieldsMd5FormatRealMap.get(datasetTableField.getOriginName()));
|
||||
updateField.setDataeaseName(datasetFieldsMd5FormatRealMap.get(datasetTableField.getDataeaseName()));
|
||||
dataSetTableFieldsService.updateByPrimaryKeySelective(updateField);
|
||||
}
|
||||
}
|
||||
}
|
||||
return datasetFieldsRealMap;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createDorisTable(List<DatasetTable> datasetTablesInfo) throws Exception {
|
||||
for (DatasetTable datasetTable : datasetTablesInfo) {
|
||||
if (1 == datasetTable.getMode() && !(DatasetType.CUSTOM.name().equalsIgnoreCase(datasetTable.getType()) || DatasetType.UNION.name().equalsIgnoreCase(datasetTable.getType()))) {
|
||||
List<DatasetTableField> fields = extractDataService.getDatasetTableFields(datasetTable.getId());
|
||||
extractDataService.createEngineTable(TableUtils.tableName(datasetTable.getId()), fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void resetCustomAndUnionDataset(List<DatasetTable> datasetTablesInfo, Map<String, String> datasetRealMap, Map<String, String> datasetFieldsRealMap) throws Exception {
|
||||
for (DatasetTable datasetTable : datasetTablesInfo) {
|
||||
|
@ -30,7 +30,6 @@ import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.plugins.common.base.domain.*;
|
||||
import io.dataease.plugins.common.base.mapper.*;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.service.SystemInfoService;
|
||||
import io.dataease.service.chart.ChartViewService;
|
||||
import io.dataease.service.dataset.DataSetGroupService;
|
||||
import io.dataease.service.dataset.DataSetTableService;
|
||||
@ -135,8 +134,6 @@ public class PanelGroupService {
|
||||
private DatasetGroupMapper datasetGroupMapper;
|
||||
@Resource
|
||||
private PanelWatermarkMapper panelWatermarkMapper;
|
||||
@Resource
|
||||
private SystemInfoService systemInfoService;
|
||||
|
||||
public List<PanelGroupDTO> tree(PanelGroupRequest panelGroupRequest) {
|
||||
String userId = String.valueOf(AuthUtils.getUser().getUserId());
|
||||
@ -811,29 +808,6 @@ public class PanelGroupService {
|
||||
List<ChartViewField> chartViewFieldsInfo = extChartViewFieldMapper.findByPanelId(panelId);
|
||||
//3.获取所有数据集信息
|
||||
List<DatasetTable> datasetTablesInfo = extDataSetTableMapper.findByPanelId(panelId);
|
||||
List<String> attachTableIds = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(datasetTablesInfo)) {
|
||||
for (DatasetTable datasetTable : datasetTablesInfo) {
|
||||
if ("union".equals(datasetTable.getType()) && StringUtils.isNotEmpty(datasetTable.getInfo())) {
|
||||
DataTableInfoDTO dt = gson.fromJson(datasetTable.getInfo(), DataTableInfoDTO.class);
|
||||
DatasetUtils.getUnionTable(attachTableIds, dt.getUnion());
|
||||
} else if ("custom".equals(datasetTable.getType()) && StringUtils.isNotEmpty(datasetTable.getInfo())) {
|
||||
Map result = gson.fromJson(datasetTable.getInfo(), Map.class);
|
||||
List<Map> list = (List<Map>) result.get("list");
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
for (Map details : list) {
|
||||
attachTableIds.add(String.valueOf(details.get("tableId")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(attachTableIds)) {
|
||||
List<DatasetTable> attachDatasetTables = extDataSetTableMapper.findByTableIds(attachTableIds);
|
||||
if (CollectionUtils.isNotEmpty(attachDatasetTables)) {
|
||||
datasetTablesInfo.addAll(attachDatasetTables);
|
||||
}
|
||||
}
|
||||
}
|
||||
// dataset check
|
||||
if (CollectionUtils.isEmpty(datasetTablesInfo)) {
|
||||
return new PanelExport2App(Translator.get("I18N_APP_NO_DATASET_ERROR"));
|
||||
@ -841,6 +815,23 @@ public class PanelGroupService {
|
||||
return new PanelExport2App(Translator.get("I18N_APP_ERROR_DATASET"));
|
||||
}
|
||||
List<String> allTableIds = datasetTablesInfo.stream().map(DatasetTable::getId).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(datasetTablesInfo)) {
|
||||
for (DatasetTable datasetTable : datasetTablesInfo) {
|
||||
if ("union".equals(datasetTable.getType()) && StringUtils.isNotEmpty(datasetTable.getInfo())) {
|
||||
DataTableInfoDTO dt = gson.fromJson(datasetTable.getInfo(), DataTableInfoDTO.class);
|
||||
DatasetUtils.getUnionTable(allTableIds, dt.getUnion());
|
||||
} else if ("custom".equals(datasetTable.getType()) && StringUtils.isNotEmpty(datasetTable.getInfo())) {
|
||||
Map result = gson.fromJson(datasetTable.getInfo(), Map.class);
|
||||
List<Map> list = (List<Map>) result.get("list");
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
for (Map details : list) {
|
||||
allTableIds.add(String.valueOf(details.get("tableId")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
datasetTablesInfo = extDataSetTableMapper.findByTableIds(allTableIds);
|
||||
//4.获取所有数据集字段信息
|
||||
List<DatasetTableField> datasetTableFieldsInfo = extDataSetTableFieldMapper.findByTableIds(allTableIds);
|
||||
//5.获取所有任务信息
|
||||
@ -917,6 +908,8 @@ public class PanelGroupService {
|
||||
|
||||
Map<String, String> datasetFieldsRealMap = panelAppTemplateService.applyDatasetField(datasetTableFieldsInfo, datasetsRealMap, datasetTypeRealMap, datasetFieldsMd5FormatRealMap);
|
||||
|
||||
panelAppTemplateService.createDorisTable(datasetTablesInfo);
|
||||
|
||||
panelAppTemplateService.resetCustomAndUnionDataset(datasetTablesInfo, datasetsRealMap, datasetFieldsRealMap);
|
||||
|
||||
Map<String, String> chartViewsRealMap = panelAppTemplateService.applyViews(chartViewsInfo, datasetsRealMap, datasetFieldsRealMap, datasetFieldsMd5FormatRealMap, newPanelId);
|
||||
|
File diff suppressed because one or more lines are too long
@ -247,3 +247,16 @@ I18N_LOG_FORMAT_POSITION=IN\u3010%s\u3011
|
||||
I18N_LOG_FORMAT=TO %s\u3010%s\u3011
|
||||
I18N_LOG_FORMAT_PREFIX=With authority of %s\u3010%s\u3011
|
||||
|
||||
\u4E0A\u4F20\u63D2\u4EF6=Upload
|
||||
\u5378\u8F7D\u63D2\u4EF6=Uninstall
|
||||
\u67E5\u770B\u7CFB\u7EDF\u6A21\u677F=System templates
|
||||
\u7F16\u8F91\u62A5\u544A=Edit report
|
||||
\u521B\u5EFA\u62A5\u544A=Create report
|
||||
\u5220\u9664\u62A5\u544A=Delete report
|
||||
\u5BFC\u51FA\u65E5\u5FD7=Export log
|
||||
\u5BFC\u5165\u7528\u6237=Import user
|
||||
\u6570\u636E\u96C6\u8868\u5355=Dataset form
|
||||
\u7F16\u8F91\u8BB0\u5F55=Edit record
|
||||
\u5220\u9664\u8BB0\u5F55=Delete record
|
||||
\u6C34\u5370\u7BA1\u7406=Watermark
|
||||
|
||||
|
@ -247,3 +247,17 @@ I18N_LOG_FORMAT_POSITION=\u5728\u3010%s\u3011
|
||||
I18N_LOG_FORMAT=\u7ED9%s\u3010%s\u3011
|
||||
I18N_LOG_FORMAT_PREFIX=\u4EE5%s\u3010%s\u3011\u6743\u9650
|
||||
|
||||
\u4E0A\u4F20\u63D2\u4EF6=\u4E0A\u4F20\u63D2\u4EF6
|
||||
\u5378\u8F7D\u63D2\u4EF6=\u5378\u8F7D\u63D2\u4EF6
|
||||
\u67E5\u770B\u7CFB\u7EDF\u6A21\u677F=\u7CFB\u7EDF\u6A21\u7248
|
||||
\u7F16\u8F91\u62A5\u544A=\u7F16\u8F91\u62A5\u544A
|
||||
\u521B\u5EFA\u62A5\u544A=\u521B\u5EFA\u62A5\u544A
|
||||
\u5220\u9664\u62A5\u544A=\u5220\u9664\u62A5\u544A
|
||||
\u5BFC\u51FA\u65E5\u5FD7=\u5BFC\u51FA\u65E5\u5FD7
|
||||
\u5BFC\u5165\u7528\u6237=\u5BFC\u5165\u7528\u6237
|
||||
\u6570\u636E\u96C6\u8868\u5355=\u6570\u636E\u96C6\u8868\u5355
|
||||
\u7F16\u8F91\u8BB0\u5F55=\u7F16\u8F91\u8BB0\u5F55
|
||||
\u5220\u9664\u8BB0\u5F55=\u5220\u9664\u8BB0\u5F55
|
||||
\u6C34\u5370\u7BA1\u7406=\u6C34\u5370\u7BA1\u7406
|
||||
|
||||
|
||||
|
@ -242,3 +242,16 @@ I18N_PROHIBIT_SCANNING_TO_CREATE_USER=\u7981\u6B62\u6383\u78BC\u5275\u5EFA\u7528
|
||||
I18N_LOG_FORMAT_POSITION=\u5728\u3010%s\u3011
|
||||
I18N_LOG_FORMAT=\u7D66%s\u3010%s\u3011
|
||||
I18N_LOG_FORMAT_PREFIX=\u4EE5%s\u3010%s\u3011\u6B0A\u9650
|
||||
|
||||
\u4E0A\u4F20\u63D2\u4EF6=\u4E0A\u50B3\u63D2\u4EF6
|
||||
\u5378\u8F7D\u63D2\u4EF6=\u5378\u8F09\u63D2\u4EF6
|
||||
\u67E5\u770B\u7CFB\u7EDF\u6A21\u677F=\u7CFB\u7D71\u6A21\u7248
|
||||
\u7F16\u8F91\u62A5\u544A=\u7DE8\u8F2F\u5831\u544A
|
||||
\u521B\u5EFA\u62A5\u544A=\u5275\u5EFA\u5831\u544A
|
||||
\u5220\u9664\u62A5\u544A=\u522A\u9664\u5831\u544A
|
||||
\u5BFC\u51FA\u65E5\u5FD7=\u5C0E\u51FA\u65E5\u8A8C
|
||||
\u5BFC\u5165\u7528\u6237=\u5C0E\u5165\u7528\u6236
|
||||
\u6570\u636E\u96C6\u8868\u5355=\u6578\u64DA\u96C6\u8868\u55AE
|
||||
\u7F16\u8F91\u8BB0\u5F55=\u7DE8\u8F2F\u8A18\u9304
|
||||
\u5220\u9664\u8BB0\u5F55=\u522A\u9664\u8A18\u9304
|
||||
\u6C34\u5370\u7BA1\u7406=\u6C34\u5370\u7BA1\u7406
|
||||
|
27
backend/src/main/resources/scripts/limit.lua
Normal file
27
backend/src/main/resources/scripts/limit.lua
Normal file
@ -0,0 +1,27 @@
|
||||
-- 下标从 1 开始 获取key
|
||||
local key = KEYS[1]
|
||||
-- 下标从 1 开始 获取参数
|
||||
local now = tonumber(ARGV[1]) -- 当前时间错
|
||||
local ttl = tonumber(ARGV[2]) -- 有效
|
||||
local expired = tonumber(ARGV[3]) --
|
||||
local max = tonumber(ARGV[4])
|
||||
|
||||
-- 清除过期的数据
|
||||
-- 移除指定分数区间内的所有元素,expired 即已经过期的 score
|
||||
-- 根据当前时间毫秒数 - 超时毫秒数,得到过期时间 expired
|
||||
redis.call('zremrangebyscore', key, 0, expired)
|
||||
|
||||
-- 获取 zset 中的当前元素个数
|
||||
local current = tonumber(redis.call('zcard', key))
|
||||
local next = current + 1
|
||||
|
||||
if next > max then
|
||||
-- 达到限流大小 返回 0
|
||||
return 0;
|
||||
else
|
||||
-- 往 zset 中添加一个值、得分均为当前时间戳的元素,[value,score]
|
||||
redis.call("zadd", key, now, now)
|
||||
-- 每次访问均重新设置 zset 的过期时间,单位毫秒
|
||||
redis.call("pexpire", key, ttl)
|
||||
return next
|
||||
end
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dataease",
|
||||
"version": "1.17.0",
|
||||
"version": "1.18.0",
|
||||
"description": "dataease front",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<artifactId>dataease-server</artifactId>
|
||||
<groupId>io.dataease</groupId>
|
||||
<version>1.17.0</version>
|
||||
<version>1.18.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -62,4 +62,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
2
frontend/public/vendor/vendor-manifest.json
vendored
2
frontend/public/vendor/vendor-manifest.json
vendored
File diff suppressed because one or more lines are too long
62
frontend/public/vendor/vendor.dll.js
vendored
62
frontend/public/vendor/vendor.dll.js
vendored
File diff suppressed because one or more lines are too long
@ -130,6 +130,13 @@ export function larkStatus() {
|
||||
})
|
||||
}
|
||||
|
||||
export function larkAppId() {
|
||||
return request({
|
||||
url: '/plugin/lark/appId',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function larksuiteStatus() {
|
||||
return request({
|
||||
url: '/api/auth/isOpenLarksuite',
|
||||
|
@ -293,14 +293,17 @@ export default {
|
||||
}
|
||||
},
|
||||
elementMouseDown(e) {
|
||||
// private 设置当前组件数据及状态
|
||||
// // private 设置当前组件数据及状态
|
||||
this.$store.commit('setClickComponentStatus', true)
|
||||
if (this.config.component !== 'v-text' && this.config.component !== 'rect-shape' && this.config.component !== 'de-input-search' && this.config.component !== 'de-select-grid' && this.config.component !== 'de-number-range' && this.config.component !== 'de-date') {
|
||||
e.preventDefault()
|
||||
}
|
||||
// 阻止冒泡事件
|
||||
e.stopPropagation()
|
||||
this.$store.commit('setCurComponent', { component: this.config, index: this.index })
|
||||
const _this = this
|
||||
setTimeout(() => {
|
||||
_this.$store.commit('setCurComponent', { component: _this.config, index: _this.index })
|
||||
}, 200)
|
||||
},
|
||||
showViewDetails(params) {
|
||||
this.$refs.wrapperChild.openChartDetailsDialog(params)
|
||||
|
@ -13,6 +13,7 @@
|
||||
<script>
|
||||
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
element: {
|
||||
@ -55,7 +56,7 @@ export default {
|
||||
},
|
||||
deleteComponent() {
|
||||
this.$emit('amRemoveItem')
|
||||
this.$store.commit('deleteComponent')
|
||||
this.$store.commit('deleteComponentWithId', this.element.id)
|
||||
this.$store.commit('setCurComponent', { component: null, index: null })
|
||||
},
|
||||
updateMobileSelected(id, mobileSelected) {
|
||||
@ -70,29 +71,30 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bar-main{
|
||||
position: absolute;
|
||||
float:right;
|
||||
z-index: 10000;
|
||||
border-radius:2px;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
cursor:pointer!important;
|
||||
text-align: center;
|
||||
background-color: var(--primary,#3370ff);
|
||||
}
|
||||
.bar-main i{
|
||||
color: white;
|
||||
float: right;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.bar-main {
|
||||
position: absolute;
|
||||
float: right;
|
||||
z-index: 10000;
|
||||
border-radius: 2px;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
cursor: pointer !important;
|
||||
text-align: center;
|
||||
background-color: var(--primary, #3370ff);
|
||||
}
|
||||
|
||||
.bar-main ::v-deep .el-checkbox__inner{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.bar-main i {
|
||||
color: white;
|
||||
float: right;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.bar-main ::v-deep .el-checkbox__inner::after{
|
||||
width: 4.5px;
|
||||
}
|
||||
.bar-main ::v-deep .el-checkbox__inner {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.bar-main ::v-deep .el-checkbox__inner::after {
|
||||
width: 4.5px;
|
||||
}
|
||||
</style>
|
||||
|
@ -63,7 +63,7 @@
|
||||
</div>
|
||||
<el-dialog
|
||||
v-if="pdfExportShow"
|
||||
:title="'['+panelInfo.name+']'+'PDF导出'"
|
||||
:title="'['+panelInfo.name+']'+$t('panel.pdf_export')"
|
||||
:visible.sync="pdfExportShow"
|
||||
width="80%"
|
||||
:top="'8vh'"
|
||||
@ -77,7 +77,7 @@
|
||||
/>
|
||||
<el-select
|
||||
v-model="pdfTemplateSelectedIndex"
|
||||
:placeholder="'切换PDF模板'"
|
||||
:placeholder="$t('panel.switch_pdf_template')"
|
||||
@change="changePdfTemplate()"
|
||||
>
|
||||
<el-option
|
||||
@ -635,7 +635,7 @@ export default {
|
||||
component.style[key] = this.format(component.style[key], this.scaleHeight)
|
||||
}
|
||||
if (this.needToChangeWidth.includes(key)) {
|
||||
if (key === 'fontSize' && (this.terminal === 'mobile' || component.type === 'custom')) {
|
||||
if ((key === 'fontSize' || key === 'activeFontSize') && (this.terminal === 'mobile' || component.type === 'custom')) {
|
||||
// do nothing 移动端字符大小无需按照比例缩放,当前保持不变(包括 v-text 和 过滤组件)
|
||||
} else {
|
||||
component.style[key] = this.format(component.style[key], this.scaleWidth)
|
||||
|
@ -85,6 +85,7 @@
|
||||
:ref="element.propValue.id"
|
||||
class="chart-class"
|
||||
:chart="chart"
|
||||
:terminal-type="scaleCoefficientType"
|
||||
:track-menu="trackMenu"
|
||||
:search-count="searchCount"
|
||||
@onChartClick="chartClick"
|
||||
|
@ -5,40 +5,49 @@ export default {
|
||||
mutations: {
|
||||
|
||||
upComponent({ componentData, curComponent }) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 上移图层 index,表示元素在数组中越往后
|
||||
if (curComponentIndex < componentData.length - 1) {
|
||||
moveUp(componentData, curComponentIndex)
|
||||
} else {
|
||||
toast('已经到顶了')
|
||||
if (curComponent) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 上移图层 index,表示元素在数组中越往后
|
||||
if (curComponentIndex < componentData.length - 1) {
|
||||
moveUp(componentData, curComponentIndex)
|
||||
} else {
|
||||
toast('已经到顶了')
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
downComponent({ componentData, curComponent }) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 下移图层 index,表示元素在数组中越往前
|
||||
if (curComponentIndex > 0) {
|
||||
moveDown(componentData, curComponentIndex)
|
||||
} else {
|
||||
toast('已经到底了')
|
||||
if (curComponent) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 下移图层 index,表示元素在数组中越往前
|
||||
if (curComponentIndex > 0) {
|
||||
moveDown(componentData, curComponentIndex)
|
||||
} else {
|
||||
toast('已经到底了')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
topComponent({ componentData, curComponent }) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 置顶
|
||||
if (curComponentIndex < componentData.length - 1) {
|
||||
toTop(componentData, curComponentIndex)
|
||||
if (curComponent) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 置顶
|
||||
if (curComponentIndex < componentData.length - 1) {
|
||||
toTop(componentData, curComponentIndex)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bottomComponent({ componentData, curComponent }) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 置底
|
||||
if (curComponentIndex > 0) {
|
||||
toBottom(componentData, curComponentIndex)
|
||||
} else {
|
||||
toast('已经到底了')
|
||||
if (curComponent) {
|
||||
const curComponentIndex = findCurComponentIndex(componentData, curComponent)
|
||||
// 置底
|
||||
if (curComponentIndex > 0) {
|
||||
toBottom(componentData, curComponentIndex)
|
||||
} else {
|
||||
toast('已经到底了')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
:active-color="activeColor"
|
||||
:border-color="borderColor"
|
||||
:border-active-color="borderActiveColor"
|
||||
:addable="isEdit"
|
||||
:addable="isEdit && !mobileLayoutStatus"
|
||||
@tab-add="addTab"
|
||||
@tab-click="handleClick"
|
||||
>
|
||||
@ -707,29 +707,27 @@ export default {
|
||||
border-color: blueviolet;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__nav {
|
||||
display: flex;
|
||||
}
|
||||
::v-deep .el-tabs__nav-prev {
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__nav-next {
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.tab-head-left ::v-deep .el-tabs__nav {
|
||||
.tab-head-left ::v-deep .el-tabs__nav-scroll {
|
||||
display: flex;
|
||||
text-align: left;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.tab-head-right ::v-deep .el-tabs__nav {
|
||||
.tab-head-right ::v-deep .el-tabs__nav-scroll {
|
||||
display: flex;
|
||||
text-align: right;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.tab-head-center ::v-deep .el-tabs__nav {
|
||||
.tab-head-center ::v-deep .el-tabs__nav-scroll {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.frame-mask {
|
||||
|
@ -135,6 +135,7 @@ export default {
|
||||
default_login: 'Normal'
|
||||
},
|
||||
commons: {
|
||||
collapse_navigation: 'Collapse navigation',
|
||||
operate_cancelled: 'Operation cancelled',
|
||||
bind: 'Bind',
|
||||
unbind: 'Unbind',
|
||||
@ -151,7 +152,7 @@ export default {
|
||||
params_value: 'Param Value',
|
||||
input_role_name: 'Enter a role name',
|
||||
publish: 'publish',
|
||||
unpublished: 'unpublished',
|
||||
unpublished: 'Unpublished',
|
||||
default_pwd: 'Default Pwd',
|
||||
stop: 'Stop',
|
||||
first_login_tips: 'Please change the initial password',
|
||||
@ -311,6 +312,7 @@ export default {
|
||||
validate: 'Validate',
|
||||
batch_add: 'Batch Add',
|
||||
tag_tip: 'Enter add label',
|
||||
search_keywords: 'Enter keywords to search',
|
||||
table: {
|
||||
select_tip: '{0} data selected'
|
||||
},
|
||||
@ -322,7 +324,10 @@ export default {
|
||||
start_date_time: 'Start date time',
|
||||
end_date_time: 'End date time',
|
||||
range_separator: 'to',
|
||||
data_time_error: 'The start date cannot be greater than the end date.'
|
||||
data_time_error: 'The start date cannot be greater than the end date.',
|
||||
one_day: 'One day',
|
||||
one_week: 'One week',
|
||||
one_month: 'One month'
|
||||
},
|
||||
adv_search: {
|
||||
title: 'Advanced search',
|
||||
@ -531,7 +536,10 @@ export default {
|
||||
set_saved_successfully: 'Data set saved successfully',
|
||||
to_start_using: 'Browse the contents of your database, tables and columns. Choose a database to get started.',
|
||||
to_run_query: 'Click to run query',
|
||||
the_running_results: 'You can view the running results'
|
||||
the_running_results: 'You can view the running results',
|
||||
item: 'item',
|
||||
logic_filter: 'Condition Filter',
|
||||
enum_filter: 'Enum Filter'
|
||||
},
|
||||
detabs: {
|
||||
custom_sort: 'Custom Sort',
|
||||
@ -655,6 +663,7 @@ export default {
|
||||
input_password: 'Please input a password',
|
||||
input_phone: 'Please enter the phone number',
|
||||
input_roles: 'Please select role',
|
||||
select_users: 'Please select user',
|
||||
user_name_pattern_error: 'IDs can only contain alphanumeric and ._- and start with a letter!',
|
||||
special_characters_are_not_supported: 'Special characters are not supported',
|
||||
mobile_number_format_is_incorrect: 'Incorrect format of mobile phone number',
|
||||
@ -811,6 +820,7 @@ export default {
|
||||
edite_organization: 'Edit organization'
|
||||
},
|
||||
system_parameter_setting: {
|
||||
email_server_config: 'Mailbox server configuration',
|
||||
edit_success: 'Edit success',
|
||||
mailbox_service_settings: 'Mail Setting',
|
||||
test_connection: 'Test connection',
|
||||
@ -1021,12 +1031,12 @@ export default {
|
||||
line_symbol_size: 'Break point size',
|
||||
line_type_solid: 'Solid line',
|
||||
line_type_dashed: 'Dotted line',
|
||||
line_symbol_circle: 'circular',
|
||||
line_symbol_circle: 'Circular',
|
||||
line_symbol_emptyCircle: 'Hollow circle',
|
||||
line_symbol_rect: 'rectangle',
|
||||
line_symbol_rect: 'Rectangle',
|
||||
line_symbol_roundRect: 'Rounded rectangle',
|
||||
line_symbol_triangle: 'triangle',
|
||||
line_symbol_diamond: 'diamond',
|
||||
line_symbol_triangle: 'Triangle',
|
||||
line_symbol_diamond: 'Diamond',
|
||||
line_symbol_pin: 'nail',
|
||||
line_symbol_arrow: 'arrow',
|
||||
line_symbol_none: 'None',
|
||||
@ -1036,7 +1046,7 @@ export default {
|
||||
funnel_width: 'width',
|
||||
line_smooth: 'Smooth polyline',
|
||||
title_style: 'Title Style',
|
||||
text_fontsize: 'font size',
|
||||
text_fontsize: 'Font size',
|
||||
text_color: 'Font color',
|
||||
text_h_position: 'Horizontal position',
|
||||
text_v_position: 'Vertical position',
|
||||
@ -1054,7 +1064,7 @@ export default {
|
||||
shape: 'shape',
|
||||
polygon: 'polygon',
|
||||
circle: 'circular',
|
||||
label: 'label',
|
||||
label: 'Label',
|
||||
label_position: 'Label location',
|
||||
label_bg: 'Label BG',
|
||||
label_shadow: 'Label Shadow',
|
||||
@ -1460,7 +1470,28 @@ export default {
|
||||
empty_data_strategy: 'Empty Data Strategy',
|
||||
break_line: 'Disconnection',
|
||||
set_zero: 'Set Zero',
|
||||
ignore_data: 'Ignore Data'
|
||||
ignore_data: 'Ignore Data',
|
||||
sub_dimension_tip: 'This field is required, and cannot be included in the type axis, you should choose non-group chart if you don\'t need it, or you will get unexpected chart.',
|
||||
drill_dimension_tip: 'Only fields in the dataset can be drilled',
|
||||
table_scroll_tip: 'The detail table is only effective when the pagination mode is "Drop-down".',
|
||||
table_threshold_tip: 'Tip: Do not select fields repeatedly. If the same field is configured repeatedly, only the last field will take effect.',
|
||||
table_column_width_tip: `Column width do not always work.<br/>
|
||||
The priority of the container width is higher than the column width, <br/>
|
||||
which means if the result of dividing the width of the table container by the number of columns is greater than specified column width, <br/>
|
||||
the former will take effect.`,
|
||||
reference_field_tip: `Reference fields start with "[" and end with "]". <br/>
|
||||
Do not modify the reference content, otherwise the reference will fail.<br/>
|
||||
If you enter content in the same format as the reference field, it will be treated as a reference field.`,
|
||||
scatter_tip: 'When this indicator is in effect, the bubble size attribute in the style size will be invalid',
|
||||
place_name_mapping: 'Place name mapping',
|
||||
axis_tip: 'The minimum value, maximum value, and interval are all numeric types; it will be regarded as automatic if left blank.<br/>Please make sure that the filled values can be calculated correctly, otherwise the axis values will not be displayed normally.',
|
||||
format_tip: `The template variables include {a}, {b}, {c}, {d}, which represent series name, data name, data value, etc. respectively.<br>
|
||||
When the trigger position is 'coordinate axis', there will be multiple series of data. At this time, the index of the series can be represented by {a0}, {a1}, {a2} followed by an index.<br>
|
||||
{a}, {b}, {c}, {d} have different meanings under different graph types. Among them, variables {a}, {b}, {c}, {d} represent data meanings in different chart types:<br><br>
|
||||
Line (area) chart, Column (Bar) chart, Dashboard: {a} is series name, {b} is category value, {c} is value<br>
|
||||
Pie chart, Funnel chart: {a} is series name, {b} is data item name, {c} is value, {d} is percentage<br>
|
||||
Map : {a} (series name), {b} is area name, {c} is merged values, {d} is none<br>
|
||||
Scatter (Bubble) plot: {a} is series name, {b} is data name, {c} is numeric array, {d} is none`
|
||||
},
|
||||
dataset: {
|
||||
spend_time: 'Spend',
|
||||
@ -1722,7 +1753,17 @@ export default {
|
||||
export_dataset: 'Export',
|
||||
filename: 'Filename',
|
||||
export_filter: 'Filter',
|
||||
pls_input_filename: 'Please input filename'
|
||||
pls_input_filename: 'Please input filename',
|
||||
calc_tips: {
|
||||
tip1: 'The expression syntax should follow the database syntax corresponding to the data source.',
|
||||
tip2: 'Aggregation operation is not supported in the dataset.',
|
||||
tip3: 'The reference field starts with "[" and ends with "]"',
|
||||
tip4: 'Do not modify the reference content, otherwise the reference will fail',
|
||||
tip5: 'If you enter content in the same format as the reference field, it will be treated as a reference field',
|
||||
tip6: 'Use the functions supported by the database type corresponding to the dataset. The syntax is the same as that of the corresponding database',
|
||||
tip7: 'For example, date format: MySQL uses DATE_ FORMAT(date,format); Oracle uses TO_ DATE(X,[,fmt])',
|
||||
tip8: 'Non direct connection mode data set, use Doris database functions, refer to Doris official website'
|
||||
}
|
||||
},
|
||||
driver: {
|
||||
driver: 'Driver',
|
||||
@ -1892,7 +1933,7 @@ export default {
|
||||
},
|
||||
panel: {
|
||||
position_adjust_component: 'Position adjust',
|
||||
active_font_size: 'Active font size',
|
||||
active_font_size: 'Selected font size',
|
||||
carousel: 'Carousel',
|
||||
switch_time: 'Switch time',
|
||||
position_adjust: 'Position',
|
||||
@ -1983,7 +2024,7 @@ export default {
|
||||
inner_padding: 'Inner Padding',
|
||||
board_radio: 'Board Radio',
|
||||
background: 'Background',
|
||||
component_style: 'component Style',
|
||||
component_style: 'Component Style',
|
||||
web_set_tips: 'Some Websites Cannot Be Displayed Because Of Not Allow Embedded ',
|
||||
repeat_params: 'Repeat Params Exist',
|
||||
enable_outer_param_set: 'Enable Outer Param Set',
|
||||
@ -2036,6 +2077,7 @@ export default {
|
||||
delete_success: 'Delete Success',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
save: 'Save',
|
||||
search: 'Search',
|
||||
back: 'Back',
|
||||
view: 'Chart',
|
||||
@ -2226,7 +2268,11 @@ export default {
|
||||
select_view: 'Please select a view...',
|
||||
visual: 'Visual',
|
||||
prohibit_multiple: 'Prohibit multiple fields in the same dataset',
|
||||
be_empty_dir: 'is empty dir'
|
||||
be_empty_dir: 'is empty dir',
|
||||
fold: 'Fold',
|
||||
expand: 'Expand',
|
||||
pdf_export: 'PDF Export',
|
||||
switch_pdf_template: 'Switch PDF Template'
|
||||
},
|
||||
plugin: {
|
||||
local_install: 'Local installation',
|
||||
@ -2543,6 +2589,14 @@ export default {
|
||||
|
||||
},
|
||||
emailtask: {
|
||||
week_mon: 'Mon',
|
||||
week_tue: 'Tue',
|
||||
week_wed: 'Wed',
|
||||
week_thu: 'Thu',
|
||||
week_fri: 'Fri',
|
||||
week_sat: 'Sat',
|
||||
week_sun: 'Sun',
|
||||
send_config: 'Send configuration',
|
||||
title: 'Title',
|
||||
panel: 'Panel',
|
||||
content: 'Content',
|
||||
@ -2727,5 +2781,24 @@ export default {
|
||||
logout: {
|
||||
oidc_logout_error: 'OIDC failed to exit, do you continue to exit DataEase?',
|
||||
cas_logout_error: 'The CAS service is abnormal, please contact the administrator!'
|
||||
},
|
||||
watermark: {
|
||||
support_params: 'Currently supported parameters:',
|
||||
enable: 'Enable',
|
||||
enable_panel_custom: 'Allow the dashboard to open or close the watermark independently',
|
||||
content: 'content',
|
||||
custom_content: 'Custom Content',
|
||||
account: 'Account',
|
||||
nick_name: 'Nick Name',
|
||||
ip: 'IP',
|
||||
now: 'Now Time',
|
||||
watermark_color: 'Watermark Color',
|
||||
watermark_font_size: 'Watermark Fontsize',
|
||||
watermark_space: 'Watermark Space',
|
||||
horizontal: 'Horizontal',
|
||||
vertical: 'Vertical',
|
||||
reset: 'Reset',
|
||||
preview: 'Preview',
|
||||
save: 'Save'
|
||||
}
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ export default {
|
||||
default_login: '普通登錄'
|
||||
},
|
||||
commons: {
|
||||
collapse_navigation: '收起導航',
|
||||
operate_cancelled: '已取消操作',
|
||||
bind: '綁定',
|
||||
unbind: '解綁',
|
||||
@ -311,6 +312,7 @@ export default {
|
||||
validate: '校驗',
|
||||
batch_add: '批量添加',
|
||||
tag_tip: '輸入回車添加標簽',
|
||||
search_keywords: '輸入關鍵字搜索',
|
||||
table: {
|
||||
select_tip: '已選中 {0} 條數據'
|
||||
},
|
||||
@ -322,7 +324,10 @@ export default {
|
||||
start_date_time: '開始日期時間',
|
||||
end_date_time: '結束日期時間',
|
||||
range_separator: '至',
|
||||
data_time_error: '開始日期不能大於結束日期'
|
||||
data_time_error: '開始日期不能大於結束日期',
|
||||
one_day: '一天',
|
||||
one_week: '一周',
|
||||
one_month: '一個月'
|
||||
},
|
||||
adv_search: {
|
||||
title: '高級搜索',
|
||||
@ -531,7 +536,10 @@ export default {
|
||||
set_saved_successfully: '數據集保存成功',
|
||||
to_start_using: '瀏覽您的數據庫,表和列的內容。 選擇一個數據庫即可開始使用。',
|
||||
to_run_query: '點擊運行査詢',
|
||||
the_running_results: '即可查看運行結果'
|
||||
the_running_results: '即可查看運行結果',
|
||||
item: '項',
|
||||
logic_filter: '條件篩選',
|
||||
enum_filter: '枚舉篩選'
|
||||
},
|
||||
detabs: {
|
||||
custom_sort: '自定義排序',
|
||||
@ -811,6 +819,7 @@ export default {
|
||||
edite_organization: '編輯組織'
|
||||
},
|
||||
system_parameter_setting: {
|
||||
email_server_config: '郵箱服務器配置',
|
||||
edit_success: '編輯成功',
|
||||
mailbox_service_settings: '郵件設置',
|
||||
test_connection: '測試連接',
|
||||
@ -1460,7 +1469,23 @@ export default {
|
||||
empty_data_strategy: '空值處理',
|
||||
break_line: '線條斷開',
|
||||
set_zero: '置為0,線條不斷開',
|
||||
ignore_data: '跳過空值,不展示'
|
||||
ignore_data: '跳過空值,不展示',
|
||||
sub_dimension_tip: '該字段為必填項,且不應使用類別軸中的字段,若無需該字段,請選擇基礎圖表進行展示,否則展示效果不理想',
|
||||
drill_dimension_tip: '鑽取字段僅支持數據集中的字段',
|
||||
table_scroll_tip: '明細表僅在分頁模式為"下拉"時生效。',
|
||||
table_threshold_tip: '提示:請勿重複選擇字段,若同一字段重複配置,則只有最後的字段配置生效。',
|
||||
table_column_width_tip: '列寬並非任何時候都能生效。<br/>容器寬度優先級高於列寬。即(表格容器寬度 / 列數 > 指定列寬),則列寬優先取(容器寬度 / 列數)',
|
||||
reference_field_tip: '引用字段以 "[" 開始,"]" 結束。請<br/>勿修改引用內容,否則將引用失敗。<br/>若輸入與引用字段相同格式的內容,將被當做引用字段處理。',
|
||||
scatter_tip: '該指標生效時,樣式大小中的氣泡大小屬性將失效',
|
||||
place_name_mapping: '地名映射',
|
||||
axis_tip: '最小值、最大值、間隔均為數值類型;若不填,則該項視為自動。<br/>請確保填寫數值能正確計算,否則將無法正常顯示值軸',
|
||||
format_tip: `模板變量有 {a}, {b},{c},{d},分別表示系列名,數據名,數據值等。<br>
|
||||
在 觸發位置 為 '坐標軸' 的時候,會有多個系列的數據,此時可以通過 {a0}, {a1}, {a2} 這種後面加索引的方式表示系列的索引。<br>
|
||||
不同圖表類型下的 {a},{b},{c},{d} 含義不一樣。 其中變量{a}, {b}, {c}, {d}在不同圖表類型下代表數據含義為:<br><br>
|
||||
折線(區域)圖、柱狀(條形)圖、儀表盤 : {a}(系列名稱),{b}(類目值),{c}(數值)<br>
|
||||
餅圖、漏鬥圖: {a}(系列名稱),{b}(數據項名稱),{c}(數值), {d}(百分比)<br>
|
||||
地圖 : {a}(系列名稱),{b}(區域名稱),{c}(合並數值), {d}(無)<br>
|
||||
散點圖(氣泡)圖 : {a}(系列名稱),{b}(數據名稱),{c}(數值數組), {d}(無)`
|
||||
},
|
||||
dataset: {
|
||||
spend_time: '耗時',
|
||||
@ -1722,7 +1747,17 @@ export default {
|
||||
export_dataset: '數據集導出',
|
||||
filename: '文件名稱',
|
||||
export_filter: '篩選條件',
|
||||
pls_input_filename: '請輸入文件名稱'
|
||||
pls_input_filename: '請輸入文件名稱',
|
||||
calc_tips: {
|
||||
tip1: '表達式語法請遵循該數據源對應的數據庫語法。',
|
||||
tip2: '數據集中不支持聚合運算。',
|
||||
tip3: '引用字段以 "[" 開始, "]" 結束',
|
||||
tip4: '請勿修改引用內容,否則將引用失敗',
|
||||
tip5: '若輸入與引用字段相同格式的內容,將被當作引用字段處理',
|
||||
tip6: '使用數據集對應數據庫類型所支持的函數,語法同對應數據庫',
|
||||
tip7: '如日期格式化:MySQL使用DATE_FORMAT(date,format);Oracle使用TO_DATE(X,[,fmt])',
|
||||
tip8: '非直連模式數據集,使用Doris數據庫函數,可參考Doris官網'
|
||||
}
|
||||
},
|
||||
driver: {
|
||||
driver: '驅動',
|
||||
@ -1892,7 +1927,7 @@ export default {
|
||||
},
|
||||
panel: {
|
||||
position_adjust_component: '位置調整',
|
||||
active_font_size: '激活字體大小',
|
||||
active_font_size: '选中字體大小',
|
||||
carousel: '輪播',
|
||||
switch_time: '切換時間',
|
||||
position_adjust: '位置',
|
||||
@ -2227,7 +2262,11 @@ export default {
|
||||
select_view: '請選擇視圖...',
|
||||
visual: '虛擬化',
|
||||
prohibit_multiple: '禁止同數據集多字段',
|
||||
be_empty_dir: '是空目錄'
|
||||
be_empty_dir: '是空目錄',
|
||||
fold: '收起',
|
||||
expand: '展開',
|
||||
pdf_export: 'PDF 導出',
|
||||
switch_pdf_template: '切換 PDF 模板'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安裝',
|
||||
@ -2544,6 +2583,14 @@ export default {
|
||||
|
||||
},
|
||||
emailtask: {
|
||||
week_mon: '周一',
|
||||
week_tue: '周二',
|
||||
week_wed: '周三',
|
||||
week_thu: '周四',
|
||||
week_fri: '周五',
|
||||
week_sat: '周六',
|
||||
week_sun: '周日',
|
||||
send_config: '發送設置',
|
||||
title: '報告主題',
|
||||
panel: '儀表闆',
|
||||
content: '報告正文',
|
||||
@ -2568,9 +2615,9 @@ export default {
|
||||
emial_preview: '報告預覽',
|
||||
chart_data_range: '視圖數據範圍',
|
||||
simple_repeat: '簡單重複',
|
||||
once_a_day: '每天一次',
|
||||
once_a_week: '每周一次',
|
||||
once_a_month: '每月一次',
|
||||
once_a_day: '每天',
|
||||
once_a_week: '每周',
|
||||
once_a_month: '每月',
|
||||
complex_repeat: '複雜重複',
|
||||
pixel_tip: '可直接輸入分辨率(例如:2560 * 1600)或者選擇',
|
||||
task_type: '任務類型',
|
||||
@ -2727,5 +2774,24 @@ export default {
|
||||
logout: {
|
||||
oidc_logout_error: 'OIDC退出失敗,是否繼續退出DataEase?',
|
||||
cas_logout_error: 'CAS服務異常,請聯系管理員!'
|
||||
},
|
||||
watermark: {
|
||||
support_params: '當前支持的參數:',
|
||||
enable: '啟用',
|
||||
enable_panel_custom: '允許儀表板單獨打開或者關閉水印',
|
||||
content: '內容',
|
||||
custom_content: '自定義公式',
|
||||
account: '賬號',
|
||||
nick_name: '昵稱',
|
||||
ip: 'IP',
|
||||
now: '當前時間',
|
||||
watermark_color: '水印顏色',
|
||||
watermark_font_size: '水印字號',
|
||||
watermark_space: '水印間距',
|
||||
horizontal: '橫向',
|
||||
vertical: '縱向',
|
||||
reset: '重置',
|
||||
preview: '預覽',
|
||||
save: '保存'
|
||||
}
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ export default {
|
||||
default_login: '普通登录'
|
||||
},
|
||||
commons: {
|
||||
collapse_navigation: '收起导航',
|
||||
operate_cancelled: '已取消操作',
|
||||
bind: '绑定',
|
||||
unbind: '解绑',
|
||||
@ -310,6 +311,7 @@ export default {
|
||||
validate: '校验',
|
||||
batch_add: '批量添加',
|
||||
tag_tip: '输入回车添加标签',
|
||||
search_keywords: '输入关键字搜索',
|
||||
table: {
|
||||
select_tip: '已选中 {0} 条数据'
|
||||
},
|
||||
@ -321,7 +323,10 @@ export default {
|
||||
start_date_time: '开始日期时间',
|
||||
end_date_time: '结束日期时间',
|
||||
range_separator: '至',
|
||||
data_time_error: '开始日期不能大于结束日期'
|
||||
data_time_error: '开始日期不能大于结束日期',
|
||||
one_day: '一天',
|
||||
one_week: '一周',
|
||||
one_month: '一个月'
|
||||
},
|
||||
adv_search: {
|
||||
title: '高级搜索',
|
||||
@ -530,7 +535,10 @@ export default {
|
||||
set_saved_successfully: '数据集保存成功',
|
||||
to_start_using: '浏览您的数据库,表和列的内容。 选择一个数据库即可开始使用。',
|
||||
to_run_query: '点击运行查询',
|
||||
the_running_results: '即可查看运行结果'
|
||||
the_running_results: '即可查看运行结果',
|
||||
item: '项',
|
||||
logic_filter: '条件筛选',
|
||||
enum_filter: '枚举筛选'
|
||||
},
|
||||
detabs: {
|
||||
custom_sort: '自定义排序',
|
||||
@ -810,6 +818,7 @@ export default {
|
||||
edite_organization: '编辑组织'
|
||||
},
|
||||
system_parameter_setting: {
|
||||
email_server_config: '邮箱服务器配置',
|
||||
edit_success: '编辑成功',
|
||||
mailbox_service_settings: '邮件设置',
|
||||
test_connection: '测试连接',
|
||||
@ -1459,7 +1468,23 @@ export default {
|
||||
empty_data_strategy: '空值处理',
|
||||
break_line: '线条断开',
|
||||
set_zero: '置为0,线条不断开',
|
||||
ignore_data: '跳过空值,不展示'
|
||||
ignore_data: '跳过空值,不展示',
|
||||
sub_dimension_tip: '该字段为必填项,且不应使用类别轴中的字段,若无需该字段,请选择基础图表进行展示,否则展示效果不理想。',
|
||||
drill_dimension_tip: '钻取字段仅支持数据集中的字段',
|
||||
table_scroll_tip: '明细表仅在分页模式为"下拉"时生效。',
|
||||
table_threshold_tip: '提示:请勿重复选择字段,若同一字段重复配置,则只有最后的字段配置生效',
|
||||
table_column_width_tip: '列宽并非任何时候都能生效。<br/>容器宽度优先级高于列宽,即(表格容器宽度 / 列数 > 指定列宽),则列宽优先取(容器宽度 / 列数)。',
|
||||
reference_field_tip: '引用字段以 "[" 开始, "]" 结束。<br/>请勿修改引用内容,否则将引用失败。<br/>若输入与引用字段相同格式的内容,将被当作引用字段处理。',
|
||||
scatter_tip: '该指标生效时,样式大小中的气泡大小属性将失效',
|
||||
place_name_mapping: '地名映射',
|
||||
axis_tip: '最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。<br/>请确保填写数值能正确计算,否则将无法正常显示轴值。',
|
||||
format_tip: `模板变量有 {a}, {b},{c},{d},分别表示系列名,数据名,数据值等。<br>
|
||||
在 触发位置 为 '坐标轴' 的时候,会有多个系列的数据,此时可以通过 {a0}, {a1}, {a2} 这种后面加索引的方式表示系列的索引。<br>
|
||||
不同图表类型下的 {a},{b},{c},{d} 含义不一样。 其中变量{a}, {b}, {c}, {d}在不同图表类型下代表数据含义为:<br><br>
|
||||
折线(区域)图、柱状(条形)图、仪表盘 : {a}(系列名称),{b}(类目值),{c}(数值)<br>
|
||||
饼图、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)<br>
|
||||
地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)<br>
|
||||
散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)`
|
||||
},
|
||||
dataset: {
|
||||
spend_time: '耗时',
|
||||
@ -1721,7 +1746,17 @@ export default {
|
||||
export_dataset: '数据集导出',
|
||||
filename: '文件名称',
|
||||
export_filter: '筛选条件',
|
||||
pls_input_filename: '请输入文件名称'
|
||||
pls_input_filename: '请输入文件名称',
|
||||
calc_tips: {
|
||||
tip1: '表达式语法请遵循该数据源对应的数据库语法。',
|
||||
tip2: '数据集中不支持聚合运算。',
|
||||
tip3: '引用字段以 "[" 开始, "]" 结束',
|
||||
tip4: '请勿修改引用内容,否则将引用失败',
|
||||
tip5: '若输入与引用字段相同格式的内容,将被当作引用字段处理',
|
||||
tip6: '使用数据集对应数据库类型所支持的函数,语法同对应数据库',
|
||||
tip7: '如日期格式化:MySQL使用DATE_FORMAT(date,format);Oracle使用TO_DATE(X,[,fmt])',
|
||||
tip8: '非直连模式数据集,使用Doris数据库函数,可参考Doris官网'
|
||||
}
|
||||
},
|
||||
driver: {
|
||||
driver: '驱动',
|
||||
@ -1892,7 +1927,7 @@ export default {
|
||||
},
|
||||
panel: {
|
||||
position_adjust_component: '位置调整',
|
||||
active_font_size: '激活字体大小',
|
||||
active_font_size: '选中字体大小',
|
||||
carousel: '轮播',
|
||||
switch_time: '切换时间',
|
||||
position_adjust: '位置',
|
||||
@ -2227,7 +2262,11 @@ export default {
|
||||
select_view: '请选择视图...',
|
||||
visual: '虚拟化',
|
||||
prohibit_multiple: '禁止同数据集多字段',
|
||||
be_empty_dir: '是空目录!'
|
||||
be_empty_dir: '是空目录!',
|
||||
fold: '收起',
|
||||
expand: '展开',
|
||||
pdf_export: 'PDF 导出',
|
||||
switch_pdf_template: '切换 PDF 模板'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安装',
|
||||
@ -2544,6 +2583,14 @@ export default {
|
||||
|
||||
},
|
||||
emailtask: {
|
||||
week_mon: '周一',
|
||||
week_tue: '周二',
|
||||
week_wed: '周三',
|
||||
week_thu: '周四',
|
||||
week_fri: '周五',
|
||||
week_sat: '周六',
|
||||
week_sun: '周日',
|
||||
send_config: '发送设置',
|
||||
title: '报告主题',
|
||||
panel: '仪表板',
|
||||
content: '报告正文',
|
||||
@ -2568,9 +2615,9 @@ export default {
|
||||
emial_preview: '报告预览',
|
||||
chart_data_range: '视图数据范围',
|
||||
simple_repeat: '简单重复',
|
||||
once_a_day: '每天一次',
|
||||
once_a_week: '每周一次',
|
||||
once_a_month: '每月一次',
|
||||
once_a_day: '每天',
|
||||
once_a_week: '每周',
|
||||
once_a_month: '每月',
|
||||
complex_repeat: '复杂重复',
|
||||
pixel_tip: '可直接输入自定义分辨率(例如:2560 * 1600)或选择',
|
||||
task_type: '任务类型',
|
||||
@ -2727,5 +2774,24 @@ export default {
|
||||
logout: {
|
||||
oidc_logout_error: 'OIDC退出失败,是否继续退出DataEase?',
|
||||
cas_logout_error: 'CAS服务异常,请联系管理员!'
|
||||
},
|
||||
watermark: {
|
||||
support_params: '当前支持的参数:',
|
||||
enable: '启用',
|
||||
enable_panel_custom: '允许仪表板单独打开或者关闭水印',
|
||||
content: '内容',
|
||||
custom_content: '自定义公式',
|
||||
account: '账号',
|
||||
nick_name: '昵称',
|
||||
ip: 'IP',
|
||||
now: '当前时间',
|
||||
watermark_color: '水印颜色',
|
||||
watermark_font_size: '水印字号',
|
||||
watermark_space: '水印间距',
|
||||
horizontal: '横向',
|
||||
vertical: '纵向',
|
||||
reset: '重置',
|
||||
preview: '预览',
|
||||
save: '保存'
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
:style="{ transform: isCollapse ? 'rotate(90deg)' : 'rotate(-90deg)' }"
|
||||
class="el-icon-upload2"
|
||||
/>
|
||||
{{ isCollapse ? "" : "收起导航" }}
|
||||
{{ isCollapse ? "" : $t('commons.collapse_navigation') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -26,7 +26,7 @@ NProgress.configure({
|
||||
showSpinner: false
|
||||
}) // NProgress Configuration
|
||||
|
||||
const whiteList = ['/login', '/401', '/404', '/delink', '/nolic'] // no redirect whitelist
|
||||
const whiteList = ['/login', '/401', '/404', '/delink', '/nolic', '/de-auto-login'] // no redirect whitelist
|
||||
|
||||
const routeBefore = (callBack) => {
|
||||
let uiInfo = getSysUI()
|
||||
@ -53,7 +53,7 @@ const routeBefore = (callBack) => {
|
||||
callBack()
|
||||
}
|
||||
}
|
||||
router.beforeEach(async(to, from, next) => routeBefore(() => {
|
||||
router.beforeEach(async (to, from, next) => routeBefore(() => {
|
||||
// start progress bar
|
||||
NProgress.start()
|
||||
const mobileIgnores = ['/delink']
|
||||
|
@ -91,6 +91,11 @@ export const constantRoutes = [
|
||||
path: '/previewFullScreen',
|
||||
component: () => import('@/components/canvas/components/editor/PreviewFullScreen'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/de-auto-login',
|
||||
component: () => import('@/views/DeAutoLogin'),
|
||||
hidden: true
|
||||
}
|
||||
|
||||
// {
|
||||
@ -208,11 +213,11 @@ export const constantRoutes = [
|
||||
// ]
|
||||
// },
|
||||
// 404 page must be placed at the end !!!
|
||||
// { path: '*', redirect: '/404', hidden: true }
|
||||
// { path: '*', redirect: '/404', hidden: true }
|
||||
]
|
||||
|
||||
const createRouter = () => new Router({
|
||||
// mode: 'history', // require service support
|
||||
// mode: 'history', // require service support
|
||||
mode: 'hash',
|
||||
scrollBehavior: () => ({ y: 0 }),
|
||||
routes: constantRoutes
|
||||
|
@ -232,8 +232,8 @@ const data = {
|
||||
}
|
||||
},
|
||||
setShapeStyle({ curComponent, canvasStyleData, curCanvasScaleMap }, { top, left, width, height, rotate }) {
|
||||
const curCanvasScaleSelf = curCanvasScaleMap[curComponent.canvasId]
|
||||
if (curComponent) {
|
||||
const curCanvasScaleSelf = curCanvasScaleMap[curComponent.canvasId]
|
||||
if (top || top === 0) curComponent.style.top = Math.round((top / curCanvasScaleSelf.scalePointHeight))
|
||||
if (left || left === 0) curComponent.style.left = Math.round((left / curCanvasScaleSelf.scalePointWidth))
|
||||
if (width || width === 0) curComponent.style.width = Math.round((width / curCanvasScaleSelf.scalePointWidth))
|
||||
@ -569,7 +569,7 @@ const data = {
|
||||
// 移动端布局转换
|
||||
state.componentData.forEach(item => {
|
||||
item.mobileStyle = (item.mobileStyle || BASE_MOBILE_STYLE)
|
||||
if (item.mobileSelected || item.canvasId !== 'canvas-main') {
|
||||
if (item.mobileSelected && item.canvasId === 'canvas-main') {
|
||||
item.style.width = item.mobileStyle.style.width
|
||||
item.style.height = item.mobileStyle.style.height
|
||||
item.style.top = item.mobileStyle.style.top
|
||||
@ -581,6 +581,8 @@ const data = {
|
||||
item.sizey = item.mobileStyle.sizey
|
||||
item.auxiliaryMatrix = item.mobileStyle.auxiliaryMatrix
|
||||
mainComponentData.push(item)
|
||||
} else if (item.canvasId !== 'canvas-main') {
|
||||
mainComponentData.push(item)
|
||||
}
|
||||
})
|
||||
state.componentData = mainComponentData
|
||||
|
@ -29,7 +29,7 @@ const actions = {
|
||||
commit('SET_CURRENT_PATH', path)
|
||||
}
|
||||
}
|
||||
export const fullScreenRouters = ['XpackThemeForm', 'system/datasource/DsForm', 'dataset/Form']
|
||||
export const fullScreenRouters = ['XpackThemeForm', 'system/datasource/DsForm', 'dataset/Form', 'DeAutoLogin']
|
||||
export const filterAsyncRouter = (routers) => { // 遍历后台传来的路由字符串,转换为组件对象
|
||||
return routers.map(router => {
|
||||
if (!fullScreenRouters.includes(router.component) && router.type === 1 && router.pid === 0 && router.component && router.component !== 'Layout') {
|
||||
|
@ -1703,4 +1703,4 @@ div:focus {
|
||||
margin-bottom: 8px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
142
frontend/src/views/DeAutoLogin.vue
Normal file
142
frontend/src/views/DeAutoLogin.vue
Normal file
@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div
|
||||
v-loading="loading"
|
||||
class="de-auto-login"
|
||||
>
|
||||
<plugin-com
|
||||
v-if="isDingTalkLink && dingtalkOpen && corpId"
|
||||
ref="DTWithoutLogin"
|
||||
:corp-id="corpId"
|
||||
component-name="DTWithoutLogin"
|
||||
/>
|
||||
|
||||
<plugin-com
|
||||
v-else-if="isLarkLink && larkOpen && appId"
|
||||
ref="LKWithoutLogin"
|
||||
:app-id="appId"
|
||||
component-name="LKWithoutLogin"
|
||||
/>
|
||||
|
||||
<plugin-com
|
||||
v-else-if="isLarksuiteLink && larksuiteOpen"
|
||||
ref="LKSWithoutLogin"
|
||||
component-name="LKSWithoutLogin"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-if="isDingTalkLink && !loading && !dingtalkOpen"
|
||||
class="auto-login-missing"
|
||||
>
|
||||
<span>未开启钉钉</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else-if="isDingTalkLink && !loading && !corpId"
|
||||
class="auto-login-missing"
|
||||
>
|
||||
<span>缺失企业ID参数</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="isLarkLink && !loading && !larkOpen"
|
||||
class="auto-login-missing"
|
||||
>
|
||||
<span>未开启飞书</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else-if="isLarkLink && !loading && !appId"
|
||||
class="auto-login-missing"
|
||||
>
|
||||
<span>缺失应用ID参数</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="isLarksuiteLink && !loading && !larksuiteOpen"
|
||||
class="auto-login-missing"
|
||||
>
|
||||
<span>未开启国际飞书</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
import { dingtalkStatus, larkStatus, larksuiteStatus, larkAppId } from '@/api/user'
|
||||
export default {
|
||||
name: 'DeAutoLogin',
|
||||
components: { PluginCom },
|
||||
data() {
|
||||
return {
|
||||
type: 'dingtalk',
|
||||
corpId: null,
|
||||
appId: null,
|
||||
dingtalkOpen: false,
|
||||
larkOpen: false,
|
||||
larksuiteOpen: false,
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isDingTalkLink() {
|
||||
return this.type === 'dingtalk' || !this.type
|
||||
},
|
||||
isLarkLink() {
|
||||
return this.type === 'lark'
|
||||
},
|
||||
isLarksuiteLink() {
|
||||
return this.type === 'larksuite'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.corpId = this.$route.query.corpId
|
||||
if (this.$route.query.type) {
|
||||
this.type = this.$route.query.type
|
||||
}
|
||||
|
||||
this.isDingTalkLink && dingtalkStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
this.dingtalkOpen = true
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
this.isLarkLink && larkStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
larkAppId().then(resp => {
|
||||
this.appId = resp.data
|
||||
this.larkOpen = true
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}).catch(e => {
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
this.isLarksuiteLink && larksuiteStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
this.larksuiteOpen = true
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.de-auto-login {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
.auto-login-missing {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -43,7 +43,7 @@
|
||||
:span="3"
|
||||
style="padding-left: 10px;padding-top: 5px"
|
||||
>
|
||||
<el-checkbox v-model="curComponent.commonBackground.backgroundColorSelect">颜色</el-checkbox>
|
||||
<el-checkbox v-model="curComponent.commonBackground.backgroundColorSelect">{{ $t('chart.color') }}</el-checkbox>
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="1"
|
||||
@ -58,7 +58,7 @@
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<span class="params-title-small">不透明度:</span>
|
||||
<span class="params-title-small">{{ $t('chart.not_alpha') }}</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-slider
|
||||
@ -137,7 +137,7 @@
|
||||
v-model="curComponent.commonBackground.backgroundType"
|
||||
label="innerImage"
|
||||
@change="onChangeType"
|
||||
>边框
|
||||
>{{ $t('panel.board') }}
|
||||
</el-radio>
|
||||
<el-color-picker
|
||||
v-model="curComponent.commonBackground.innerImageColor"
|
||||
|
@ -378,7 +378,7 @@ export function getTooltip(chart) {
|
||||
} else {
|
||||
// 百分比堆叠柱状图隐藏 tooltip 设置 show 为 false 或者直接设置 tooltip 为 false 都无效,会变成分组显示,
|
||||
// 需要将容器(container)或者内容框(showContent)设置为 false 或者 null 才可以隐藏
|
||||
if (chart.type === 'percentage-bar-stack') {
|
||||
if (chart.type.includes('percentage')) {
|
||||
tooltip.showContent = false
|
||||
} else {
|
||||
tooltip = false
|
||||
|
@ -156,6 +156,7 @@ export function getCustomTheme(chart) {
|
||||
theme.colCell.text.fill = c.tableHeaderFontColor ? c.tableHeaderFontColor : c.tableFontColor
|
||||
theme.colCell.measureText.fill = c.tableHeaderFontColor ? c.tableHeaderFontColor : c.tableFontColor
|
||||
|
||||
theme.dataCell.cell.crossBackgroundColor = i_c
|
||||
theme.dataCell.cell.backgroundColor = i_c
|
||||
theme.dataCell.cell.horizontalBorderColor = b_c
|
||||
theme.dataCell.cell.verticalBorderColor = b_c
|
||||
|
@ -435,7 +435,6 @@ export function baseTablePivot(s2, container, chart, action, tableData) {
|
||||
}
|
||||
sortParams.push(sort)
|
||||
}
|
||||
totalCfg.col.totalSort = false
|
||||
if (totalCfg.col.totalSort && totalCfg.col.totalSort !== 'none' && r.length > 0 && totalCfg.col.showGrandTotals && v.indexOf(totalCfg.col.totalSortField) > -1) {
|
||||
const sort = {
|
||||
sortFieldId: r[0],
|
||||
|
@ -1163,7 +1163,6 @@ export const TYPE_CONFIGS = [
|
||||
icon: 'percentage-bar-stack-horizontal',
|
||||
properties: [
|
||||
'color-selector',
|
||||
'size-selector-ant-v',
|
||||
'label-selector-ant-v',
|
||||
'tooltip-selector-ant-v',
|
||||
'x-axis-selector-ant-v',
|
||||
@ -1179,10 +1178,6 @@ export const TYPE_CONFIGS = [
|
||||
'gradient',
|
||||
'alpha'
|
||||
],
|
||||
'size-selector-ant-v': [
|
||||
'barDefault',
|
||||
'barGap'
|
||||
],
|
||||
'label-selector-ant-v': [
|
||||
'show',
|
||||
'fontSize',
|
||||
@ -1478,7 +1473,6 @@ export const TYPE_CONFIGS = [
|
||||
icon: 'percentage-bar-stack',
|
||||
properties: [
|
||||
'color-selector',
|
||||
'size-selector-ant-v',
|
||||
'label-selector-ant-v',
|
||||
'tooltip-selector-ant-v',
|
||||
'x-axis-selector-ant-v',
|
||||
@ -1494,10 +1488,6 @@ export const TYPE_CONFIGS = [
|
||||
'gradient',
|
||||
'alpha'
|
||||
],
|
||||
'size-selector-ant-v': [
|
||||
'barDefault',
|
||||
'barGap'
|
||||
],
|
||||
'label-selector-ant-v': [
|
||||
'show',
|
||||
'fontSize',
|
||||
|
@ -18,7 +18,7 @@
|
||||
:style="title_class"
|
||||
style="cursor: default;display: block;"
|
||||
>
|
||||
<div style="padding:6px 4px 0;margin: 0;">
|
||||
<div style="padding:4px 4px 0;margin: 0;">
|
||||
<chart-title-update
|
||||
:title-class="title_class"
|
||||
:chart-info="chartInfo"
|
||||
|
@ -18,7 +18,7 @@
|
||||
:style="title_class"
|
||||
style="cursor: default;display: block;"
|
||||
>
|
||||
<div style="padding:6px 4px 0;margin: 0;">
|
||||
<div style="padding:4px 4px 0;margin: 0;">
|
||||
<chart-title-update
|
||||
:title-class="title_class"
|
||||
:chart-info="chartInfo"
|
||||
@ -67,8 +67,8 @@
|
||||
>
|
||||
{{ $t('chart.total') }}
|
||||
<span>{{
|
||||
chart.datasetMode === 0 ? chart.totalItems : ((chart.data && chart.data.tableRow) ? chart.data.tableRow.length : 0)
|
||||
}}</span>
|
||||
(chart.datasetMode === 0 && !not_support_page_dataset.includes(chart.datasourceType)) ? chart.totalItems : ((chart.data && chart.data.tableRow) ? chart.data.tableRow.length : 0)
|
||||
}}</span>
|
||||
{{ $t('chart.items') }}
|
||||
</span>
|
||||
<de-pagination
|
||||
@ -101,10 +101,15 @@ import { DEFAULT_TITLE_STYLE, NOT_SUPPORT_PAGE_DATASET } from '@/views/chart/cha
|
||||
import ChartTitleUpdate from './ChartTitleUpdate.vue'
|
||||
import { mapState } from 'vuex'
|
||||
import DePagination from '@/components/deCustomCm/pagination.js'
|
||||
|
||||
export default {
|
||||
name: 'ChartComponentS2',
|
||||
components: { TitleRemark, ViewTrackBar, ChartTitleUpdate, DePagination },
|
||||
props: {
|
||||
terminalType: {
|
||||
type: String,
|
||||
default: 'pc'
|
||||
},
|
||||
chart: {
|
||||
type: Object,
|
||||
required: true
|
||||
@ -173,7 +178,8 @@ export default {
|
||||
},
|
||||
totalStyle: {
|
||||
color: '#606266'
|
||||
}
|
||||
},
|
||||
not_support_page_dataset: NOT_SUPPORT_PAGE_DATASET
|
||||
}
|
||||
},
|
||||
|
||||
@ -182,13 +188,18 @@ export default {
|
||||
return this.previewCanvasScale.scalePointWidth
|
||||
},
|
||||
autoStyle() {
|
||||
return {
|
||||
height: (100 / this.scale) + '%!important',
|
||||
width: (100 / this.scale) + '%!important',
|
||||
left: 50 * (1 - 1 / this.scale) + '%', // 放大余量 除以 2
|
||||
top: 50 * (1 - 1 / this.scale) + '%', // 放大余量 除以 2
|
||||
transform: 'scale(' + this.scale + ')'
|
||||
if (this.terminalType === 'pc') {
|
||||
return {
|
||||
height: (100 / this.scale) + '%!important',
|
||||
width: (100 / this.scale) + '%!important',
|
||||
left: 50 * (1 - 1 / this.scale) + '%', // 放大余量 除以 2
|
||||
top: 50 * (1 - 1 / this.scale) + '%', // 放大余量 除以 2
|
||||
transform: 'scale(' + this.scale + ')'
|
||||
}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
|
||||
},
|
||||
trackBarStyleTime() {
|
||||
return this.trackBarStyle
|
||||
|
@ -84,11 +84,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。
|
||||
<br>
|
||||
请确保填写数值能正确计算,否则将无法正常显示轴值。
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.axis_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -84,11 +84,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。
|
||||
<br>
|
||||
请确保填写数值能正确计算,否则将无法正常显示轴值。
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.axis_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -81,11 +81,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。
|
||||
<br>
|
||||
请确保填写数值能正确计算,否则将无法正常显示轴值。
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.axis_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -84,11 +84,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。
|
||||
<br>
|
||||
请确保填写数值能正确计算,否则将无法正常显示轴值。
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.axis_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -84,11 +84,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。
|
||||
<br>
|
||||
请确保填写数值能正确计算,否则将无法正常显示轴值。
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.axis_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -84,11 +84,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
最小值、最大值、间隔均为数值类型;若不填,则该项视为自动。
|
||||
<br>
|
||||
请确保填写数值能正确计算,否则将无法正常显示轴值。
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.axis_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -67,7 +67,8 @@ export default {
|
||||
min_height: 200,
|
||||
max_height: 500,
|
||||
elementpath: false,
|
||||
statusbar: false
|
||||
statusbar: false,
|
||||
convert_urls: false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div
|
||||
ref="tableContainer"
|
||||
:style="bg_class"
|
||||
style="padding: 8px;width: 100%;height: 100%;overflow: hidden;"
|
||||
style="padding: 4px;width: 100%;height: 100%;overflow: hidden;"
|
||||
>
|
||||
<span
|
||||
v-show="title_show"
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div
|
||||
ref="tableContainer"
|
||||
:style="bg_class"
|
||||
style="width: 100%;height: 100%;overflow: hidden;"
|
||||
style="padding: 4px;width: 100%;height: 100%;overflow: hidden;"
|
||||
>
|
||||
<view-track-bar
|
||||
ref="viewTrack"
|
||||
|
@ -56,7 +56,7 @@
|
||||
:id="scope.$index"
|
||||
v-model="keyWord"
|
||||
size="mini"
|
||||
placeholder="输入关键字搜索"
|
||||
:placeholder="$t('commons.search_keywords')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
明细表仅在分页模式为"下拉"时生效。
|
||||
{{ $t('chart.table_scroll_tip') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
|
@ -369,7 +369,7 @@ export default {
|
||||
const arr = this.thresholdForm.gaugeThreshold.split(',')
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const ele = arr[i]
|
||||
if (parseFloat(ele).toString() === 'NaN' || parseFloat(ele) < 1 || parseFloat(ele) > 99) {
|
||||
if (parseFloat(ele).toString() === 'NaN' || parseFloat(ele) <= 0 || parseFloat(ele) >= 100) {
|
||||
this.$message({
|
||||
message: this.$t('chart.gauge_threshold_format_error'),
|
||||
type: 'error',
|
||||
|
@ -164,7 +164,7 @@
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tip">提示:请勿重复选择字段,若同一字段重复配置,则只有最后的字段配置生效</div>
|
||||
<div class="tip">{{ $t('chart.table_threshold_tip') }}</div>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
|
@ -331,11 +331,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
列宽并非任何时候都能生效。
|
||||
<br>
|
||||
容器宽度优先级高于列宽,即(表格容器宽度 / 列数 > 指定列宽),则列宽优先取(容器宽度 / 列数)。
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.table_column_width_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;color: #606266;margin-left: 4px;"
|
||||
|
@ -87,21 +87,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
模板变量有 {a}, {b},{c},{d},分别表示系列名,数据名,数据值等。
|
||||
<br>
|
||||
在 触发位置 为 '坐标轴' 的时候,会有多个系列的数据,此时可以通过 {a0}, {a1}, {a2} 这种后面加索引的方式表示系列的索引。
|
||||
<br>
|
||||
不同图表类型下的 {a},{b},{c},{d} 含义不一样。 其中变量{a}, {b}, {c}, {d}在不同图表类型下代表数据含义为:
|
||||
<br><br>
|
||||
折线(区域)图、柱状(条形)图、仪表盘 : {a}(系列名称),{b}(类目值),{c}(数值)
|
||||
<br>
|
||||
饼图、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
|
||||
<br>
|
||||
地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)
|
||||
<br>
|
||||
散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.format_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -225,7 +225,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="false && chart.type === 'table-pivot'"
|
||||
v-if="chart.type === 'table-pivot'"
|
||||
:label="$t('chart.total_sort')"
|
||||
class="form-item"
|
||||
>
|
||||
@ -239,7 +239,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="false && chart.type === 'table-pivot' && totalForm.col.totalSort !== 'none'"
|
||||
v-if="chart.type === 'table-pivot' && totalForm.col.totalSort !== 'none'"
|
||||
:label="$t('chart.total_sort_field')"
|
||||
class="form-item"
|
||||
>
|
||||
|
@ -55,7 +55,7 @@
|
||||
>
|
||||
{{ $t('chart.total') }}
|
||||
<span>{{
|
||||
chart.datasetMode === 0 ? chart.totalItems : ((chart.data && chart.data.tableRow) ? chart.data.tableRow.length : 0)
|
||||
(chart.datasetMode === 0 && !not_support_page_dataset.includes(chart.datasourceType)) ? chart.totalItems : ((chart.data && chart.data.tableRow) ? chart.data.tableRow.length : 0)
|
||||
}}</span>
|
||||
{{ $t('chart.items') }}
|
||||
</span>
|
||||
@ -166,7 +166,8 @@ export default {
|
||||
scrollBarHoverColor: DEFAULT_COLOR_CASE.tableScrollBarHoverColor,
|
||||
totalStyle: {
|
||||
color: '#606266'
|
||||
}
|
||||
},
|
||||
not_support_page_dataset: NOT_SUPPORT_PAGE_DATASET
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -32,9 +32,9 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
表达式语法请遵循该数据源对应的数据库语法。
|
||||
{{ $t('dataset.calc_tips.tip1') }}
|
||||
<br>
|
||||
字段类型将使用原始类型,如有需要,请在表达式中自行转换。
|
||||
{{ $t('dataset.calc_tips.tip2') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
@ -112,11 +112,11 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
引用字段以 "[" 开始, "]" 结束
|
||||
{{ $t('dataset.calc_tips.tip3') }}
|
||||
<br>
|
||||
请勿修改引用内容,否则将引用失败
|
||||
{{ $t('dataset.calc_tips.tip4') }}
|
||||
<br>
|
||||
若输入与引用字段相同格式的内容,将被当作引用字段处理
|
||||
{{ $t('dataset.calc_tips.tip5') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
@ -239,11 +239,11 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
使用数据集对应数据库类型所支持的函数,语法同对应数据库
|
||||
{{ $t('dataset.calc_tips.tip6') }}
|
||||
<br>
|
||||
如日期格式化:MySQL使用DATE_FORMAT(date,format);Oracle使用TO_DATE(X,[,fmt])
|
||||
{{ $t('dataset.calc_tips.tip7') }}
|
||||
<br>
|
||||
非直连模式数据集,使用Doris数据库函数,可参考Doris官网 https://doris.apache.org/zh-CN/
|
||||
{{ $t('dataset.calc_tips.tip8') }} https://doris.apache.org/zh-CN/
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
|
@ -581,7 +581,7 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
该字段为必填项,且不应使用类别轴中字段,若无需该字段,请选择基础柱状图展示;否则展示结果不理想
|
||||
{{ $t('chart.sub_dimension_tip') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
@ -820,7 +820,7 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
该指标生效时,样式大小中的气泡大小属性将失效
|
||||
{{ $t('chart.scatter_tip') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
@ -914,7 +914,7 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
钻取字段仅支持数据集中的字段
|
||||
{{ $t('chart.drill_dimension_tip') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
@ -1084,7 +1084,7 @@
|
||||
>
|
||||
|
||||
<el-collapse-item
|
||||
title="地名映射"
|
||||
:title="$t('chart.place_name_mapping')"
|
||||
name="map-mapping"
|
||||
>
|
||||
<map-mapping
|
||||
|
@ -14,7 +14,9 @@
|
||||
v-model="styleInfo.top"
|
||||
type="number"
|
||||
:min="0"
|
||||
:max="maxTop"
|
||||
class="hide-icon-number"
|
||||
@change="topOnChange"
|
||||
>
|
||||
<template slot="append">px</template>
|
||||
</el-input>
|
||||
@ -44,8 +46,11 @@
|
||||
>
|
||||
<el-input
|
||||
v-model="styleInfo.width"
|
||||
:min="0"
|
||||
:max="maxWidth"
|
||||
type="number"
|
||||
class="hide-icon-number"
|
||||
@change="widthOnChange"
|
||||
>
|
||||
<template slot="append">px</template>
|
||||
</el-input>
|
||||
@ -59,7 +64,10 @@
|
||||
<el-input
|
||||
v-model="styleInfo.height"
|
||||
type="number"
|
||||
:min="0"
|
||||
:max="maxHeight"
|
||||
class="hide-icon-number"
|
||||
@change="heightOnChange"
|
||||
>
|
||||
<template slot="append">px</template>
|
||||
</el-input>
|
||||
@ -77,12 +85,18 @@ export default {
|
||||
name: 'PositionAdjust',
|
||||
props: {},
|
||||
data() {
|
||||
return {}
|
||||
return {
|
||||
maxHeight: 2000,
|
||||
maxTop: 40000
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
maxLeft() {
|
||||
return 1600 - this.styleInfo.width - this.componentGap
|
||||
},
|
||||
maxWidth() {
|
||||
return 1600 - this.styleInfo.left - this.componentGap
|
||||
},
|
||||
styleInfo() {
|
||||
return this.$store.state.curComponent.style
|
||||
},
|
||||
@ -97,7 +111,34 @@ export default {
|
||||
leftOnChange() {
|
||||
if (this.styleInfo.left > this.maxLeft) {
|
||||
this.styleInfo.left = this.maxLeft
|
||||
} else if (this.styleInfo.left < 0) {
|
||||
this.styleInfo.left = 0
|
||||
}
|
||||
this.$store.commit('canvasChange')
|
||||
},
|
||||
widthOnChange() {
|
||||
if (this.styleInfo.width > this.maxWidth) {
|
||||
this.styleInfo.width = this.maxWidth
|
||||
} else if (this.styleInfo.width < 0) {
|
||||
this.styleInfo.left = 0
|
||||
}
|
||||
this.$store.commit('canvasChange')
|
||||
},
|
||||
heightOnChange() {
|
||||
if (this.styleInfo.height > this.maxHeight) {
|
||||
this.styleInfo.height = this.maxHeight
|
||||
} else if (this.styleInfo.height < 0) {
|
||||
this.styleInfo.height = 0
|
||||
}
|
||||
this.$store.commit('canvasChange')
|
||||
},
|
||||
topOnChange() {
|
||||
if (this.styleInfo.top > this.maxTop) {
|
||||
this.styleInfo.top = this.maxTop
|
||||
} else if (this.styleInfo.top < 0) {
|
||||
this.styleInfo.top = 0
|
||||
}
|
||||
this.$store.commit('canvasChange')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
v-if="['db', 'excel', 'api'].includes(datasetType)"
|
||||
class="table-num"
|
||||
>{{ $t('deDataset.selected') }} {{ tableNum }}
|
||||
{{ ['excel'].includes(datasetType) ? $t('deDataset.table') : '项' }}</span>
|
||||
{{ ['excel'].includes(datasetType) ? $t('deDataset.table') : $t('deDataset.item') }}</span>
|
||||
<deBtn
|
||||
:disabled="['db', 'excel', 'api'].includes(datasetType) && !tableNum"
|
||||
type="primary"
|
||||
|
@ -29,9 +29,9 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
表达式语法请遵循该数据源对应的数据库语法。
|
||||
{{ $t('dataset.calc_tips.tip1') }}
|
||||
<br>
|
||||
数据集中不支持聚合运算。
|
||||
{{ $t('dataset.calc_tips.tip2') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
@ -90,11 +90,11 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
引用字段以 "[" 开始, "]" 结束
|
||||
{{ $t('dataset.calc_tips.tip3') }}
|
||||
<br>
|
||||
请勿修改引用内容,否则将引用失败
|
||||
{{ $t('dataset.calc_tips.tip4') }}
|
||||
<br>
|
||||
若输入与引用字段相同格式的内容,将被当作引用字段处理
|
||||
{{ $t('dataset.calc_tips.tip5') }}
|
||||
</div>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
@ -214,11 +214,11 @@
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
使用数据集对应数据库类型所支持的函数,语法同对应数据库
|
||||
{{ $t('dataset.calc_tips.tip6') }}
|
||||
<br>
|
||||
如日期格式化:MySQL使用DATE_FORMAT(date,format);Oracle使用TO_DATE(X,[,fmt])
|
||||
{{ $t('dataset.calc_tips.tip7') }}
|
||||
<br>
|
||||
非直连模式数据集,使用Doris数据库函数,可参考Doris官网
|
||||
{{ $t('dataset.calc_tips.tip8') }}
|
||||
https://doris.apache.org/zh-CN/
|
||||
</div>
|
||||
<i
|
||||
|
@ -859,6 +859,9 @@ export default {
|
||||
if (item.dateFormatType !== 'custom') {
|
||||
item.dateFormat = item.dateFormatType
|
||||
}
|
||||
} else {
|
||||
item.dateFormatType = ''
|
||||
item.dateFormat = ''
|
||||
}
|
||||
if (item.dateFormatType === 'custom' && !item.dateFormat) {
|
||||
return
|
||||
|
@ -398,11 +398,11 @@ export default {
|
||||
this.filterList = [
|
||||
{
|
||||
value: 'logic',
|
||||
label: '条件筛选'
|
||||
label: this.$t('deDataset.logic_filter')
|
||||
},
|
||||
{
|
||||
value: 'enum',
|
||||
label: '枚举筛选'
|
||||
label: this.$t('deDataset.enum_filter')
|
||||
}
|
||||
]
|
||||
if ([1, 2, 3].includes(deType)) {
|
||||
|
@ -44,7 +44,7 @@
|
||||
<el-date-picker
|
||||
v-model="form.overTime"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
:placeholder="$t('commons.date.select_date_time')"
|
||||
align="right"
|
||||
value-format="timestamp"
|
||||
:picker-options="pickerOptions"
|
||||
@ -148,17 +148,17 @@ export default {
|
||||
},
|
||||
|
||||
shortcuts: [{
|
||||
text: '一天',
|
||||
text: this.$t('commons.date.one_day'),
|
||||
onClick: function(picker) {
|
||||
picker.$emit('pick', this.limitDate('day'))
|
||||
}.bind(this)
|
||||
}, {
|
||||
text: '一周',
|
||||
text: this.$t('commons.date.one_week'),
|
||||
onClick: (picker) => {
|
||||
picker.$emit('pick', this.limitDate('week'))
|
||||
}
|
||||
}, {
|
||||
text: '一月',
|
||||
text: this.$t('commons.date.one_month'),
|
||||
onClick: (picker) => {
|
||||
picker.$emit('pick', this.limitDate('month'))
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<el-row class="component-wait">
|
||||
<el-tabs
|
||||
class="wait-tab"
|
||||
v-model="activeName"
|
||||
style="padding-left: 10px"
|
||||
>
|
||||
@ -36,7 +37,7 @@
|
||||
class="component-wait-main"
|
||||
style="padding:10px"
|
||||
>
|
||||
<mobile-background-selector />
|
||||
<mobile-background-selector/>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -141,7 +142,8 @@ export default {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs--top {
|
||||
|
||||
.wait-tab {
|
||||
height: 40px !important;
|
||||
background-color: #9ea6b2;
|
||||
}
|
||||
|
@ -292,7 +292,9 @@
|
||||
v-else
|
||||
class="view-selected-message-class"
|
||||
>
|
||||
<span style="font-size: 14px;margin-left: 10px;font-weight: bold;line-height: 20px">{{ $t('panel.select_view') }}</span>
|
||||
<span style="font-size: 14px;margin-left: 10px;font-weight: bold;line-height: 20px">
|
||||
{{ $t('panel.select_view') }}
|
||||
</span>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -452,7 +454,9 @@
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="21">
|
||||
<span style="font-size: 13px;margin-left: 10px;font-weight: bold;line-height: 20px">{{ $t('panel.panel_cache_use_tips') }}</span>
|
||||
<span style="font-size: 13px;margin-left: 10px;font-weight: bold;line-height: 20px">
|
||||
{{ $t('panel.panel_cache_use_tips') }}
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div
|
||||
@ -651,7 +655,7 @@ export default {
|
||||
},
|
||||
// 显示视图工具栏
|
||||
showViewToolsAside() {
|
||||
return !this.batchOptStatus && this.curComponent && (this.curComponent.type === 'view' || this.curComponent.type === 'de-tabs')
|
||||
return !this.batchOptStatus && this.curComponent && (this.curComponent.type === 'view' || (this.curComponent.type === 'de-tabs' && this.$store.state.chart.viewId))
|
||||
},
|
||||
showBatchViewToolsAside() {
|
||||
return this.batchOptStatus
|
||||
@ -966,11 +970,10 @@ export default {
|
||||
if (this.showIndex === -1 || this.showIndex === type) {
|
||||
this.$nextTick(() => {
|
||||
if (this.show) {
|
||||
this.showIndex === -1
|
||||
this.showIndex = -1
|
||||
}
|
||||
this.show = !this.show
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
this.showIndex = type
|
||||
},
|
||||
@ -1376,6 +1379,7 @@ export default {
|
||||
this.$store.commit('setComponentWithId', this.currentFilterCom)
|
||||
this.$store.commit('recordSnapshot', 'sureFilter')
|
||||
this.$store.commit('setCurComponent', { component: this.currentFilterCom, index: this.curComponentIndex })
|
||||
this.$store.commit('setComponentFromList', this.currentFilterCom)
|
||||
bus.$emit('refresh-button-info')
|
||||
this.closeButton()
|
||||
},
|
||||
|
@ -23,12 +23,14 @@
|
||||
<el-button
|
||||
size="mini"
|
||||
@click="cancel()"
|
||||
>{{ $t('commons.cancel') }}</el-button>
|
||||
>{{ $t('commons.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="save()"
|
||||
>{{ $t('panel.export_pdf') }}</el-button>
|
||||
>{{ $t('panel.export_pdf') }}
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -41,7 +43,7 @@ import { pdfTemplateReplaceAll } from '@/utils/StringUtils.js'
|
||||
|
||||
export default {
|
||||
name: 'PDFPreExport',
|
||||
components: { },
|
||||
components: {},
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
panelName: {
|
||||
@ -132,36 +134,35 @@ export default {
|
||||
setTimeout(() => {
|
||||
html2canvas(document.getElementById('exportPdf')).then(function(canvas) {
|
||||
_this.exportLoading = false
|
||||
const contentWidth = canvas.width
|
||||
const contentHeight = canvas.height
|
||||
const contentWidth = canvas.width / 4
|
||||
const contentHeight = canvas.height / 4
|
||||
const pageData = canvas.toDataURL('image/jpeg', 1.0)
|
||||
const lp = contentWidth > contentHeight ? 'l' : 'p'
|
||||
const PDF = new JsPDF(lp, 'pt', [contentWidth, contentHeight])
|
||||
PDF.addImage(pageData, 'JPEG', 0, 0, contentWidth, contentHeight)
|
||||
PDF.save(_this.panelName + '.pdf')
|
||||
_this.$emit('closePreExport')
|
||||
}
|
||||
)
|
||||
})
|
||||
}, 1500)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.root_class {
|
||||
margin: 15px 0px 5px;
|
||||
text-align: center;
|
||||
}
|
||||
.export_body_class{
|
||||
border: 1px solid #dcdfe6 ;
|
||||
height: 65vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.root_class {
|
||||
margin: 15px 0px 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.export_body_inner_class{
|
||||
margin: 10px;
|
||||
}
|
||||
.export_body_class {
|
||||
border: 1px solid #dcdfe6;
|
||||
height: 65vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.export_body_inner_class {
|
||||
margin: 10px;
|
||||
}
|
||||
</style>
|
||||
|
@ -283,13 +283,10 @@
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<div slot="content">
|
||||
引用字段以 "[" 开始, "]" 结束
|
||||
<br>
|
||||
请勿修改引用内容,否则将引用失败
|
||||
<br>
|
||||
若输入与引用字段相同格式的内容,将被当作引用字段处理
|
||||
</div>
|
||||
<div
|
||||
slot="content"
|
||||
v-html="$t('chart.reference_field_tip')"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-info"
|
||||
style="cursor: pointer;"
|
||||
|
@ -69,7 +69,7 @@
|
||||
</span>
|
||||
<span
|
||||
v-if="hasDataPermission('manage', data.privileges)"
|
||||
:title="'置顶'"
|
||||
:title="$t('panel.to_top')"
|
||||
class="child"
|
||||
@click.stop
|
||||
>
|
||||
@ -121,7 +121,7 @@
|
||||
class="default-expansion"
|
||||
@click="defaultExpansion = !defaultExpansion"
|
||||
>
|
||||
{{ defaultExpansion ? '收起' : '展开' }}
|
||||
{{ defaultExpansion ? $t('panel.fold') : $t('panel.expand') }}
|
||||
<i
|
||||
:class="[
|
||||
defaultExpansion ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
|
||||
@ -373,7 +373,7 @@
|
||||
|
||||
<el-dialog
|
||||
v-dialogDrag
|
||||
:title="linkTitle"
|
||||
:title="$t('panel.link_share')"
|
||||
:visible.sync="linkVisible"
|
||||
width="500px"
|
||||
@closed="removeLink"
|
||||
@ -512,7 +512,6 @@ export default {
|
||||
node: {},
|
||||
optType: 'newFirstFolder'
|
||||
},
|
||||
linkTitle: '链接分享',
|
||||
linkVisible: false,
|
||||
linkResourceId: null,
|
||||
authTitle: null,
|
||||
|
@ -235,7 +235,7 @@
|
||||
|
||||
<el-dialog
|
||||
v-if="templateSaveShow"
|
||||
:title="templateSaveTitle"
|
||||
:title="$t('panel.save_to_panel')"
|
||||
:visible.sync="templateSaveShow"
|
||||
width="500px"
|
||||
>
|
||||
@ -246,7 +246,7 @@
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-if="pdfExportShow"
|
||||
:title="'['+panelInfo.name+']'+'PDF导出'"
|
||||
:title="'['+panelInfo.name+']'+$t('panel.pdf_export')"
|
||||
:visible.sync="pdfExportShow"
|
||||
width="80%"
|
||||
:top="'8vh'"
|
||||
@ -260,7 +260,7 @@
|
||||
/>
|
||||
<el-select
|
||||
v-model="pdfTemplateSelectedIndex"
|
||||
:placeholder="'切换PDF模板'"
|
||||
:placeholder="$t('panel.switch_pdf_template')"
|
||||
@change="changePdfTemplate()"
|
||||
>
|
||||
<el-option
|
||||
@ -295,7 +295,7 @@
|
||||
/>
|
||||
<el-select
|
||||
v-model="pdfTemplateSelectedIndex"
|
||||
:placeholder="'切换PDF模板'"
|
||||
:placeholder="$t('panel.switch_pdf_template')"
|
||||
@change="changePdfTemplate()"
|
||||
>
|
||||
<el-option
|
||||
@ -359,7 +359,6 @@ export default {
|
||||
pdfTemplateContent: '',
|
||||
templateInfo: {},
|
||||
pdfTemplateAll: [],
|
||||
templateSaveTitle: '保存为模板',
|
||||
templateSaveShow: false,
|
||||
hasStar: false,
|
||||
fullscreen: false,
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div style="width: 100%">
|
||||
<el-row>
|
||||
<el-col class="custom-item el-form-item">
|
||||
<el-row type="flex">
|
||||
<el-col class="el-form-item">
|
||||
<el-checkbox
|
||||
v-model="componentStyleForm.backgroundColorSelect"
|
||||
style="margin-right: 10px;float: right"
|
||||
@ -10,7 +10,7 @@
|
||||
<span style="font-size: 12px">{{ $t('chart.chart_background') }}</span>
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col>
|
||||
<el-color-picker
|
||||
v-model="componentStyleForm.color"
|
||||
:disabled="!componentStyleForm.backgroundColorSelect"
|
||||
|
@ -81,7 +81,7 @@
|
||||
:placeholder="$t('system_parameter_setting.SMTP_password')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('system_parameter_setting.test_recipients')">
|
||||
<el-form-item :label="$t('ç.test_recipients')">
|
||||
<template slot="label">
|
||||
{{ $t("system_parameter_setting.test_recipients") }}
|
||||
<el-tooltip
|
||||
@ -98,7 +98,7 @@
|
||||
:placeholder="$t('system_parameter_setting.test_recipients')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱服务器配置">
|
||||
<el-form-item :label="$t('system_parameter_setting.email_server_config')">
|
||||
<el-checkbox v-model="formInline.ssl">{{ $t('chart.open') }}SSL
|
||||
<el-tooltip
|
||||
class="item"
|
||||
|
@ -109,18 +109,18 @@
|
||||
|
||||
<!--提供修改个人电话,邮箱和昵称的功能-->
|
||||
<el-form-item v-if="formType!=='modify'">
|
||||
<el-button @click="formType = 'modify'">修改个人信息</el-button>
|
||||
<el-button @click="formType = 'modify'">{{ $t('member.modify_personal_info') }}</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item v-else>
|
||||
<el-button
|
||||
v-if="formType==='modify'"
|
||||
type="primary"
|
||||
@click="save"
|
||||
>保存</el-button>
|
||||
>{{ $t('commons.save') }}</el-button>
|
||||
<el-button
|
||||
v-if="formType==='modify'"
|
||||
@click="reset"
|
||||
>取消</el-button>
|
||||
>{{ $t('commons.cancel') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dataease-mobile",
|
||||
"version": "1.17.0",
|
||||
"version": "1.18.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "npm run dev:h5",
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>dataease-server</artifactId>
|
||||
<groupId>io.dataease</groupId>
|
||||
<version>1.17.0</version>
|
||||
<version>1.18.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -61,5 +61,5 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
|
6
pom.xml
6
pom.xml
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dataease-server</artifactId>
|
||||
<version>1.17.0</version>
|
||||
<version>1.18.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
@ -16,7 +16,7 @@
|
||||
</parent>
|
||||
|
||||
<name>dataease</name>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>frontend</module>
|
||||
<module>mobile</module>
|
||||
|
Loading…
Reference in New Issue
Block a user