forked from github/dataease
refactor: 解决冲突
This commit is contained in:
commit
6c9191e9bd
72
.github/workflows/codeql-analysis.yml
vendored
Normal file
72
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "dev" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "dev" ]
|
||||
schedule:
|
||||
- cron: '36 10 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'java', 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
@ -90,6 +90,10 @@ curl -sSL https://github.com/dataease/dataease/releases/latest/download/quick_st
|
||||
- 数据处理:[Kettle](https://github.com/pentaho/pentaho-kettle)、[Apache Doris](https://github.com/apache/incubator-doris/)
|
||||
- 基础设施:[Docker](https://www.docker.com/)
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#dataease/dataease&Date)
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2014-2022 飞致云 FIT2CLOUD, All rights reserved.
|
||||
|
@ -18,6 +18,9 @@
|
||||
<java.version>1.8</java.version>
|
||||
<graalvm.version>20.1.0</graalvm.version>
|
||||
<jwt.version>3.12.1</jwt.version>
|
||||
|
||||
<buji.version>4.0.0</buji.version>
|
||||
<pac4j.version>3.3.0</pac4j.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -36,12 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<!--<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>-->
|
||||
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -89,11 +87,7 @@
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>-->
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -122,7 +116,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring-boot-starter</artifactId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -236,8 +230,7 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--由于暂时插件接口未注册到公司仓库,请先down下代码安装到本地仓库
|
||||
https://github.com/dataease/dataease-plugins-->
|
||||
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dataease-plugin-interface</artifactId>
|
||||
@ -336,7 +329,6 @@
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.jsqlparser</groupId>
|
||||
<artifactId>jsqlparser</artifactId>
|
||||
@ -356,9 +348,7 @@
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<!-- <includes>
|
||||
<include>**/*</include>
|
||||
</includes> -->
|
||||
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>static/**/*.woff</exclude>
|
||||
|
@ -14,6 +14,7 @@ import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
@ -24,14 +25,13 @@ import java.util.stream.Collectors;
|
||||
public class DePermissionAnnotationHandler {
|
||||
|
||||
@Around(value = "@annotation(io.dataease.auth.annotation.DePermissions)")
|
||||
public Object PermissionsAround(ProceedingJoinPoint point) throws Throwable{
|
||||
public Object PermissionsAround(ProceedingJoinPoint point) throws Throwable {
|
||||
|
||||
if (AuthUtils.getUser().getIsAdmin()) {
|
||||
return point.proceed(point.getArgs());
|
||||
}
|
||||
Boolean access = false;
|
||||
try {
|
||||
|
||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
||||
Method method = ms.getMethod();
|
||||
DePermissions annotation = method.getAnnotation(DePermissions.class);
|
||||
@ -66,17 +66,15 @@ public class DePermissionAnnotationHandler {
|
||||
throw exceptions.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
LogUtil.error(throwable.getMessage(), throwable);
|
||||
throw new RuntimeException(throwable.getMessage());
|
||||
}
|
||||
|
||||
return access ? point.proceed(point.getArgs()) : null;
|
||||
}
|
||||
|
||||
@Around(value = "@annotation(io.dataease.auth.annotation.DePermission)")
|
||||
public Object PermissionAround(ProceedingJoinPoint point) throws Throwable{
|
||||
public Object PermissionAround(ProceedingJoinPoint point) throws Throwable {
|
||||
Boolean access = false;
|
||||
try {
|
||||
if (AuthUtils.getUser().getIsAdmin()) {
|
||||
@ -84,7 +82,6 @@ public class DePermissionAnnotationHandler {
|
||||
}
|
||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
||||
Method method = ms.getMethod();
|
||||
|
||||
DePermission annotation = method.getAnnotation(DePermission.class);
|
||||
Object arg = point.getArgs()[annotation.paramIndex()];
|
||||
if (access(arg, annotation, 0)) {
|
||||
@ -94,7 +91,6 @@ public class DePermissionAnnotationHandler {
|
||||
LogUtil.error(throwable.getMessage(), throwable);
|
||||
throw new RuntimeException(throwable.getMessage());
|
||||
}
|
||||
|
||||
return access ? point.proceed(point.getArgs()) : null;
|
||||
}
|
||||
|
||||
@ -104,10 +100,8 @@ public class DePermissionAnnotationHandler {
|
||||
String type = annotation.type().name().toLowerCase();
|
||||
String value = annotation.value();
|
||||
Integer requireLevel = annotation.level().getLevel();
|
||||
|
||||
Set<String> resourceIds = AuthUtils.permissionByType(type).stream().filter(
|
||||
item -> item.getLevel() >= requireLevel).map(AuthItem::getAuthSource).collect(Collectors.toSet());
|
||||
|
||||
Class<?> parameterType = arg.getClass();
|
||||
if (parameterType.isPrimitive() || ReflectUtil.isWrapClass(parameterType) || ReflectUtil.isString(parameterType)) {
|
||||
boolean permissionValid = resourceIds.contains(arg);
|
||||
@ -122,7 +116,6 @@ public class DePermissionAnnotationHandler {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (ReflectUtil.isCollection(parameterType)) {
|
||||
Object[] array = ((Collection) arg).toArray();
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
@ -140,14 +133,10 @@ public class DePermissionAnnotationHandler {
|
||||
// 当作自定义类处理
|
||||
String[] values = value.split("\\.");
|
||||
String fieldName = values[layer];
|
||||
|
||||
Object fieldValue = ReflectUtil.getFieldValue(arg, fieldName);
|
||||
return access(fieldValue, annotation, ++layer);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -35,21 +35,13 @@ public class DePermissionProxyHandler {
|
||||
Object[] args = point.getArgs();
|
||||
if (null == args || args.length == 0) {
|
||||
return point.proceed(args);
|
||||
|
||||
}
|
||||
Object arg = point.getArgs()[annotation.paramIndex()];
|
||||
/*
|
||||
* if (arg instanceof PermissionProxy) {
|
||||
* PermissionProxy proxy = (PermissionProxy) arg;
|
||||
* AuthUtils.setProxyUser(proxy.getUserId());
|
||||
* }
|
||||
*/
|
||||
PermissionProxy proxy = getProxy(arg, annotation, 0);
|
||||
if (null != proxy && null != proxy.getUserId()) {
|
||||
AuthUtils.setProxyUser(proxy.getUserId());
|
||||
}
|
||||
return point.proceed(args);
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
LogUtil.error(throwable.getMessage(), throwable);
|
||||
/* throw new RuntimeException(throwable.getMessage()); */
|
||||
@ -69,26 +61,8 @@ public class DePermissionProxyHandler {
|
||||
if (arg instanceof PermissionProxy) {
|
||||
return (PermissionProxy) arg;
|
||||
} else if (isArray(parameterType)) {
|
||||
/*
|
||||
* for (int i = 0; i < Array.getLength(arg); i++) {
|
||||
* Object o = Array.get(arg, i);
|
||||
* if ((result = getProxy(o, annotation, layer)) != null) {
|
||||
* return result;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
return null;
|
||||
|
||||
} else if (isCollection(parameterType)) {
|
||||
/*
|
||||
* Object[] array = ((Collection) arg).toArray();
|
||||
* for (int i = 0; i < array.length; i++) {
|
||||
* Object o = array[i];
|
||||
* if ((result = getProxy(o, annotation, layer)) != null) {
|
||||
* return result;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
return null;
|
||||
} else if (isMap(parameterType)) {
|
||||
Map<String, Object> argMap = (Map) arg;
|
||||
@ -99,10 +73,8 @@ public class DePermissionProxyHandler {
|
||||
// 当作自定义类处理
|
||||
String[] values = value.split("\\.");
|
||||
String fieldName = values[layer];
|
||||
|
||||
Object fieldValue = getFieldValue(arg, fieldName);
|
||||
return getProxy(fieldValue, annotation, ++layer);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,6 +38,10 @@ public interface AuthApi {
|
||||
@PostMapping("/logout")
|
||||
String logout();
|
||||
|
||||
@ApiIgnore
|
||||
@PostMapping("/deLogout")
|
||||
String deLogout();
|
||||
|
||||
@ApiOperation("验证账号")
|
||||
@PostMapping("/validateName")
|
||||
Boolean validateName(Map<String, String> nameDto);
|
||||
@ -50,6 +54,10 @@ public interface AuthApi {
|
||||
@PostMapping("/isOpenOidc")
|
||||
boolean isOpenOidc();
|
||||
|
||||
@ApiOperation("是否开启cas")
|
||||
@PostMapping("/isOpenCas")
|
||||
boolean isOpenCas();
|
||||
|
||||
@ApiIgnore
|
||||
@PostMapping("/isPluginLoaded")
|
||||
boolean isPluginLoaded();
|
||||
|
@ -0,0 +1,60 @@
|
||||
package io.dataease.auth.config.cas;
|
||||
|
||||
import io.dataease.auth.service.impl.ShiroServiceImpl;
|
||||
import io.dataease.commons.utils.CommonBeanFactory;
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.util.AntPathMatcher;
|
||||
import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
public class CasStrategy implements UrlPatternMatcherStrategy {
|
||||
|
||||
|
||||
private static Set<String> releaseTypes = new HashSet<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
releaseTypes.add("anon");
|
||||
releaseTypes.add("link");
|
||||
releaseTypes.add("doc");
|
||||
}
|
||||
@Override
|
||||
public boolean matches(String s) {
|
||||
SystemParameterService service = CommonBeanFactory.getBean(SystemParameterService.class);
|
||||
String serviceValue = service.getValue("cas.callBack");
|
||||
if (StringUtils.isBlank(serviceValue)) return false;
|
||||
String serverName = serviceValue.substring(0, serviceValue.indexOf("/cas/callBack"));
|
||||
int beginIndex = -1;
|
||||
if ((beginIndex = s.indexOf(serverName)) != -1) {
|
||||
s = s.substring(beginIndex + serverName.length());
|
||||
}
|
||||
if (StringUtils.equals("/", s)) return false;
|
||||
if (StringUtils.equals("/login", s)) return false;
|
||||
if (StringUtils.startsWith(s, "/cas/callBack")) return false;
|
||||
if (StringUtils.equals("/api/auth/deLogout", s)) return true;
|
||||
AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||
ShiroServiceImpl shiroService = CommonBeanFactory.getBean(ShiroServiceImpl.class);
|
||||
Map<String, String> stringStringMap = shiroService.loadFilterChainDefinitionMap();
|
||||
for (Map.Entry<String, String> entry : stringStringMap.entrySet()) {
|
||||
if (releaseTypes.contains(entry.getValue())) {
|
||||
boolean matches = antPathMatcher.matches(entry.getKey(), s);
|
||||
if (matches) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPattern(String s) {
|
||||
|
||||
}
|
||||
}
|
@ -17,12 +17,14 @@ import io.dataease.i18n.Translator;
|
||||
import io.dataease.plugins.common.entity.XpackLdapUserEntity;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.util.PluginUtils;
|
||||
import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
||||
import io.dataease.plugins.xpack.ldap.dto.request.LdapValidateRequest;
|
||||
import io.dataease.plugins.xpack.ldap.dto.response.ValidateResult;
|
||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
import io.dataease.service.sys.SysUserService;
|
||||
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
@ -36,7 +38,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@RestController
|
||||
public class AuthServer implements AuthApi {
|
||||
@ -50,6 +54,9 @@ public class AuthServer implements AuthApi {
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Resource
|
||||
private SystemParameterService systemParameterService;
|
||||
|
||||
@Override
|
||||
public Object login(@RequestBody LoginDto loginDto) throws Exception {
|
||||
String username = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, loginDto.getUsername());
|
||||
@ -159,6 +166,37 @@ public class AuthServer implements AuthApi {
|
||||
return DEFAULT_PWD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deLogout() {
|
||||
String token = ServletUtils.getToken();
|
||||
if (StringUtils.isEmpty(token) || StringUtils.equals("null", token) || StringUtils.equals("undefined", token)) {
|
||||
return "success";
|
||||
}
|
||||
SecurityUtils.getSubject().logout();
|
||||
String result = null;
|
||||
Integer defaultLoginType = systemParameterService.defaultLoginType();
|
||||
if (defaultLoginType == 3 && isOpenCas()) {
|
||||
HttpServletRequest request = ServletUtils.request();
|
||||
HttpSession session = request.getSession();
|
||||
session.invalidate();
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
result = casXpackService.logout();
|
||||
}
|
||||
try {
|
||||
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
|
||||
authUserService.clearCache(userId);
|
||||
if (StringUtils.isBlank(result)) {
|
||||
result = "success";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
if (StringUtils.isBlank(result)) {
|
||||
result = "fail";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String logout() {
|
||||
String token = ServletUtils.getToken();
|
||||
@ -170,20 +208,36 @@ public class AuthServer implements AuthApi {
|
||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
||||
oidcXpackService.logout(idToken);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(token) || StringUtils.equals("null", token) || StringUtils.equals("undefined", token)) {
|
||||
return "success";
|
||||
}
|
||||
|
||||
SecurityUtils.getSubject().logout();
|
||||
String result = null;
|
||||
Integer defaultLoginType = systemParameterService.defaultLoginType();
|
||||
if (defaultLoginType == 3 && isOpenCas()) {
|
||||
HttpServletRequest request = ServletUtils.request();
|
||||
HttpSession session = request.getSession();
|
||||
session.invalidate();
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
result = casXpackService.logout();
|
||||
}
|
||||
try {
|
||||
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
|
||||
|
||||
authUserService.clearCache(userId);
|
||||
if (StringUtils.isBlank(result)) {
|
||||
result = "success";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
return "fail";
|
||||
if (StringUtils.isBlank(result)) {
|
||||
result = "fail";
|
||||
}
|
||||
}
|
||||
|
||||
return "success";
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -211,6 +265,17 @@ public class AuthServer implements AuthApi {
|
||||
return authUserService.supportOidc();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isOpenCas() {
|
||||
Boolean licValid = PluginUtils.licValid();
|
||||
if (!licValid)
|
||||
return false;
|
||||
Boolean supportCas = authUserService.supportCas();
|
||||
|
||||
return authUserService.supportCas();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPluginLoaded() {
|
||||
Boolean licValid = PluginUtils.licValid();
|
||||
|
@ -14,6 +14,8 @@ public interface AuthUserService {
|
||||
|
||||
SysUserEntity getLdapUserByName(String username);
|
||||
|
||||
SysUserEntity getCasUserByName(String username);
|
||||
|
||||
SysUserEntity getUserBySub(String sub);
|
||||
|
||||
List<String> roles(Long userId);
|
||||
@ -28,6 +30,8 @@ public interface AuthUserService {
|
||||
|
||||
Boolean supportOidc();
|
||||
|
||||
Boolean supportCas();
|
||||
|
||||
Boolean pluginLoaded();
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@ import io.dataease.plugins.common.base.domain.SysUser;
|
||||
import io.dataease.plugins.common.base.mapper.SysUserMapper;
|
||||
import io.dataease.plugins.common.service.PluginCommonService;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
|
||||
@ -65,6 +66,11 @@ public class AuthUserServiceImpl implements AuthUserService {
|
||||
return authMapper.findLdapUserByName(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUserEntity getCasUserByName(String username) {
|
||||
return authMapper.findCasUserByName(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUserEntity getUserBySub(String sub) {
|
||||
return authMapper.findUserBySub(sub);
|
||||
@ -147,6 +153,15 @@ public class AuthUserServiceImpl implements AuthUserService {
|
||||
return oidcXpackService.isSuuportOIDC();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean supportCas() {
|
||||
Map<String, CasXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((CasXpackService.class));
|
||||
if (beansOfType.keySet().size() == 0) return false;
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
if (ObjectUtils.isEmpty(casXpackService)) return false;
|
||||
return casXpackService.suuportCas();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean pluginLoaded() {
|
||||
Map<String, PluginCommonService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((PluginCommonService.class));
|
||||
|
@ -84,6 +84,8 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
filterChainDefinitionMap.put("/api/pluginCommon/staticInfo/**", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/oidc/authInfo", ANON);
|
||||
filterChainDefinitionMap.put("/sso/callBack*", ANON);
|
||||
filterChainDefinitionMap.put("/cas/callBack*", ANON);
|
||||
filterChainDefinitionMap.put("/cas/reset", ANON);
|
||||
|
||||
filterChainDefinitionMap.put("/unauth", ANON);
|
||||
filterChainDefinitionMap.put("/display/**", ANON);
|
||||
@ -91,7 +93,6 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
filterChainDefinitionMap.put("/downline", ANON);
|
||||
filterChainDefinitionMap.put("/common-files/**", ANON);
|
||||
filterChainDefinitionMap.put("/linkage/getPanelAllLinkageInfo/**", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/logout", "logout");
|
||||
|
||||
filterChainDefinitionMap.put("/api/link/resourceDetail/**", "link");
|
||||
filterChainDefinitionMap.put("/api/link/viewDetail/**", "link");
|
||||
|
@ -1,8 +1,12 @@
|
||||
package io.dataease.commons.filter;
|
||||
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.holder.ThreadLocalContextHolder;
|
||||
import io.dataease.commons.wrapper.XssAndSqlHttpServletRequestWrapper;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@ -15,13 +19,14 @@ public class SqlFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
if (ObjectUtils.isEmpty(RequestContextHolder.getRequestAttributes())) {
|
||||
ServletRequestAttributes attributes = new ServletRequestAttributes((HttpServletRequest) request);
|
||||
RequestContextHolder.setRequestAttributes(attributes);
|
||||
}
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
if ("TRACE".equalsIgnoreCase(httpRequest.getMethod()) || "TRACK".equalsIgnoreCase(httpRequest.getMethod())) {
|
||||
@ -42,9 +47,8 @@ public class SqlFilter implements Filter {
|
||||
if (xssRequest.checkXSSAndSql(param)) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
String msg = ThreadLocalContextHolder.getData().toString();
|
||||
out.write(msg);
|
||||
DEException.throwException(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -52,9 +56,8 @@ public class SqlFilter implements Filter {
|
||||
if (xssRequest.checkParameter()) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
String msg = ThreadLocalContextHolder.getData().toString();
|
||||
out.write(msg);
|
||||
DEException.throwException(msg);
|
||||
return;
|
||||
}
|
||||
chain.doFilter(xssRequest, response);
|
||||
|
@ -243,22 +243,12 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
||||
ThreadLocalContextHolder.setData("包含SQL注入的参数,请检查参数!");
|
||||
return true;
|
||||
}
|
||||
// NOTE: It's highly recommended to use the ESAPI library and
|
||||
// uncomment the following line to
|
||||
// avoid encoded attacks.
|
||||
// value = ESAPI.encoder().canonicalize(value);
|
||||
// Avoid null characters
|
||||
/** value = value.replaceAll("", ""); ***/
|
||||
// Avoid anything between script tags
|
||||
Pattern scriptPattern = Pattern.compile(
|
||||
"<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
|
||||
flag = scriptPattern.matcher(value).find();
|
||||
if (flag) {
|
||||
return flag;
|
||||
}
|
||||
// Avoid anything in a
|
||||
// src="http://www.yihaomen.com/article/java/..." type of
|
||||
// e-xpression
|
||||
scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
|
||||
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
||||
flag = scriptPattern.matcher(value).find();
|
||||
|
@ -0,0 +1,86 @@
|
||||
package io.dataease.controller.chart;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.auth.annotation.DePermission;
|
||||
import io.dataease.commons.constants.DePermissionType;
|
||||
import io.dataease.commons.constants.ResourceAuthLevel;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.controller.request.dataset.DataSetTableRequest;
|
||||
import io.dataease.controller.response.ChartViewField4Type;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.plugins.common.base.domain.ChartViewField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTable;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.service.chart.ChartViewFieldService;
|
||||
import io.dataease.service.dataset.DataSetTableService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author gin
|
||||
*/
|
||||
@Api(tags = "视图:字段")
|
||||
@ApiSupport(order = 130)
|
||||
@RestController
|
||||
@RequestMapping("/chart/field")
|
||||
public class ChartViewFieldController {
|
||||
@Resource
|
||||
private ChartViewFieldService chartViewFieldService;
|
||||
@Resource
|
||||
private DataSetTableService dataSetTableService;
|
||||
|
||||
@DePermission(type = DePermissionType.PANEL, level = ResourceAuthLevel.PANNEL_LEVEL_MANAGE)
|
||||
@ApiOperation("保存")
|
||||
@PostMapping("/save/{panelId}")
|
||||
public ChartViewField save(@PathVariable String panelId, @RequestBody ChartViewField chartViewField) {
|
||||
try {
|
||||
// 执行一次sql,确保数据集中所有字段均能正确执行
|
||||
DatasetTable datasetTable = dataSetTableService.get(chartViewField.getTableId());
|
||||
DataSetTableRequest dataSetTableRequest = new DataSetTableRequest();
|
||||
BeanUtils.copyProperties(datasetTable, dataSetTableRequest);
|
||||
DatasetTableField datasetTableField = new DatasetTableField();
|
||||
BeanUtils.copyProperties(chartViewField, datasetTableField);
|
||||
dataSetTableService.getPreviewData(dataSetTableRequest, 1, 1, Collections.singletonList(datasetTableField));
|
||||
} catch (Exception e) {
|
||||
DEException.throwException(Translator.get("i18n_calc_field_error"));
|
||||
}
|
||||
return chartViewFieldService.save(chartViewField);
|
||||
}
|
||||
|
||||
@DePermission(type = DePermissionType.PANEL, level = ResourceAuthLevel.PANNEL_LEVEL_MANAGE, paramIndex = 1)
|
||||
@ApiOperation("删除")
|
||||
@PostMapping("/delete/{id}/{panelId}")
|
||||
public void delete(@PathVariable String id, @PathVariable String panelId) {
|
||||
chartViewFieldService.delete(id);
|
||||
}
|
||||
|
||||
@DePermission(type = DePermissionType.PANEL, level = ResourceAuthLevel.PANNEL_LEVEL_MANAGE, paramIndex = 1)
|
||||
@ApiOperation("删除视图的字段")
|
||||
@PostMapping("/deleteByChartId/{chartId}/{panelId}")
|
||||
public void deleteByChartId(@PathVariable String chartId, @PathVariable String panelId) {
|
||||
chartViewFieldService.deleteByChartId(chartId);
|
||||
}
|
||||
|
||||
@DePermission(type = DePermissionType.PANEL, level = ResourceAuthLevel.PANNEL_LEVEL_VIEW, paramIndex = 1)
|
||||
@ApiOperation("分组查询表下属字段")
|
||||
@PostMapping("listByDQ/{chartId}/{panelId}")
|
||||
public ChartViewField4Type listByDQ(@PathVariable String chartId, @PathVariable String panelId) {
|
||||
ChartViewField chartViewField = new ChartViewField();
|
||||
chartViewField.setChartId(chartId);
|
||||
chartViewField.setGroupType("d");
|
||||
List<ChartViewField> dimensionList = chartViewFieldService.list(chartViewField);
|
||||
chartViewField.setGroupType("q");
|
||||
List<ChartViewField> quotaList = chartViewFieldService.list(chartViewField);
|
||||
|
||||
ChartViewField4Type chartViewField4Type = new ChartViewField4Type();
|
||||
chartViewField4Type.setDimensionList(dimensionList);
|
||||
chartViewField4Type.setQuotaList(quotaList);
|
||||
return chartViewField4Type;
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ import io.dataease.controller.response.DataSetDetail;
|
||||
import io.dataease.dto.dataset.DataSetTableDTO;
|
||||
import io.dataease.dto.dataset.ExcelFileData;
|
||||
import io.dataease.dto.dataset.SqlVariableDetails;
|
||||
import io.dataease.plugins.common.base.domain.ChartView;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTable;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableIncrementalConfig;
|
||||
@ -51,7 +50,8 @@ public class DataSetTableController {
|
||||
|
||||
@DePermissions(value = {
|
||||
@DePermission(type = DePermissionType.DATASET, value = "id", level = ResourceAuthLevel.DATASET_LEVEL_MANAGE),
|
||||
@DePermission(type = DePermissionType.DATASET, value = "sceneId", level = ResourceAuthLevel.DATASET_LEVEL_MANAGE)
|
||||
@DePermission(type = DePermissionType.DATASET, value = "sceneId", level = ResourceAuthLevel.DATASET_LEVEL_MANAGE),
|
||||
@DePermission(type = DePermissionType.DATASOURCE, value = "dataSourceId", level = ResourceAuthLevel.DATASOURCE_LEVEL_USE)
|
||||
}, logical = Logical.AND)
|
||||
@ApiOperation("更新")
|
||||
@PostMapping("update")
|
||||
@ -137,6 +137,10 @@ public class DataSetTableController {
|
||||
|
||||
@ApiOperation("根据sql查询预览数据")
|
||||
@PostMapping("sqlPreview")
|
||||
@DePermissions(value = {
|
||||
@DePermission(type = DePermissionType.DATASET, value = "id", level = ResourceAuthLevel.DATASET_LEVEL_USE),
|
||||
@DePermission(type = DePermissionType.DATASOURCE, value = "dataSourceId", level = ResourceAuthLevel.DATASOURCE_LEVEL_USE)
|
||||
}, logical = Logical.AND)
|
||||
public Map<String, Object> getSQLPreview(@RequestBody DataSetTableRequest dataSetTableRequest) throws Exception {
|
||||
return dataSetTableService.getSQLPreview(dataSetTableRequest);
|
||||
}
|
||||
|
@ -1,14 +1,7 @@
|
||||
package io.dataease.controller.panel;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.plugins.common.base.domain.PanelGroup;
|
||||
import io.dataease.plugins.common.base.domain.PanelGroupWithBLOBs;
|
||||
import io.dataease.controller.handler.annotation.I18n;
|
||||
import io.dataease.controller.request.panel.PanelGroupRequest;
|
||||
import io.dataease.dto.chart.ChartViewDTO;
|
||||
import io.dataease.dto.panel.PanelGroupDTO;
|
||||
import io.dataease.dto.panel.PanelViewTableDTO;
|
||||
import io.dataease.service.panel.PanelGroupService;
|
||||
import io.dataease.service.panel.PanelViewService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
@ -17,6 +17,8 @@ public class PanelTemplateRequest extends PanelTemplateWithBLOBs {
|
||||
private String withBlobs="Y";
|
||||
@ApiModelProperty("操作类型")
|
||||
private String optType;
|
||||
@ApiModelProperty("静态文件")
|
||||
private String staticResource;
|
||||
@ApiModelProperty("是否及联")
|
||||
private Boolean withChildren = false;
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
package io.dataease.controller.response;
|
||||
|
||||
import io.dataease.plugins.common.base.domain.ChartViewField;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ChartViewField4Type {
|
||||
@ApiModelProperty("维度")
|
||||
List<ChartViewField> dimensionList;
|
||||
@ApiModelProperty("指标")
|
||||
List<ChartViewField> quotaList;
|
||||
}
|
@ -10,6 +10,7 @@ import io.dataease.controller.sys.request.PluginStatus;
|
||||
import io.dataease.service.sys.PluginService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -29,6 +30,7 @@ public class SysPluginController {
|
||||
|
||||
@ApiOperation("查询已安装插件")
|
||||
@PostMapping("/pluginGrid/{goPage}/{pageSize}")
|
||||
@RequiresPermissions("plugin:read")
|
||||
public Pager<List<MyPlugin>> pluginGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody BaseGridRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
return PageUtils.setPageInfo(page, pluginService.query(request));
|
||||
@ -36,19 +38,16 @@ public class SysPluginController {
|
||||
|
||||
@ApiOperation("安装插件")
|
||||
@PostMapping("upload")
|
||||
@RequiresPermissions("plugin:upload")
|
||||
public Map<String, Object> localUpload(@RequestParam("file") MultipartFile file) throws Exception {
|
||||
return pluginService.localInstall(file);
|
||||
}
|
||||
|
||||
@ApiOperation("卸载插件")
|
||||
@PostMapping("/uninstall/{pluginId}")
|
||||
@RequiresPermissions("plugin:uninstall")
|
||||
public Boolean unInstall(@PathVariable Long pluginId) {
|
||||
return pluginService.uninstall(pluginId);
|
||||
}
|
||||
|
||||
@ApiOperation("切换插件状态")
|
||||
@PostMapping("/changeStatus")
|
||||
public Boolean changeStatus(@RequestBody PluginStatus pluginStatus) {
|
||||
return pluginService.changeStatus(pluginStatus.getPluginId(), pluginStatus.getStatus());
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import io.dataease.controller.sys.response.MailInfo;
|
||||
import io.dataease.dto.SystemParameterDTO;
|
||||
import io.dataease.listener.DatasetCheckListener;
|
||||
import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.plugins.xpack.cas.dto.CasSaveResult;
|
||||
import io.dataease.service.FileService;
|
||||
import io.dataease.service.system.EmailService;
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
@ -66,8 +67,14 @@ public class SystemParameterController {
|
||||
|
||||
@RequiresPermissions("sysparam:read")
|
||||
@PostMapping("/edit/basic")
|
||||
public void editBasic(@RequestBody List<SystemParameter> systemParameter) {
|
||||
systemParameterService.editBasic(systemParameter);
|
||||
public CasSaveResult editBasic(@RequestBody List<SystemParameter> systemParameter) {
|
||||
int timeout = Integer.parseInt(systemParameter.stream().filter(
|
||||
parameter -> parameter.getParamKey().equals("basic.frontTimeOut")
|
||||
).findFirst().get().getParamValue());
|
||||
if (timeout < 0 || timeout > 300) { //增加了合法性检验
|
||||
throw new NumberFormatException("Timeout Range Error!");
|
||||
}
|
||||
return systemParameterService.editBasic(systemParameter);
|
||||
}
|
||||
|
||||
@PostMapping("/testConnection")
|
||||
|
@ -27,6 +27,8 @@ public interface AuthMapper {
|
||||
|
||||
SysUserEntity findLdapUserByName(@Param("username") String username);
|
||||
|
||||
SysUserEntity findCasUserByName(@Param("username") String username);
|
||||
|
||||
SysUserEntity findUserBySub(@Param("sub") String sub);
|
||||
|
||||
|
||||
|
@ -49,6 +49,11 @@
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin, `from` from sys_user a where username = #{username} and a.from = 1
|
||||
</select>
|
||||
|
||||
|
||||
<select id="findCasUserByName" resultMap="baseMap">
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin, `from` from sys_user a where username = #{username} and a.from = 3
|
||||
</select>
|
||||
|
||||
<select id="findUserBySub" resultMap="baseMap">
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin, `from` from sys_user where sub = #{sub}
|
||||
</select>
|
||||
|
@ -12,8 +12,6 @@ import java.util.List;
|
||||
public interface ExtChartViewMapper {
|
||||
List<ChartViewDTO> search(ChartViewRequest request);
|
||||
|
||||
// ChartViewDTO searchOne(ChartViewRequest request);
|
||||
|
||||
void chartCopy(@Param("newChartId")String newChartId,@Param("oldChartId")String oldChartId,@Param("panelId")String panelId);
|
||||
|
||||
@Select("select id from chart_view where table_id = #{tableId}")
|
||||
@ -35,8 +33,6 @@ public interface ExtChartViewMapper {
|
||||
|
||||
List<ChartViewDTO> searchViewsWithPanelId(@Param("panelId") String panelId);
|
||||
|
||||
// ChartViewDTO searchOneFromCache(@Param("id") String id );
|
||||
|
||||
void copyToCache(@Param("id") String id );
|
||||
|
||||
void deleteCacheWithPanel(@Param("viewIds") List<String> viewIds,@Param("panelId") String panelId );
|
||||
|
@ -91,9 +91,6 @@
|
||||
<if test="level != null">
|
||||
and panel_group.level = #{level}
|
||||
</if>
|
||||
<!-- <if test="isAdmin != null and !isAdmin">-->
|
||||
<!-- and (panel_group.node_type='folder' or (panel_group.node_type='panel' and panel_group.`status`='publish') or (panel_group.node_type='panel' and panel_group.`status`='unpublished' and authInfo.privileges like '%manage%') )-->
|
||||
<!-- </if>-->
|
||||
</where>
|
||||
ORDER BY CONVERT(panel_group.name using gbk)
|
||||
</select>
|
||||
@ -170,9 +167,6 @@
|
||||
<if test="level != null">
|
||||
and panel_group.level = #{level}
|
||||
</if>
|
||||
<!-- <if test="isAdmin != null and !isAdmin">-->
|
||||
<!-- and (panel_group.node_type='folder' or (panel_group.node_type='panel' and panel_group.`status`='publish') or (panel_group.node_type='panel' and panel_group.`status`='unpublished' and authInfo.privileges like '%manage%') )-->
|
||||
<!-- </if>-->
|
||||
</where>
|
||||
ORDER BY panel_group.node_type desc, CONVERT(panel_group.name using gbk)
|
||||
</select>
|
||||
|
@ -0,0 +1,27 @@
|
||||
package io.dataease.listener;
|
||||
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class CasStatusListener implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
Map<String, CasXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((CasXpackService.class));
|
||||
if (beansOfType.keySet().size() == 0) return;
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
if (ObjectUtils.isEmpty(casXpackService)) return;
|
||||
ServletContext servletContext = event.getApplicationContext().getBean(ServletContext.class);
|
||||
casXpackService.checkCasStatus(servletContext);
|
||||
}
|
||||
}
|
103
backend/src/main/java/io/dataease/plugins/server/CasServer.java
Normal file
103
backend/src/main/java/io/dataease/plugins/server/CasServer.java
Normal file
@ -0,0 +1,103 @@
|
||||
package io.dataease.plugins.server;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import io.dataease.auth.entity.SysUserEntity;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.service.AuthUserService;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.commons.utils.CodingUtil;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
|
||||
import io.dataease.service.sys.SysUserService;
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jasig.cas.client.authentication.AttributePrincipal;
|
||||
import org.jasig.cas.client.util.AssertionHolder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
@ApiIgnore
|
||||
@RequestMapping("/cas")
|
||||
@Controller
|
||||
public class CasServer {
|
||||
|
||||
@Autowired
|
||||
private AuthUserService authUserService;
|
||||
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Resource
|
||||
private SystemParameterService systemParameterService;
|
||||
|
||||
@GetMapping("/callBack")
|
||||
public ModelAndView callBack() {
|
||||
ModelAndView modelAndView = new ModelAndView("redirect:/");
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
|
||||
AttributePrincipal principal = AssertionHolder.getAssertion().getPrincipal();
|
||||
String name = principal.getName();
|
||||
try {
|
||||
SysUserEntity sysUserEntity = authUserService.getCasUserByName(name);
|
||||
if(null == sysUserEntity){
|
||||
String s = RandomUtil.randomString(6);
|
||||
String email = s + "@xxx.com";
|
||||
sysUserService.validateCasUser(name);
|
||||
sysUserService.saveCASUser(name, email);
|
||||
sysUserEntity = authUserService.getUserByName(name);
|
||||
}
|
||||
String realPwd = CodingUtil.md5(sysUserService.defaultPWD());
|
||||
TokenInfo tokenInfo = TokenInfo.builder().userId(sysUserEntity.getUserId()).username(sysUserEntity.getUsername()).build();
|
||||
String token = JWTUtils.sign(tokenInfo, realPwd);
|
||||
ServletUtils.setToken(token);
|
||||
Cookie cookie_token = new Cookie("Authorization", token);cookie_token.setPath("/");
|
||||
response.addCookie(cookie_token);
|
||||
|
||||
}catch(Exception e) {
|
||||
|
||||
String msg = e.getMessage();
|
||||
if (null != e.getCause()) {
|
||||
msg = e.getCause().getMessage();
|
||||
}
|
||||
try {
|
||||
msg = URLEncoder.encode(msg, "UTF-8");
|
||||
LogUtil.error(e);
|
||||
Cookie cookie_error = new Cookie("CasError", msg);
|
||||
cookie_error.setPath("/");
|
||||
response.addCookie(cookie_error);
|
||||
|
||||
return modelAndView;
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("/reset")
|
||||
@ResponseBody
|
||||
public String reset() {
|
||||
systemParameterService.resetCas();
|
||||
String token = ServletUtils.getToken();
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
|
||||
authUserService.clearCache(userId);
|
||||
}
|
||||
HttpServletRequest request = ServletUtils.request();
|
||||
request.getSession().invalidate();
|
||||
return "已经切换默认登录方式";
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package io.dataease.plugins.server;
|
||||
|
||||
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.cas.dto.CasSaveResult;
|
||||
import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
||||
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiIgnore
|
||||
@RequestMapping("/plugin/cas")
|
||||
@RestController
|
||||
public class XCasServer {
|
||||
|
||||
|
||||
@PostMapping("/info")
|
||||
public List<SysSettingDto> getOidcInfo() {
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
return casXpackService.casSettings();
|
||||
}
|
||||
|
||||
@RequiresPermissions("sysparam:read")
|
||||
@PostMapping("/save")
|
||||
public CasSaveResult save(@RequestBody List<SysSettingDto> settings) {
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
return casXpackService.save(settings);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.DorisConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO;
|
||||
@ -1060,7 +1061,13 @@ public class DorisQueryProvider extends QueryProvider {
|
||||
} else if (x.getDeType() == 0) {
|
||||
fieldName = String.format(DorisConstants.CAST, originField, DorisConstants.VARCHAR);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(DorisConstants.CAST, originField, DorisConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(DorisConstants.CAST, originField, DorisConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -5,6 +5,7 @@ import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
import io.dataease.plugins.common.constants.engine.MysqlConstants;
|
||||
import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO;
|
||||
@ -64,6 +65,7 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
case "MEDIUMINT":
|
||||
case "INTEGER":
|
||||
case "BIGINT":
|
||||
case "LONG": //增加了LONG类型
|
||||
return 2;// 整型
|
||||
case "FLOAT":
|
||||
case "DOUBLE":
|
||||
@ -1065,7 +1067,13 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
} else if (x.getDeType() == 0 && x.getDeExtractType() == 0) {
|
||||
fieldName = String.format(MysqlConstants.CAST, originField, MysqlConstants.CHAR);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(MysqlConstants.CAST, originField, MysqlConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(MysqlConstants.CAST, originField, MysqlConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -1115,7 +1115,13 @@ public class CKQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(CKConstants.formatDateTime, String.format(CKConstants.toDateTime, String.format(CKConstants.toFloat64, originField)), format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(CKConstants.toInt64, originField);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(CKConstants.toFloat64, originField);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.dataease.provider.query.db2;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.dto.datasource.Db2Configuration;
|
||||
import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
@ -114,9 +115,9 @@ public class Db2QueryProvider extends QueryProvider {
|
||||
if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(Db2Constants.UNIX_TIMESTAMP, originField);
|
||||
} else {
|
||||
if(f.getType().equalsIgnoreCase("TIME")){
|
||||
if (f.getType().equalsIgnoreCase("TIME")) {
|
||||
fieldName = String.format(Db2Constants.FORMAT_TIME, originField, Db2Constants.DEFAULT_DATE_FORMAT);
|
||||
}else {
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
@ -191,9 +192,9 @@ public class Db2QueryProvider extends QueryProvider {
|
||||
if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(Db2Constants.UNIX_TIMESTAMP, originField);
|
||||
} else {
|
||||
if(f.getType().equalsIgnoreCase("TIME")){
|
||||
if (f.getType().equalsIgnoreCase("TIME")) {
|
||||
fieldName = String.format(Db2Constants.FORMAT_TIME, originField, Db2Constants.DEFAULT_DATE_FORMAT);
|
||||
}else {
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
@ -854,9 +855,9 @@ public class Db2QueryProvider extends QueryProvider {
|
||||
whereName = String.format(Db2Constants.FROM_UNIXTIME, cast, Db2Constants.DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
if (field.getDeExtractType() == DeTypeConstants.DE_TIME) {
|
||||
if(field.getType().equalsIgnoreCase("TIME")){
|
||||
if (field.getType().equalsIgnoreCase("TIME")) {
|
||||
whereName = String.format(Db2Constants.FORMAT_TIME, originName, Db2Constants.DEFAULT_DATE_FORMAT);
|
||||
}else {
|
||||
} else {
|
||||
whereName = originName;
|
||||
}
|
||||
}
|
||||
@ -962,9 +963,9 @@ public class Db2QueryProvider extends QueryProvider {
|
||||
whereName = String.format(Db2Constants.FROM_UNIXTIME, cast, Db2Constants.DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
if (field.getDeExtractType() == DeTypeConstants.DE_TIME) {
|
||||
if(field.getType().equalsIgnoreCase("TIME")){
|
||||
if (field.getType().equalsIgnoreCase("TIME")) {
|
||||
whereName = String.format(Db2Constants.FORMAT_TIME, originName, Db2Constants.DEFAULT_DATE_FORMAT);
|
||||
}else {
|
||||
} else {
|
||||
whereName = originName;
|
||||
}
|
||||
}
|
||||
@ -1065,9 +1066,9 @@ public class Db2QueryProvider extends QueryProvider {
|
||||
fieldName = String.format(Db2Constants.UNIX_TIMESTAMP, originField) + "*1000";
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_TIME) {
|
||||
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
|
||||
if(x.getType().equalsIgnoreCase("TIME")){
|
||||
if (x.getType().equalsIgnoreCase("TIME")) {
|
||||
fieldName = String.format(Db2Constants.FORMAT_TIME, originField, format);
|
||||
}else {
|
||||
} else {
|
||||
fieldName = String.format(Db2Constants.DATE_FORMAT, originField, format);
|
||||
}
|
||||
} else {
|
||||
@ -1084,7 +1085,13 @@ public class Db2QueryProvider extends QueryProvider {
|
||||
fieldName = String.format(Db2Constants.DATE_FORMAT, from_unixtime, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(Db2Constants.CAST, originField, Db2Constants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(Db2Constants.CAST, originField, Db2Constants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -1105,7 +1105,13 @@ public class EsQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(EsSqlLConstants.DATETIME_FORMAT, cast, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(EsSqlLConstants.CAST, originField, "bigint");
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(EsSqlLConstants.CAST, originField, "double");
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -1042,7 +1042,13 @@ public class HiveQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(HiveConstants.DATE_FORMAT, from_unixtime, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(HiveConstants.CAST, originField, HiveConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(HiveConstants.CAST, originField, HiveConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -1048,7 +1048,13 @@ public class ImpalaQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(ImpalaConstants.DATE_FORMAT, from_unixtime, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(ImpalaConstants.CAST, originField, ImpalaConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(ImpalaConstants.CAST, originField, ImpalaConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -5,6 +5,7 @@ import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.MySQLConstants;
|
||||
import io.dataease.plugins.common.constants.engine.MysqlConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
@ -66,6 +67,7 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
case "MEDIUMINT":
|
||||
case "INTEGER":
|
||||
case "BIGINT":
|
||||
case "LONG": //增加了LONG类型
|
||||
return 2;// 整型
|
||||
case "FLOAT":
|
||||
case "DOUBLE":
|
||||
@ -194,7 +196,6 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
}
|
||||
|
||||
|
||||
|
||||
STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE);
|
||||
ST st_sql = stg.getInstanceOf("previewSql");
|
||||
st_sql.add("isGroup", isGroup);
|
||||
@ -368,7 +369,7 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
originField = String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName());
|
||||
} else {
|
||||
if (x.getDeType() == 2 || x.getDeType() == 3) {
|
||||
originField = String.format(MySQLConstants.CAST, String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), MysqlConstants.DEFAULT_FLOAT_FORMAT);
|
||||
originField = String.format(MySQLConstants.CAST, String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), MySQLConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
originField = String.format(MySQLConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName());
|
||||
}
|
||||
@ -1048,7 +1049,13 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(MySQLConstants.DATE_FORMAT, from_unixtime, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(MySQLConstants.CAST, originField, MySQLConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(MySQLConstants.CAST, originField, MySQLConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
@ -1102,11 +1109,9 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
} else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) {
|
||||
if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) {
|
||||
fieldName = String.format(MySQLConstants.AGG_FIELD, "COUNT", "DISTINCT " + originField);
|
||||
}
|
||||
else if (StringUtils.equalsIgnoreCase(y.getSummary(), "group_concat")) {
|
||||
} else if (StringUtils.equalsIgnoreCase(y.getSummary(), "group_concat")) {
|
||||
fieldName = String.format(MySQLConstants.GROUP_CONCAT, originField);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fieldName = String.format(MySQLConstants.AGG_FIELD, y.getSummary(), originField);
|
||||
}
|
||||
} else {
|
||||
|
@ -1,13 +1,13 @@
|
||||
package io.dataease.provider.query.oracle;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.dto.datasource.OracleConfiguration;
|
||||
import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper;
|
||||
import io.dataease.dto.datasource.OracleConfiguration;
|
||||
import io.dataease.plugins.common.constants.datasource.MySQLConstants;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.OracleConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO;
|
||||
@ -109,7 +109,6 @@ public class OracleQueryProvider extends QueryProvider {
|
||||
List<SQLObj> xFields = xFields(table, fields);
|
||||
|
||||
|
||||
|
||||
STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE);
|
||||
ST st_sql = stg.getInstanceOf("previewSql");
|
||||
st_sql.add("isGroup", isGroup);
|
||||
@ -136,7 +135,6 @@ public class OracleQueryProvider extends QueryProvider {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup, Datasource ds, List<ChartFieldCustomFilterDTO> fieldCustomFilter) {
|
||||
return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, null);
|
||||
@ -1122,7 +1120,13 @@ public class OracleQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(OracleConstants.TO_CHAR, date, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
@ -1178,8 +1182,7 @@ public class OracleQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(OracleConstants.AGG_FIELD, "COUNT", "DISTINCT " + originField);
|
||||
} else if (StringUtils.equalsIgnoreCase(y.getSummary(), "group_concat")) {
|
||||
fieldName = String.format(OracleConstants.GROUP_CONCAT, originField, originField);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fieldName = String.format(OracleConstants.AGG_FIELD, y.getSummary(), originField);
|
||||
}
|
||||
} else {
|
||||
|
@ -6,7 +6,7 @@ import io.dataease.plugins.common.base.domain.DatasetTableField;
|
||||
import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper;
|
||||
import io.dataease.plugins.common.constants.*;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.PgConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SqlServerSQLConstants;
|
||||
@ -1072,7 +1072,13 @@ public class PgQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(PgConstants.DATE_FORMAT, from_unixtime, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(PgConstants.CAST, originField, PgConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(PgConstants.CAST, originField, PgConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
@ -1090,8 +1096,7 @@ public class PgQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(PgConstants.AGG_FIELD, "COUNT", "DISTINCT " + originField);
|
||||
} else if (StringUtils.equalsIgnoreCase(y.getSummary(), "group_concat")) {
|
||||
fieldName = String.format(PgConstants.GROUP_CONCAT, originField);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fieldName = String.format(PgConstants.AGG_FIELD, y.getSummary(), originField);
|
||||
}
|
||||
} else {
|
||||
|
@ -1000,7 +1000,13 @@ public class RedshiftQueryProvider extends QueryProvider {
|
||||
fieldName = String.format(PgConstants.DATE_FORMAT, from_unixtime, format);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(PgConstants.CAST, originField, PgConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(PgConstants.CAST, originField, PgConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -7,7 +7,6 @@ import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.ImpalaConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SqlServerSQLConstants;
|
||||
import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO;
|
||||
@ -1121,7 +1120,13 @@ public class SqlserverQueryProvider extends QueryProvider {
|
||||
fieldName = transDateFormat(x.getDateStyle(), x.getDatePattern(), cast);
|
||||
}
|
||||
} else {
|
||||
fieldName = originField;
|
||||
if (x.getDeType() == DeTypeConstants.DE_INT) {
|
||||
fieldName = String.format(SqlServerSQLConstants.CONVERT, originField, SqlServerSQLConstants.DEFAULT_INT_FORMAT);
|
||||
} else if (x.getDeType() == DeTypeConstants.DE_FLOAT) {
|
||||
fieldName = String.format(SqlServerSQLConstants.CONVERT, originField, SqlServerSQLConstants.DEFAULT_FLOAT_FORMAT);
|
||||
} else {
|
||||
fieldName = originField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLObj.builder()
|
||||
|
@ -0,0 +1,80 @@
|
||||
package io.dataease.service.chart;
|
||||
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.utils.TableUtils;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.plugins.common.base.domain.ChartViewField;
|
||||
import io.dataease.plugins.common.base.domain.ChartViewFieldExample;
|
||||
import io.dataease.plugins.common.base.mapper.ChartViewFieldMapper;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Author: Gin
|
||||
*/
|
||||
@Service
|
||||
public class ChartViewFieldService {
|
||||
@Resource
|
||||
private ChartViewFieldMapper chartViewFieldMapper;
|
||||
|
||||
public ChartViewField save(ChartViewField chartViewField) {
|
||||
checkFieldName(chartViewField);
|
||||
if (StringUtils.isEmpty(chartViewField.getId())) {
|
||||
chartViewField.setId(UUID.randomUUID().toString());
|
||||
// 若dataeasename为空,则用MD5(id)作为dataeasename
|
||||
if (StringUtils.isEmpty(chartViewField.getDataeaseName())) {
|
||||
chartViewField.setDataeaseName(TableUtils.columnName(chartViewField.getId()));
|
||||
}
|
||||
if (ObjectUtils.isEmpty(chartViewField.getLastSyncTime())) {
|
||||
chartViewField.setLastSyncTime(System.currentTimeMillis());
|
||||
}
|
||||
chartViewFieldMapper.insert(chartViewField);
|
||||
} else {
|
||||
chartViewFieldMapper.updateByPrimaryKeySelective(chartViewField);
|
||||
}
|
||||
return chartViewField;
|
||||
}
|
||||
|
||||
public List<ChartViewField> list(ChartViewField chartViewField) {
|
||||
ChartViewFieldExample chartViewFieldExample = new ChartViewFieldExample();
|
||||
ChartViewFieldExample.Criteria criteria = chartViewFieldExample.createCriteria();
|
||||
if (StringUtils.isNotEmpty(chartViewField.getChartId())) {
|
||||
criteria.andChartIdEqualTo(chartViewField.getChartId());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(chartViewField.getGroupType())) {
|
||||
criteria.andGroupTypeEqualTo(chartViewField.getGroupType());
|
||||
}
|
||||
return chartViewFieldMapper.selectByExampleWithBLOBs(chartViewFieldExample);
|
||||
}
|
||||
|
||||
public void delete(String id) {
|
||||
chartViewFieldMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public void deleteByChartId(String chartId) {
|
||||
ChartViewFieldExample chartViewFieldExample = new ChartViewFieldExample();
|
||||
chartViewFieldExample.createCriteria().andChartIdEqualTo(chartId);
|
||||
chartViewFieldMapper.deleteByExample(chartViewFieldExample);
|
||||
}
|
||||
|
||||
public void checkFieldName(ChartViewField chartViewField) {
|
||||
if (StringUtils.isNotEmpty(chartViewField.getName()) && StringUtils.isNotEmpty(chartViewField.getChartId())) {
|
||||
ChartViewFieldExample chartViewFieldExample = new ChartViewFieldExample();
|
||||
ChartViewFieldExample.Criteria criteria = chartViewFieldExample.createCriteria();
|
||||
criteria.andNameEqualTo(chartViewField.getName()).andChartIdEqualTo(chartViewField.getChartId());
|
||||
if (StringUtils.isNotEmpty(chartViewField.getId())) {
|
||||
criteria.andIdNotEqualTo(chartViewField.getId());
|
||||
}
|
||||
List<ChartViewField> datasetTableFields = chartViewFieldMapper.selectByExample(chartViewFieldExample);
|
||||
if (CollectionUtils.isNotEmpty(datasetTableFields)) {
|
||||
DEException.throwException(Translator.get("i18n_field_name_repeat"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -577,10 +577,10 @@ public class ChartViewService {
|
||||
//将没有权限的列删掉
|
||||
List<String> dataeaseNames = columnPermissionFields.stream().map(DatasetTableField::getDataeaseName).collect(Collectors.toList());
|
||||
dataeaseNames.add("*");
|
||||
fieldCustomFilter = fieldCustomFilter.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
extStack = extStack.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
extBubble = extBubble.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
drill = drill.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
fieldCustomFilter = fieldCustomFilter.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
extStack = extStack.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
extBubble = extBubble.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
drill = drill.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
|
||||
|
||||
//行权限
|
||||
@ -597,7 +597,7 @@ public class ChartViewService {
|
||||
|
||||
switch (view.getType()) {
|
||||
case "label":
|
||||
xAxis = xAxis.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
xAxis = xAxis.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
yAxis = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(xAxis)) {
|
||||
return emptyChartViewDTO(view);
|
||||
@ -607,25 +607,25 @@ public class ChartViewService {
|
||||
case "gauge":
|
||||
case "liquid":
|
||||
xAxis = new ArrayList<>();
|
||||
yAxis = yAxis.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
yAxis = yAxis.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(yAxis)) {
|
||||
return emptyChartViewDTO(view);
|
||||
}
|
||||
break;
|
||||
case "table-info":
|
||||
yAxis = new ArrayList<>();
|
||||
xAxis = xAxis.stream().filter(item -> dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
xAxis = xAxis.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(xAxis)) {
|
||||
return emptyChartViewDTO(view);
|
||||
}
|
||||
break;
|
||||
case "table-normal":
|
||||
xAxis = xAxis.stream().filter(item -> dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
yAxis = yAxis.stream().filter(item -> dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
xAxis = xAxis.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
yAxis = yAxis.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
break;
|
||||
default:
|
||||
xAxis = xAxis.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
yAxis = yAxis.stream().filter(item -> !desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName())).collect(Collectors.toList());
|
||||
xAxis = xAxis.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
yAxis = yAxis.stream().filter(item -> StringUtils.isNotEmpty(item.getChartId()) || (!desensitizationList.contains(item.getDataeaseName()) && dataeaseNames.contains(item.getDataeaseName()))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// 过滤来自仪表板的条件
|
||||
|
@ -1737,6 +1737,7 @@ public class DataSetTableService {
|
||||
TableUtils.fieldName(field.getTableId() + "_" + field.getDataeaseName()),
|
||||
tableField.getFieldName())) {
|
||||
tableField.setRemarks(field.getName());
|
||||
tableField.setFieldType(field.getType()); //将原有的type赋值给新创建的数据列
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -136,22 +136,22 @@ public class DirectFieldService implements DataSetFieldService {
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
|
||||
if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.DB.toString())) {
|
||||
datasourceRequest.setTable(dataTableInfoDTO.getTable());
|
||||
datasourceRequest.setQuery(qp.createQuerySQL(dataTableInfoDTO.getTable(), permissionFields, true, ds, customFilter, deSortFields));
|
||||
datasourceRequest.setQuery(qp.createQuerySQL(dataTableInfoDTO.getTable(), permissionFields, false, ds, customFilter, deSortFields));
|
||||
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.SQL.toString())) {
|
||||
String sql = dataTableInfoDTO.getSql();
|
||||
if (rowAndColumnMgm) {
|
||||
sql = dataSetTableService.removeVariables(sql);
|
||||
}
|
||||
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(sql, permissionFields, true, customFilter, deSortFields));
|
||||
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(sql, permissionFields, false, customFilter, deSortFields));
|
||||
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.CUSTOM.toString())) {
|
||||
DataTableInfoDTO dt = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class);
|
||||
List<DataSetTableUnionDTO> listUnion = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId());
|
||||
String sql = dataSetTableService.getCustomSQLDatasource(dt, listUnion, ds);
|
||||
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(sql, permissionFields, true, customFilter, deSortFields));
|
||||
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(sql, permissionFields, false, customFilter, deSortFields));
|
||||
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.UNION.toString())) {
|
||||
DataTableInfoDTO dt = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class);
|
||||
String sql = (String) dataSetTableService.getUnionSQLDatasource(dt, ds).get("sql");
|
||||
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(sql, permissionFields, true, customFilter, deSortFields));
|
||||
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(sql, permissionFields, false, customFilter, deSortFields));
|
||||
}
|
||||
} else if (datasetTable.getMode() == 1) {// 抽取
|
||||
// 连接doris,构建doris数据源查询
|
||||
@ -162,7 +162,7 @@ public class DirectFieldService implements DataSetFieldService {
|
||||
String tableName = "ds_" + datasetTable.getId().replaceAll("-", "_");
|
||||
datasourceRequest.setTable(tableName);
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
|
||||
datasourceRequest.setQuery(qp.createQuerySQL(tableName, permissionFields, true, null, customFilter));
|
||||
datasourceRequest.setQuery(qp.createQuerySQL(tableName, permissionFields, false, null, customFilter));
|
||||
}
|
||||
System.out.println(datasourceRequest.getQuery());
|
||||
List<String[]> rows = datasourceProvider.getData(datasourceRequest);
|
||||
|
@ -106,7 +106,7 @@ public class DriverService {
|
||||
DeDriverDetails deDriverDetails = deDriverDetailsMapper.selectByPrimaryKey(driverFileId);
|
||||
DeDriver deDriver = deDriverMapper.selectByPrimaryKey(deDriverDetails.getDeDriverId());
|
||||
if(deDriver == null){
|
||||
throw new Exception("未找到驱动");
|
||||
throw new Exception(Translator.get("I18N_DRIVER_NOT_FOUND"));
|
||||
}
|
||||
DeFileUtils.deleteFile(DRIVER_PATH + deDriverDetails.getDeDriverId() + "/" + deDriverDetails.getFileName());
|
||||
SysLogDTO sysLogDTO = DeLogUtils.buildLog(SysLogConstants.OPERATE_TYPE.DELETE, SysLogConstants.SOURCE_TYPE.DRIVER_FILE, deDriverDetails.getId(), deDriverDetails.getDeDriverId(), null, null);
|
||||
@ -119,7 +119,7 @@ public class DriverService {
|
||||
public DeDriverDetails saveJar(MultipartFile file, String driverId) throws Exception {
|
||||
DeDriver deDriver = deDriverMapper.selectByPrimaryKey(driverId);
|
||||
if(deDriver == null){
|
||||
throw new Exception("未找到驱动");
|
||||
throw new Exception(Translator.get("I18N_DRIVER_NOT_FOUND"));
|
||||
}
|
||||
String filename = file.getOriginalFilename();
|
||||
String dirPath = DRIVER_PATH + driverId + "/";
|
||||
@ -128,13 +128,6 @@ public class DriverService {
|
||||
saveFile(file, dirPath, filePath);
|
||||
List<String> jdbcList = new ArrayList<>();
|
||||
String version = "";
|
||||
// ExtendedJdbcClassLoader extendedJdbcClassLoader = new ExtendedJdbcClassLoader(new URL[]{new File(filePath).toURI().toURL()}, null);
|
||||
// for (String className : getClassNameFrom(filePath)) {
|
||||
// if (isChildClass(className, java.sql.Driver.class, extendedJdbcClassLoader)) {
|
||||
// jdbcList.add(className);
|
||||
// version = classVersion(extendedJdbcClassLoader, className);
|
||||
// }
|
||||
// }
|
||||
|
||||
DeDriverDetails deDriverDetails = new DeDriverDetails();
|
||||
deDriverDetails.setId(UUID.randomUUID().toString());
|
||||
|
@ -222,22 +222,16 @@ public class PanelGroupService {
|
||||
//清理view 和 view cache
|
||||
extPanelGroupMapper.deleteCircleView(id);
|
||||
extPanelGroupMapper.deleteCircleViewCache(id);
|
||||
|
||||
// 同时会删除对应默认仪表盘
|
||||
extPanelGroupMapper.deleteCircle(id);
|
||||
storeService.removeByPanelId(id);
|
||||
shareService.delete(id, null);
|
||||
panelLinkService.deleteByResourceId(id);
|
||||
|
||||
|
||||
//清理跳转信息
|
||||
extPanelLinkJumpMapper.deleteJumpTargetViewInfoWithPanel(id);
|
||||
extPanelLinkJumpMapper.deleteJumpInfoWithPanel(id);
|
||||
extPanelLinkJumpMapper.deleteJumpWithPanel(id);
|
||||
|
||||
DeLogUtils.save(sysLogDTO);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -285,7 +279,6 @@ public class PanelGroupService {
|
||||
List<String> panelIds = panelResult.stream().map(VAuthModelDTO::getId).collect(Collectors.toList());
|
||||
VAuthModelRequest viewRequest = new VAuthModelRequest();
|
||||
viewRequest.setPids(panelIds);
|
||||
// Version 1.11 only gets the current panel
|
||||
List<VAuthModelDTO> viewResult = extVAuthModelMapper.queryAuthModelViews(viewRequest);
|
||||
if (CollectionUtils.isNotEmpty(viewResult)) {
|
||||
result.addAll(viewResult);
|
||||
@ -316,10 +309,6 @@ public class PanelGroupService {
|
||||
VAuthModelRequest viewRequest = new VAuthModelRequest();
|
||||
viewRequest.setPids(panelIds);
|
||||
// Version 1.11 only gets the current panel
|
||||
// List<VAuthModelDTO> viewResult = extVAuthModelMapper.queryAuthModelViews(viewRequest);
|
||||
// if (CollectionUtils.isNotEmpty(viewResult)) {
|
||||
// result.addAll(viewResult);
|
||||
// }
|
||||
result = TreeUtils.mergeTree(result, "panel_list");
|
||||
if (AuthUtils.getUser().getIsAdmin()) {
|
||||
// 原有视图的目录结构
|
||||
|
@ -12,6 +12,7 @@ import io.dataease.plugins.common.base.domain.PanelTemplate;
|
||||
import io.dataease.plugins.common.base.domain.PanelTemplateExample;
|
||||
import io.dataease.plugins.common.base.domain.PanelTemplateWithBLOBs;
|
||||
import io.dataease.plugins.common.base.mapper.PanelTemplateMapper;
|
||||
import io.dataease.service.staticResource.StaticResourceService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -35,6 +36,8 @@ public class PanelTemplateService {
|
||||
private PanelTemplateMapper panelTemplateMapper;
|
||||
@Resource
|
||||
private ExtPanelTemplateMapper extPanelTemplateMapper;
|
||||
@Resource
|
||||
private StaticResourceService staticResourceService;
|
||||
|
||||
public List<PanelTemplateDTO> templateList(PanelTemplateRequest panelTemplateRequest) {
|
||||
panelTemplateRequest.setWithBlobs("N");
|
||||
@ -75,6 +78,8 @@ public class PanelTemplateService {
|
||||
exampleDelete.createCriteria().andPidEqualTo(request.getPid()).andNameEqualTo(request.getName());
|
||||
panelTemplateMapper.deleteByExample(exampleDelete);
|
||||
}
|
||||
//Store static resource into the server
|
||||
staticResourceService.saveFilesToServe(request.getStaticResource());
|
||||
panelTemplateMapper.insert(request);
|
||||
} else {
|
||||
String nameCheckResult = this.nameCheck(CommonConstants.OPT_TYPE.UPDATE, request.getName(), request.getPid(), request.getId());
|
||||
|
@ -125,7 +125,6 @@ public class PanelViewService {
|
||||
extPanelViewMapper.savePanelView(panelViewInsertDTOList);
|
||||
//将视图从cache表中更新到正式表中
|
||||
viewIds = panelViewInsertDTOList.stream().map(panelView -> panelView.getChartViewId()).collect(Collectors.toList());
|
||||
// extChartViewMapper.copyCacheToView(viewIds);
|
||||
}
|
||||
extChartViewMapper.deleteCacheWithPanel(viewIds, panelId);
|
||||
extChartViewMapper.deleteNoUseView(viewIds, panelId);
|
||||
|
@ -54,7 +54,7 @@ public class ShareService {
|
||||
* 5.批量新增
|
||||
* 6.发送取消分享消息
|
||||
* 7.发送新增分享消息
|
||||
*
|
||||
*
|
||||
* @param panelShareFineDto
|
||||
*/
|
||||
@Transactional
|
||||
@ -72,12 +72,6 @@ public class ShareService {
|
||||
authURDMap.put(0, authURD.getUserIds());
|
||||
authURDMap.put(1, authURD.getRoleIds());
|
||||
authURDMap.put(2, authURD.getDeptIds());
|
||||
|
||||
/*
|
||||
* PanelShareExample example = new PanelShareExample();
|
||||
* example.createCriteria().andPanelGroupIdEqualTo(panelGroupId);
|
||||
* List<PanelShare> panelShares = mapper.selectByExample(example);
|
||||
*/
|
||||
PanelShareSearchRequest request = new PanelShareSearchRequest();
|
||||
request.setCurrentUserName(AuthUtils.getUser().getUsername());
|
||||
request.setResourceId(panelGroupId);
|
||||
@ -322,7 +316,7 @@ public class ShareService {
|
||||
|
||||
/**
|
||||
* panel_group_id建了索引 效率不会很差
|
||||
*
|
||||
*
|
||||
* @param panel_group_id
|
||||
*/
|
||||
@Transactional
|
||||
|
@ -124,6 +124,31 @@ public class SysUserService {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveCASUser(String name, String email) {
|
||||
long now = System.currentTimeMillis();
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUsername(name);
|
||||
sysUser.setNickName(name);
|
||||
sysUser.setEmail(email);
|
||||
sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD));
|
||||
sysUser.setCreateTime(now);
|
||||
sysUser.setUpdateTime(now);
|
||||
sysUser.setEnabled(1L);
|
||||
sysUser.setLanguage("zh_CN");
|
||||
sysUser.setFrom(3);
|
||||
sysUser.setIsAdmin(false);
|
||||
// sysUser.setSub(ssoUserInfo.getSub());
|
||||
sysUserMapper.insert(sysUser);
|
||||
SysUser dbUser = findOne(sysUser);
|
||||
if (null != dbUser && null != dbUser.getUserId()) {
|
||||
// oidc默认角色是普通员工
|
||||
List<Long> roleIds = new ArrayList<Long>();
|
||||
roleIds.add(2L);
|
||||
saveUserRoles( dbUser.getUserId(), roleIds);
|
||||
}
|
||||
}
|
||||
|
||||
public String defaultPWD() {
|
||||
return DEFAULT_PWD;
|
||||
}
|
||||
@ -323,6 +348,14 @@ public class SysUserService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void validateCasUser(String userName) {
|
||||
SysUserExample example = new SysUserExample();
|
||||
example.createCriteria().andUsernameEqualTo(userName);
|
||||
List<SysUser> users = sysUserMapper.selectByExample(example);
|
||||
if(CollectionUtils.isNotEmpty(users)) {
|
||||
throw new RuntimeException("用户ID【"+userName+"】已存在,请联系管理员");
|
||||
}
|
||||
}
|
||||
public void validateExistUser(String userName, String nickName, String email) {
|
||||
SysUserExample example = new SysUserExample();
|
||||
if (StringUtils.isNotBlank(userName)) {
|
||||
|
@ -47,11 +47,6 @@ public class LogService {
|
||||
// 驱动文件操作 上传, 删除
|
||||
private static Integer[] driver_file_ope = {11, 3};
|
||||
|
||||
|
||||
// 排除驱动和驱动文件的公共操作的资源类型
|
||||
// 暂时屏蔽视图日志
|
||||
// private static Integer[] COMMON_SOURCE = {1, 2,3,4,6,7,8,9};
|
||||
|
||||
private static Integer[] COMMON_SOURCE = {1, 2, 3, 6, 7, 8, 9};
|
||||
|
||||
// 增 改 删 针对公共资源的操作
|
||||
|
@ -10,8 +10,12 @@ import io.dataease.plugins.common.base.domain.FileMetadata;
|
||||
import io.dataease.plugins.common.base.domain.SystemParameter;
|
||||
import io.dataease.plugins.common.base.domain.SystemParameterExample;
|
||||
import io.dataease.plugins.common.base.mapper.SystemParameterMapper;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.cas.dto.CasSaveResult;
|
||||
import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
||||
import io.dataease.service.FileService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -22,6 +26,8 @@ import javax.imageio.ImageIO;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import io.dataease.ext.*;
|
||||
|
||||
@Service
|
||||
@ -29,6 +35,7 @@ import io.dataease.ext.*;
|
||||
public class SystemParameterService {
|
||||
|
||||
private final static String LOGIN_TYPE_KEY = "basic.loginType";
|
||||
private final static String CAS_LOGIN_TYPE = "3";
|
||||
@Resource
|
||||
private SystemParameterMapper systemParameterMapper;
|
||||
@Resource
|
||||
@ -81,8 +88,11 @@ public class SystemParameterService {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void editBasic(List<SystemParameter> parameters) {
|
||||
parameters.forEach(parameter -> {
|
||||
@Transactional
|
||||
public CasSaveResult editBasic(List<SystemParameter> parameters) {
|
||||
CasSaveResult casSaveResult = afterSwitchDefaultLogin(parameters);
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
SystemParameter parameter = parameters.get(i);
|
||||
SystemParameterExample example = new SystemParameterExample();
|
||||
|
||||
example.createCriteria().andParamKeyEqualTo(parameter.getParamKey());
|
||||
@ -92,8 +102,65 @@ public class SystemParameterService {
|
||||
systemParameterMapper.insert(parameter);
|
||||
}
|
||||
example.clear();
|
||||
}
|
||||
return casSaveResult;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void resetCas() {
|
||||
Map<String, CasXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((CasXpackService.class));
|
||||
if (beansOfType.keySet().size() == 0) DEException.throwException("当前未启用CAS");
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
if (ObjectUtils.isEmpty(casXpackService)) DEException.throwException("当前未启用CAS");
|
||||
|
||||
String loginTypePk = "basic.loginType";
|
||||
SystemParameter loginTypeParameter = systemParameterMapper.selectByPrimaryKey(loginTypePk);
|
||||
if (ObjectUtils.isNotEmpty(loginTypeParameter) && StringUtils.equals("3", loginTypeParameter.getParamValue())) {
|
||||
loginTypeParameter.setParamValue("0");
|
||||
systemParameterMapper.updateByPrimaryKeySelective(loginTypeParameter);
|
||||
}
|
||||
casXpackService.setEnabled(false);
|
||||
}
|
||||
|
||||
public CasSaveResult afterSwitchDefaultLogin(List<SystemParameter> parameters) {
|
||||
CasSaveResult casSaveResult = new CasSaveResult();
|
||||
casSaveResult.setNeedLogout(false);
|
||||
Map<String, CasXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((CasXpackService.class));
|
||||
if (beansOfType.keySet().size() == 0) return casSaveResult;
|
||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
||||
if (ObjectUtils.isEmpty(casXpackService)) return casSaveResult;
|
||||
|
||||
AtomicReference<String> loginType = new AtomicReference();
|
||||
boolean containLoginType = parameters.stream().anyMatch(param -> {
|
||||
if (StringUtils.equals(param.getParamKey(), LOGIN_TYPE_KEY)) {
|
||||
loginType.set(param.getParamValue());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (!containLoginType) return casSaveResult;
|
||||
|
||||
|
||||
SystemParameter systemParameter = systemParameterMapper.selectByPrimaryKey(LOGIN_TYPE_KEY);
|
||||
String originVal = null;
|
||||
if (ObjectUtils.isNotEmpty(systemParameter)) {
|
||||
originVal = systemParameter.getParamValue();
|
||||
}
|
||||
|
||||
if (StringUtils.equals(originVal, loginType.get())) return casSaveResult;
|
||||
|
||||
if (StringUtils.equals(CAS_LOGIN_TYPE, loginType.get())) {
|
||||
casSaveResult.setNeedLogout(true);
|
||||
casXpackService.setEnabled(true);
|
||||
casSaveResult.setCasEnable(true);
|
||||
}
|
||||
|
||||
if (StringUtils.equals(CAS_LOGIN_TYPE, originVal)) {
|
||||
casSaveResult.setNeedLogout(true);
|
||||
casXpackService.setEnabled(false);
|
||||
casSaveResult.setCasEnable(false);
|
||||
}
|
||||
return casSaveResult;
|
||||
}
|
||||
|
||||
public List<SystemParameter> getParamList(String type) {
|
||||
@ -102,6 +169,8 @@ public class SystemParameterService {
|
||||
return systemParameterMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getVersion() {
|
||||
return System.getenv("MS_VERSION");
|
||||
}
|
||||
|
@ -25,6 +25,5 @@ public class PrincipalHandshakeHandler extends DefaultHandshakeHandler {
|
||||
return new DePrincipal(userId);
|
||||
}
|
||||
return null;
|
||||
//return super.determineUser(request, wsHandler, attributes);
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,5 @@ public class WsUtil {
|
||||
return ONLINE_USERS.contains(userId);
|
||||
}
|
||||
|
||||
/*public static void releaseMessage(WsMessage wsMessage){
|
||||
if(ObjectUtils.isEmpty(wsMessage) || ObjectUtils.isEmpty(wsMessage.getUserId()) || ObjectUtils.isEmpty(wsMessage.getTopic())) return;
|
||||
CommonBeanFactory.getBean()
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
|
@ -114,6 +114,13 @@ server.compression.min-response-size=1024
|
||||
|
||||
|
||||
|
||||
server.servlet.context-parameters.configurationStrategy=SYSTEM_PROPERTIES
|
||||
server.servlet.session.cookie.http-only=true
|
||||
server.servlet.session.tracking-modes=cookie
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
2
backend/src/main/resources/db/migration/V36__1.11.2.sql
Normal file
2
backend/src/main/resources/db/migration/V36__1.11.2.sql
Normal file
@ -0,0 +1,2 @@
|
||||
INSERT INTO `sys_menu` (`menu_id`, `pid`, `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`, `path`, `i_frame`, `cache`, `hidden`, `permission`, `create_by`, `update_by`, `create_time`, `update_time`) VALUES (102, 101, 0, 2, '上传插件', NULL, NULL, 999, NULL, NULL, b'0', b'0', b'0', 'plugin:upload', NULL, NULL, 1614930862373, 1614930862373);
|
||||
INSERT INTO `sys_menu` (`menu_id`, `pid`, `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`, `path`, `i_frame`, `cache`, `hidden`, `permission`, `create_by`, `update_by`, `create_time`, `update_time`) VALUES (103, 101, 0, 2, '卸载插件', NULL, NULL, 999, NULL, NULL, b'0', b'0', b'0', 'plugin:uninstall', NULL, NULL, 1614930862373, 1614930862373);
|
@ -21,5 +21,4 @@ CREATE TABLE `chart_view_field`
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
|
||||
ALTER TABLE `dataset_table`
|
||||
ADD COLUMN `sql_variable_details` LONGTEXT NULL AFTER `last_update_time`;
|
||||
ALTER TABLE `dataset_table` ADD COLUMN `sql_variable_details` LONGTEXT NULL AFTER `last_update_time`;
|
@ -155,4 +155,5 @@ SOURCE_TYPE_DRIVER_FILE=DRIVER FILE
|
||||
SOURCE_TYPE_MENU=MENU
|
||||
|
||||
I18N_DRIVER_NOT_DELETE=Drivers in use cannot be deleted
|
||||
I18N_DRIVER_REPEAT_NAME=Driver name cannot be same.
|
||||
I18N_DRIVER_REPEAT_NAME=Driver name cannot be same.
|
||||
I18N_DRIVER_NOT_FOUND=Cannot find driver.
|
@ -159,3 +159,4 @@ I18N_TIME=操作时间
|
||||
|
||||
I18N_DRIVER_NOT_DELETE=使用中的驱动不允许删除
|
||||
I18N_DRIVER_REPEAT_NAME=名称重复
|
||||
I18N_DRIVER_NOT_FOUND=未找到驱动
|
||||
|
@ -154,4 +154,5 @@ SOURCE_TYPE_DRIVER_FILE=驅動文件
|
||||
SOURCE_TYPE_MENU=菜單
|
||||
|
||||
I18N_DRIVER_NOT_DELETE=使用中的驅動不允許删除
|
||||
I18N_DRIVER_REPEAT_NAME=名稱重複
|
||||
I18N_DRIVER_REPEAT_NAME=名稱重複
|
||||
I18N_DRIVER_NOT_FOUND=未找到驅動
|
@ -8,6 +8,7 @@
|
||||
"build": "vue-cli-service build",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"dll": "webpack -p --progress --config ./webpack.dll.conf.js",
|
||||
"preview": "node build/index.js --preview",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
|
||||
@ -78,8 +79,10 @@
|
||||
"@vue/cli-plugin-babel": "3.6.0",
|
||||
"@vue/cli-plugin-eslint": "^3.9.1",
|
||||
"@vue/cli-service": "^3.3.1",
|
||||
"add-asset-html-webpack-plugin": "^3.1.3",
|
||||
"babel-eslint": "10.0.1",
|
||||
"chalk": "2.4.2",
|
||||
"clean-webpack-plugin": "^1.0.1",
|
||||
"connect": "3.6.6",
|
||||
"copy-webpack-plugin": "^4.6.0",
|
||||
"eslint": "5.15.3",
|
||||
@ -95,7 +98,8 @@
|
||||
"script-loader": "^0.7.2",
|
||||
"serve-static": "^1.13.2",
|
||||
"vue-template-compiler": "2.6.10",
|
||||
"vuetify": "^2.6.6"
|
||||
"vuetify": "^2.6.6",
|
||||
"webpack-cli": "^3.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9",
|
||||
|
1
frontend/public/vendor/vendor-manifest.json
vendored
Normal file
1
frontend/public/vendor/vendor-manifest.json
vendored
Normal file
File diff suppressed because one or more lines are too long
179
frontend/public/vendor/vendor.dll.js
vendored
Normal file
179
frontend/public/vendor/vendor.dll.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -8,14 +8,6 @@ export const areaMapping = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// export function geoJson(areaCode) {
|
||||
// return request({
|
||||
// url: '/api/map/resourceFull/' + areaCode,
|
||||
// method: 'get',
|
||||
// loading: true
|
||||
// })
|
||||
// }
|
||||
|
||||
export function geoJson(areaCode) {
|
||||
return request({
|
||||
url: '/geo/' + areaCode + '_full.json',
|
||||
|
@ -17,35 +17,9 @@ export function loadTable(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// export function addDept(data) {
|
||||
// return request({
|
||||
// url: '/api/dept/create',
|
||||
// method: 'post',
|
||||
// data
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function delDept(ids) {
|
||||
// return request({
|
||||
// url: '/api/dept/delete',
|
||||
// method: 'post',
|
||||
// data: ids
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function editDept(data) {
|
||||
// return request({
|
||||
// url: '/api/dept/update',
|
||||
// method: 'post',
|
||||
// data
|
||||
// })
|
||||
// }
|
||||
|
||||
export function treeByDeptId(deptId) {
|
||||
return request({
|
||||
url: '/api/dept/nodesByDeptId/' + deptId,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// export default { addDept, delDept, editDept, getDeptTree, loadTable, treeByDeptId }
|
||||
|
@ -1,57 +0,0 @@
|
||||
// import request from '@/utils/request'
|
||||
|
||||
// export function allRoles() {
|
||||
// return request({
|
||||
// url: '/api/user/all',
|
||||
// method: 'post',
|
||||
// loading: true
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function roleGrid(pageIndex, pageSize, data) {
|
||||
// return request({
|
||||
// url: '/api/role/roleGrid/' + pageIndex + '/' + pageSize,
|
||||
// method: 'post',
|
||||
// data,
|
||||
// loading: true
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function delRole(pid) {
|
||||
// return request({
|
||||
// url: '/api/role/delete/' + pid,
|
||||
// method: 'post'
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function addRole(data) {
|
||||
// return request({
|
||||
// url: '/api/role/create',
|
||||
// method: 'post',
|
||||
// data
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function editRole(data) {
|
||||
// return request({
|
||||
// url: '/api/role/update',
|
||||
// method: 'post',
|
||||
// data
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function addRoleMenus(data) {
|
||||
// return request({
|
||||
// url: '/api/role/saveRolesMenus',
|
||||
// method: 'post',
|
||||
// data
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function menuIds(roleId) {
|
||||
// return request({
|
||||
// url: '/api/role/menuIds/' + roleId,
|
||||
// method: 'post'
|
||||
// })
|
||||
// }
|
||||
// export default { addRole, editRole, delRole, roleGrid, allRoles, addRoleMenus, menuIds }
|
@ -22,6 +22,13 @@ export function logout() {
|
||||
})
|
||||
}
|
||||
|
||||
export function deLogout() {
|
||||
return request({
|
||||
url: '/api/auth/deLogout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function needModifyPwd() {
|
||||
return request({
|
||||
url: '/api/auth/useInitPwd',
|
||||
@ -79,6 +86,13 @@ export function oidcStatus() {
|
||||
})
|
||||
}
|
||||
|
||||
export function casStatus() {
|
||||
return request({
|
||||
url: '/api/auth/isOpenCas',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function pluginLoaded() {
|
||||
return request({
|
||||
url: '/api/auth/isPluginLoaded',
|
||||
|
@ -31,9 +31,24 @@
|
||||
]"
|
||||
:style="mainSlotStyle"
|
||||
>
|
||||
<edit-bar v-if="editBarShow" style="transform: translateZ(10px)" :active-model="'edit'" :element="element" @showViewDetails="showViewDetails" @amRemoveItem="amRemoveItem" @amAddItem="amAddItem" @resizeView="resizeView" @linkJumpSet="linkJumpSet" @boardSet="boardSet" />
|
||||
<edit-bar
|
||||
v-if="editBarShow"
|
||||
style="transform: translateZ(10px)"
|
||||
:active-model="'edit'"
|
||||
:element="element"
|
||||
@showViewDetails="showViewDetails"
|
||||
@amRemoveItem="amRemoveItem"
|
||||
@amAddItem="amAddItem"
|
||||
@resizeView="resizeView"
|
||||
@linkJumpSet="linkJumpSet"
|
||||
@boardSet="boardSet"
|
||||
/>
|
||||
<mobile-check-bar v-if="mobileCheckBarShow" :element="element" @amRemoveItem="amRemoveItem" />
|
||||
<div v-if="resizing" style="transform: translateZ(11px);position: absolute; z-index: 3" :style="resizeShadowStyle" />
|
||||
<div
|
||||
v-if="resizing"
|
||||
style="transform: translateZ(11px);position: absolute; z-index: 3"
|
||||
:style="resizeShadowStyle"
|
||||
/>
|
||||
<div
|
||||
v-for="(handlei, indexi) in actualHandles"
|
||||
:key="indexi"
|
||||
@ -44,7 +59,7 @@
|
||||
>
|
||||
<slot :name="handlei" />
|
||||
</div>
|
||||
<div :style="mainSlotStyleInner" class="main-background">
|
||||
<div :id="componentCanvasId" :style="mainSlotStyleInner" class="main-background">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
@ -55,6 +70,7 @@
|
||||
import { matchesSelectorToParentElements, getComputedSize, addEvent, removeEvent } from '../../utils/dom'
|
||||
import { computeWidth, computeHeight, restrictToBounds, snapToGrid, rotatedPoint, getAngle } from '../../utils/fns'
|
||||
import { events, userSelectNone, userSelectAuto } from './option.js'
|
||||
|
||||
let eventsFor = events.mouse
|
||||
|
||||
// private
|
||||
@ -385,6 +401,13 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
componentCanvasId() {
|
||||
if (this.element.type === 'view') {
|
||||
return 'user-view-' + this.element.propValue.viewId
|
||||
} else {
|
||||
return 'components-' + this.element.id
|
||||
}
|
||||
},
|
||||
// 编辑组件显示
|
||||
editBarShow() {
|
||||
// 编辑组件显示条件:1.当前组件存在 2.组件是激活状态或者当前在联动设置状态 3.当前不在移动端画布编辑状态 4.或者批量操作状态
|
||||
@ -545,16 +568,22 @@ export default {
|
||||
mainSlotStyleInner() {
|
||||
const style = {}
|
||||
if (this.element.commonBackground) {
|
||||
let colorRGBA = ''
|
||||
if (this.element.commonBackground.backgroundColorSelect) {
|
||||
colorRGBA = hexColorToRGBA(this.element.commonBackground.color, this.element.commonBackground.alpha)
|
||||
}
|
||||
style['padding'] = (this.element.commonBackground.innerPadding || 0) + 'px'
|
||||
style['border-radius'] = (this.element.commonBackground.borderRadius || 0) + 'px'
|
||||
if (this.element.commonBackground.enable) {
|
||||
if (this.element.commonBackground.backgroundType === 'innerImage' && this.element.commonBackground.innerImage) {
|
||||
style['background'] = `url(${this.element.commonBackground.innerImage}) no-repeat`
|
||||
} else if (this.element.commonBackground.backgroundType === 'outerImage' && this.element.commonBackground.outerImage) {
|
||||
style['background'] = `url(${this.element.commonBackground.outerImage}) no-repeat`
|
||||
} else if (this.element.commonBackground.backgroundType === 'color') {
|
||||
style['background-color'] = hexColorToRGBA(this.element.commonBackground.color, this.element.commonBackground.alpha)
|
||||
if (this.element.commonBackground.backgroundType === 'innerImage' && typeof this.element.commonBackground.innerImage === 'string') {
|
||||
style['background'] = `url(${this.element.commonBackground.innerImage}) no-repeat ${colorRGBA}`
|
||||
} else if (this.element.commonBackground.backgroundType === 'outerImage' && typeof this.element.commonBackground.outerImage === 'string') {
|
||||
style['background'] = `url(${this.element.commonBackground.outerImage}) no-repeat ${colorRGBA}`
|
||||
} else {
|
||||
style['background-color'] = colorRGBA
|
||||
}
|
||||
} else {
|
||||
style['background-color'] = colorRGBA
|
||||
}
|
||||
}
|
||||
return style
|
||||
@ -1741,8 +1770,8 @@ export default {
|
||||
removeEvent(document.documentElement, 'touchend touchcancel', this.deselect)
|
||||
removeEvent(window, 'resize', this.checkParentSize)
|
||||
},
|
||||
showViewDetails() {
|
||||
this.$emit('showViewDetails')
|
||||
showViewDetails(params) {
|
||||
this.$emit('showViewDetails', params)
|
||||
},
|
||||
amAddItem() {
|
||||
this.$emit('amAddItem')
|
||||
@ -1769,7 +1798,7 @@ export default {
|
||||
.vdr {
|
||||
touch-action: none;
|
||||
position: absolute;
|
||||
transform-style:preserve-3d;
|
||||
transform-style: preserve-3d;
|
||||
border: 1px
|
||||
}
|
||||
|
||||
@ -1781,30 +1810,39 @@ export default {
|
||||
border-radius: 50%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.handle-tl {
|
||||
cursor: nw-resize;
|
||||
}
|
||||
|
||||
.handle-tm {
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.handle-tr {
|
||||
cursor: ne-resize;
|
||||
}
|
||||
|
||||
.handle-ml {
|
||||
cursor: w-resize;
|
||||
}
|
||||
|
||||
.handle-mr {
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.handle-bl {
|
||||
cursor: sw-resize;
|
||||
}
|
||||
|
||||
.handle-bm {
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.handle-br {
|
||||
cursor: se-resize;
|
||||
}
|
||||
|
||||
/* 新增 旋转控制柄 */
|
||||
|
||||
.handle-rot {
|
||||
@ -1817,6 +1855,7 @@ export default {
|
||||
text-indent: -9999px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.handle-rot:before,
|
||||
.handle-rot:after {
|
||||
content: "";
|
||||
@ -1826,6 +1865,7 @@ export default {
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.handle-rot:before {
|
||||
/* display: block; */
|
||||
width: 1em;
|
||||
@ -1834,6 +1874,7 @@ export default {
|
||||
border-right-color: transparent;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.handle-rot:after {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
@ -1849,29 +1890,30 @@ export default {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.linkageSetting{
|
||||
.linkageSetting {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.batchSetting{
|
||||
.batchSetting {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.positionChange{
|
||||
.positionChange {
|
||||
transition: 0.2s
|
||||
}
|
||||
|
||||
.de-drag-active{
|
||||
.de-drag-active {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.de-drag-active-inner{
|
||||
.de-drag-active-inner {
|
||||
outline: 1px solid #70c0ff;
|
||||
}
|
||||
.main-background{
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
|
||||
.main-background {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div class="main-shadow" style="z-index:-1" :style="styleInfo">
|
||||
<!-- {{ curComponent }}-->
|
||||
</div>
|
||||
<div class="main-shadow" style="z-index:-1" :style="styleInfo" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -31,7 +29,6 @@ export default {
|
||||
width = this.dragComponentInfo.style.width
|
||||
height = this.dragComponentInfo.style.height
|
||||
}
|
||||
|
||||
} else {
|
||||
// temp 临时测试
|
||||
// left = this.curComponent.style.left * this.curCanvasScale.scaleWidth / 100
|
||||
|
@ -6,14 +6,20 @@
|
||||
{{ item.name }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-tag>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
|
||||
<el-dropdown-item v-if="isSortWidget" :disabled="disabledSort" :command="beforeClickItem('none')">
|
||||
<span class="de-sort-menu" :class="!disabledSort && (!sortNode || sortNode.sort === 'none') ? 'de-active-li': ''">{{ $t('chart.none') }}</span>
|
||||
<span
|
||||
class="de-sort-menu"
|
||||
:class="!disabledSort && (!sortNode || sortNode.sort === 'none') ? 'de-active-li': ''"
|
||||
>{{
|
||||
$t('chart.none')
|
||||
}}</span>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="isSortWidget" :disabled="disabledSort" :command="beforeClickItem('asc')">
|
||||
|
||||
<span v-popover:popoverasc class="el-dropdown-link inner-dropdown-menu de-sort-menu" :class="!disabledSort && sortNode.sort === 'asc' ? 'de-active-li': ''">
|
||||
<span
|
||||
v-popover:popoverasc
|
||||
class="el-dropdown-link inner-dropdown-menu de-sort-menu"
|
||||
:class="!disabledSort && sortNode.sort === 'asc' ? 'de-active-li': ''"
|
||||
>
|
||||
<span>
|
||||
<span>{{ $t('chart.asc') }}</span>
|
||||
</span>
|
||||
@ -28,7 +34,6 @@
|
||||
trigger="hover"
|
||||
>
|
||||
<ul class="de-ul">
|
||||
|
||||
<li
|
||||
v-for="(node, i) in allFields"
|
||||
:key="node.id"
|
||||
@ -39,14 +44,15 @@
|
||||
>
|
||||
<span>{{ node.name }}</span>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</el-popover>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="isSortWidget" :disabled="disabledSort" :command="beforeClickItem('desc')">
|
||||
|
||||
<span v-popover:popoverdesc class="el-dropdown-link inner-dropdown-menu de-sort-menu" :class="!disabledSort && sortNode.sort === 'desc' ? 'de-active-li': ''">
|
||||
<span
|
||||
v-popover:popoverdesc
|
||||
class="el-dropdown-link inner-dropdown-menu de-sort-menu"
|
||||
:class="!disabledSort && sortNode.sort === 'desc' ? 'de-active-li': ''"
|
||||
>
|
||||
<span>
|
||||
<span>{{ $t('chart.desc') }}</span>
|
||||
</span>
|
||||
@ -61,7 +67,6 @@
|
||||
trigger="hover"
|
||||
>
|
||||
<ul class="de-ul">
|
||||
|
||||
<li
|
||||
v-for="(node, i) in allFields"
|
||||
:key="node.id"
|
||||
@ -72,14 +77,9 @@
|
||||
>
|
||||
<span>{{ node.name }}</span>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</el-popover>
|
||||
</el-dropdown-item>
|
||||
<!-- <el-dropdown-item :disabled="index" :command="beforeClickItem('customSort')">
|
||||
<span class="de-sort-menu" :class="sortNode.sort === 'custom' ? 'de-active-li': ''">{{ $t('chart.custom_sort') }}</span>
|
||||
</el-dropdown-item> -->
|
||||
<el-dropdown-item :divided="isSortWidget" icon="el-icon-delete" :command="beforeClickItem('remove')">
|
||||
<span class="de-delete-field">{{ $t('chart.delete') }}</span>
|
||||
</el-dropdown-item>
|
||||
@ -137,7 +137,6 @@ export default {
|
||||
created() {
|
||||
if (!this.sortNode) {
|
||||
this.sortNode = this.sort && this.sort.id ? JSON.parse(JSON.stringify(this.sort)) : JSON.parse(JSON.stringify(this.defaultSortProp))
|
||||
// this.sortChange('none')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -199,67 +198,72 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.item-axis {
|
||||
padding: 1px 6px;
|
||||
margin: 0 3px 2px 3px;
|
||||
text-align: left;
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
.item-axis {
|
||||
padding: 1px 6px;
|
||||
margin: 0 3px 2px 3px;
|
||||
text-align: left;
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.item-axis:hover {
|
||||
background-color: #fdfdfd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.de-ul li {
|
||||
margin: 5px 2px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
border-color: rgb(198, 226, 255);
|
||||
background-color: rgb(236, 245, 255);
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-axis:hover {
|
||||
background-color: #fdfdfd;
|
||||
cursor: pointer;
|
||||
.de-active-li {
|
||||
&:before {
|
||||
background: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
.de-ul li {
|
||||
margin: 5px 2px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
border-color: rgb(198, 226, 255);
|
||||
background-color: rgb(236, 245, 255);
|
||||
}
|
||||
&:before {
|
||||
content: "";
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.de-active-li {
|
||||
&:before {
|
||||
background: #409EFF;
|
||||
}
|
||||
}
|
||||
.de-sort-menu::before {
|
||||
content: "";
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.de-delete-field {
|
||||
margin-left: 4px;
|
||||
}
|
||||
.de-sort-field-span {
|
||||
/* width: 80px;
|
||||
max-width: 80px; */
|
||||
display: inline-flexbox;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.de-sort-menu::before {
|
||||
content: "";
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.de-delete-field {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.de-sort-field-span {
|
||||
display: inline-flexbox;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
|
@ -5,8 +5,8 @@
|
||||
@click="handleClick"
|
||||
@mousedown="elementMouseDown"
|
||||
>
|
||||
<div :style="commonStyle" class="main_view">
|
||||
<edit-bar v-if="componentActiveFlag" :element="config" @showViewDetails="showViewDetails" />
|
||||
<edit-bar v-if="componentActiveFlag" :element="config" @showViewDetails="showViewDetails" />
|
||||
<div :id="componentCanvasId" :style="commonStyle" class="main_view">
|
||||
<close-bar v-if="previewVisible" @closePreview="closePreview" />
|
||||
<de-out-widget
|
||||
v-if="config.type==='custom'"
|
||||
@ -110,6 +110,13 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
componentCanvasId() {
|
||||
if (this.config.type === 'view') {
|
||||
return 'user-view-' + this.config.propValue.viewId
|
||||
} else {
|
||||
return 'components-' + this.config.id
|
||||
}
|
||||
},
|
||||
commonStyle() {
|
||||
const style = {
|
||||
width: '100%',
|
||||
@ -118,25 +125,31 @@ export default {
|
||||
if (this.config.commonBackground) {
|
||||
style['padding'] = (this.config.commonBackground.innerPadding || 0) + 'px'
|
||||
style['border-radius'] = (this.config.commonBackground.borderRadius || 0) + 'px'
|
||||
let colorRGBA = ''
|
||||
if (this.config.commonBackground.backgroundColorSelect) {
|
||||
colorRGBA = hexColorToRGBA(this.config.commonBackground.color, this.config.commonBackground.alpha)
|
||||
}
|
||||
if (this.config.commonBackground.enable) {
|
||||
if (this.config.commonBackground.backgroundType === 'innerImage' && this.config.commonBackground.innerImage) {
|
||||
if (this.config.commonBackground.backgroundType === 'innerImage' && typeof this.config.commonBackground.innerImage === 'string') {
|
||||
let innerImage = this.config.commonBackground.innerImage
|
||||
if (this.screenShot) {
|
||||
innerImage = innerImage.replace('svg', 'png')
|
||||
}
|
||||
style['background'] = `url(${innerImage}) no-repeat`
|
||||
} else if (this.config.commonBackground.backgroundType === 'outerImage' && this.config.commonBackground.outerImage) {
|
||||
style['background'] = `url(${this.config.commonBackground.outerImage}) no-repeat`
|
||||
} else if (this.config.commonBackground.backgroundType === 'color') {
|
||||
style['background-color'] = hexColorToRGBA(this.config.commonBackground.color, this.config.commonBackground.alpha)
|
||||
style['background'] = `url(${innerImage}) no-repeat ${colorRGBA}`
|
||||
} else if (this.config.commonBackground.backgroundType === 'outerImage' && typeof this.config.commonBackground.outerImage === 'string') {
|
||||
style['background'] = `url(${this.config.commonBackground.outerImage}) no-repeat ${colorRGBA}`
|
||||
} else {
|
||||
style['background-color'] = colorRGBA
|
||||
}
|
||||
} else {
|
||||
style['background-color'] = colorRGBA
|
||||
}
|
||||
style['overflow'] = 'hidden'
|
||||
}
|
||||
return style
|
||||
},
|
||||
componentActiveFlag() {
|
||||
return (this.curComponent && this.config === this.curComponent) && !this.previewVisible
|
||||
return (this.curComponent && this.config === this.curComponent) && !this.previewVisible && !this.showPosition.includes('multiplexing')
|
||||
},
|
||||
curGap() {
|
||||
return (this.canvasStyleData.panel.gap === 'yes' && this.config.auxiliaryMatrix) ? this.componentGap : 0
|
||||
@ -224,8 +237,8 @@ export default {
|
||||
e.stopPropagation()
|
||||
this.$store.commit('setCurComponent', { component: this.config, index: this.index })
|
||||
},
|
||||
showViewDetails() {
|
||||
this.$refs.wrapperChild.openChartDetailsDialog()
|
||||
showViewDetails(params) {
|
||||
this.$refs.wrapperChild.openChartDetailsDialog(params)
|
||||
},
|
||||
closePreview() {
|
||||
this.previewVisible = false
|
||||
|
@ -24,7 +24,10 @@
|
||||
<i v-if="activeModel==='edit'&&!curComponent.auxiliaryMatrix" class="icon iconfont icon-xuanfuanniu" @click.stop="auxiliaryMatrixChange" />
|
||||
</span>
|
||||
<span :title="$t('panel.details')">
|
||||
<i v-if="curComponent.type==='view'" class="icon iconfont icon-fangda" @click.stop="showViewDetails" />
|
||||
<i v-if="curComponent.type==='view'" class="icon iconfont icon-chakan" @click.stop="showViewDetails('details')" />
|
||||
</span>
|
||||
<span :title="$t('panel.enlarge')">
|
||||
<i v-if="curComponent.type==='view'" class="icon iconfont icon-fangda" @click.stop="showViewDetails('enlarge')" />
|
||||
</span>
|
||||
<span :title="$t('panel.cancel_linkage')">
|
||||
<i v-if="curComponent.type==='view'&&existLinkage" class="icon iconfont icon-quxiaoliandong" @click.stop="clearLinkage" />
|
||||
@ -154,12 +157,8 @@ export default {
|
||||
this.timer = null
|
||||
}
|
||||
},
|
||||
showViewDetails() {
|
||||
this.$emit('showViewDetails')
|
||||
},
|
||||
componentJump() {
|
||||
window.open(url, '_blank')
|
||||
// this.$emit('showViewDetails')
|
||||
showViewDetails(openType = 'details') {
|
||||
this.$emit('showViewDetails', { openType: openType })
|
||||
},
|
||||
auxiliaryMatrixChange() {
|
||||
if (this.curComponent.auxiliaryMatrix) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
<i class="icon iconfont icon-edit" @click.stop="edit" />
|
||||
</span>
|
||||
<span :title="$t('panel.details')">
|
||||
<i class="icon iconfont icon-fangda" @click.stop="showViewDetails" />
|
||||
<i class="icon iconfont icon-chakan" @click.stop="showViewDetails('details')" />
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="positionCheck('multiplexing')" style="margin-right: -1px;width: 18px;z-index: 5">
|
||||
@ -87,8 +87,8 @@ export default {
|
||||
amRemoveItem() {
|
||||
this.$emit('amRemoveItem')
|
||||
},
|
||||
showViewDetails() {
|
||||
this.$emit('showViewDetails')
|
||||
showViewDetails(params) {
|
||||
this.$emit('showViewDetails', params)
|
||||
},
|
||||
positionCheck(position) {
|
||||
return this.showPosition.includes(position)
|
||||
|
@ -37,22 +37,20 @@
|
||||
<el-dialog
|
||||
:title="$t('chart.chart_details')"
|
||||
:visible.sync="chartDetailsVisible"
|
||||
width="70%"
|
||||
width="80%"
|
||||
class="dialog-css"
|
||||
:destroy-on-close="true"
|
||||
top="5vh"
|
||||
>
|
||||
<span v-if="chartDetailsVisible" style="position: absolute;right: 70px;top:15px">
|
||||
<el-dropdown>
|
||||
<el-button size="mini">
|
||||
{{ $t('chart.export') }}<i class="el-icon-download" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="exportExcel"><svg-icon icon-class="ds-excel" class="ds-icon-excel" />Excel</el-dropdown-item>
|
||||
<el-dropdown-item v-if="showExportImgButton" icon="el-icon-picture-outline" @click.native="exportViewImg">{{ $t('chart.image') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button v-if="showChartInfoType==='enlarge'" class="el-icon-picture-outline" size="mini" @click="exportViewImg">
|
||||
{{ $t('chart.export_img') }}
|
||||
</el-button>
|
||||
<el-button v-if="showChartInfoType==='details'" size="mini" @click="exportExcel">
|
||||
<svg-icon icon-class="ds-excel" class="ds-icon-excel" />{{ $t('chart.export') }}Excel
|
||||
</el-button>
|
||||
</span>
|
||||
<UserViewDialog v-if="chartDetailsVisible" ref="userViewDialog" :chart="showChartInfo" :chart-table="showChartTableInfo" />
|
||||
<UserViewDialog v-if="chartDetailsVisible" ref="userViewDialog" :open-type="showChartInfoType" :chart="showChartInfo" :chart-table="showChartTableInfo" />
|
||||
</el-dialog>
|
||||
|
||||
<!--手机视图详情-->
|
||||
@ -84,6 +82,8 @@ import UserViewMobileDialog from '@/components/canvas/custom-component/UserViewM
|
||||
import bus from '@/utils/bus'
|
||||
import { buildFilterMap } from '@/utils/conditionUtil'
|
||||
import { hasDataPermission } from '@/utils/permission'
|
||||
const erd = elementResizeDetectorMaker()
|
||||
|
||||
export default {
|
||||
components: { UserViewMobileDialog, ComponentWrapper, UserViewDialog, CanvasOptBar },
|
||||
model: {
|
||||
@ -169,11 +169,16 @@ export default {
|
||||
mobileChartDetailsVisible: false,
|
||||
showChartInfo: {},
|
||||
showChartTableInfo: {},
|
||||
showChartInfoType: 'details',
|
||||
// 布局展示 1.pc pc端布局 2.mobile 移动端布局
|
||||
terminal: 'pc'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 取消视图请求
|
||||
this.$cancelRequest('/chart/view/getData/**')
|
||||
this.$cancelRequest('/api/link/viewDetail/**')
|
||||
this.$cancelRequest('/static-resource/**')
|
||||
},
|
||||
computed: {
|
||||
mainActiveName() {
|
||||
@ -189,9 +194,6 @@ export default {
|
||||
return this.panelInfo.status === 'unpublished'
|
||||
}
|
||||
},
|
||||
showExportImgButton() {
|
||||
return this.showChartInfo.type && !this.showChartInfo.type.includes('table')
|
||||
},
|
||||
canvasInfoMainStyle() {
|
||||
if (this.backScreenShot) {
|
||||
return {
|
||||
@ -273,37 +275,17 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this._isMobile()
|
||||
const _this = this
|
||||
const erd = elementResizeDetectorMaker()
|
||||
const canvasMain = document.getElementById('canvasInfoMain')
|
||||
// 监听主div变动事件
|
||||
if (canvasMain) {
|
||||
erd.listenTo(canvasMain, element => {
|
||||
_this.$nextTick(() => {
|
||||
_this.restore()
|
||||
})
|
||||
})
|
||||
}
|
||||
// 监听画布div变动事件
|
||||
const tempCanvas = document.getElementById('canvasInfoTemp')
|
||||
if (tempCanvas) {
|
||||
erd.listenTo(document.getElementById('canvasInfoTemp'), element => {
|
||||
_this.$nextTick(() => {
|
||||
// 将mainHeight 修改为px 临时解决html2canvas 截图不全的问题
|
||||
_this.mainHeight = tempCanvas.scrollHeight + 'px!important'
|
||||
this.$emit('mainHeightChange', _this.mainHeight)
|
||||
})
|
||||
})
|
||||
}
|
||||
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||
_this.$store.commit('clearLinkageSettingInfo', false)
|
||||
_this.canvasStyleDataInit()
|
||||
this.initListen()
|
||||
this.$store.commit('clearLinkageSettingInfo', false)
|
||||
this.canvasStyleDataInit()
|
||||
// 如果当前终端设备是移动端,则进行移动端的布局设计
|
||||
if (_this.terminal === 'mobile') {
|
||||
_this.initMobileCanvas()
|
||||
if (this.terminal === 'mobile') {
|
||||
this.initMobileCanvas()
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
erd.uninstall(this.$refs.canvasInfoTemp)
|
||||
erd.uninstall(this.$refs.canvasInfoMain)
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
@ -378,6 +360,7 @@ export default {
|
||||
openChartDetailsDialog(chartInfo) {
|
||||
this.showChartInfo = chartInfo.chart
|
||||
this.showChartTableInfo = chartInfo.tableChart
|
||||
this.showChartInfoType = chartInfo.openType
|
||||
if (this.terminal === 'pc') {
|
||||
this.chartDetailsVisible = true
|
||||
} else {
|
||||
@ -403,6 +386,33 @@ export default {
|
||||
},
|
||||
canvasScroll() {
|
||||
bus.$emit('onScroll')
|
||||
},
|
||||
initListen() {
|
||||
const _this = this
|
||||
const canvasMain = document.getElementById('canvasInfoMain')
|
||||
// 监听主div变动事件
|
||||
if (canvasMain) {
|
||||
erd.listenTo(canvasMain, element => {
|
||||
_this.$nextTick(() => {
|
||||
_this.restore()
|
||||
})
|
||||
})
|
||||
}
|
||||
setTimeout(() => {
|
||||
// 监听画布div变动事件
|
||||
const tempCanvas = document.getElementById('canvasInfoTemp')
|
||||
if (tempCanvas) {
|
||||
erd.listenTo(document.getElementById('canvasInfoTemp'), element => {
|
||||
_this.$nextTick(() => {
|
||||
// 将mainHeight 修改为px 临时解决html2canvas 截图不全的问题
|
||||
_this.mainHeight = tempCanvas.scrollHeight + 'px!important'
|
||||
this.$emit('mainHeightChange', _this.mainHeight)
|
||||
})
|
||||
})
|
||||
}
|
||||
}, 1500)
|
||||
|
||||
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,19 @@
|
||||
<el-dropdown-item v-if="editFilter.includes(curComponent.type)" icon="el-icon-edit-outline" @click.native="edit">{{ $t('panel.edit') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-document-copy" @click.native="copy">{{ $t('panel.copy') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-delete" @click.native="deleteComponent">{{ $t('panel.delete') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-upload2" @click.native="topComponent">{{ $t('panel.topComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-download" @click.native="bottomComponent">{{ $t('panel.bottomComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-arrow-up" @click.native="upComponent">{{ $t('panel.upComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-arrow-down" @click.native="downComponent">{{ $t('panel.downComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item v-if="!curComponent.auxiliaryMatrix">
|
||||
<el-dropdown placement="right-start">
|
||||
<span class="el-icon-copy-document">
|
||||
{{ $t('panel.level') }} <i class="el-icon-arrow-right el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-upload2" @click.native="topComponent">{{ $t('panel.topComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-download" @click.native="bottomComponent">{{ $t('panel.bottomComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-arrow-up" @click.native="upComponent">{{ $t('panel.upComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-arrow-down" @click.native="downComponent">{{ $t('panel.downComponent') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="'view'===curComponent.type" icon="el-icon-link" @click.native="linkageSetting">{{ $t('panel.linkage_setting') }}</el-dropdown-item>
|
||||
<el-dropdown-item v-if="'de-tabs'===curComponent.type" icon="el-icon-plus" @click.native="addTab">{{ $t('panel.add_tab') }}</el-dropdown-item>
|
||||
<el-dropdown-item v-if="'view'===curComponent.type" icon="el-icon-connection" @click.native="linkJumpSet">{{ $t('panel.setting_jump') }}</el-dropdown-item>
|
||||
@ -56,12 +65,8 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'menuTop',
|
||||
'menuLeft',
|
||||
'menuShow',
|
||||
'curComponent',
|
||||
'componentData',
|
||||
'canvasStyleData'
|
||||
'componentData'
|
||||
]),
|
||||
methods: {
|
||||
edit() {
|
||||
|
@ -45,7 +45,7 @@
|
||||
:linkage-active="linkageActiveCheck(item)"
|
||||
:batch-opt-active="batchOptActiveCheck(item)"
|
||||
@refLineParams="getRefLineParams"
|
||||
@showViewDetails="showViewDetails(index)"
|
||||
@showViewDetails="showViewDetails($event,index)"
|
||||
@resizeView="resizeView(index,item)"
|
||||
@onResizeStart="startResize"
|
||||
@onDragStart="onStartMove"
|
||||
@ -137,27 +137,26 @@
|
||||
<el-dialog
|
||||
:title="$t('chart.chart_details')"
|
||||
:visible.sync="chartDetailsVisible"
|
||||
width="70%"
|
||||
width="80%"
|
||||
class="dialog-css"
|
||||
:destroy-on-close="true"
|
||||
:show-close="true"
|
||||
top="5vh"
|
||||
>
|
||||
<span v-if="chartDetailsVisible" style="position: absolute;right: 70px;top:15px">
|
||||
<el-dropdown>
|
||||
<el-button size="mini">
|
||||
{{ $t('chart.export') }}<i class="el-icon-download" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="exportExcel"><svg-icon icon-class="ds-excel" class="ds-icon-excel" />Excel</el-dropdown-item>
|
||||
<el-dropdown-item v-if="showExportImgButton" icon="el-icon-picture-outline" @click.native="exportViewImg">{{ $t('chart.image') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button v-if="showChartInfoType==='enlarge'" class="el-icon-picture-outline" size="mini" @click="exportViewImg">
|
||||
{{ $t('chart.export_img') }}
|
||||
</el-button>
|
||||
<el-button v-if="showChartInfoType==='details'" size="mini" @click="exportExcel">
|
||||
<svg-icon icon-class="ds-excel" class="ds-icon-excel" />{{ $t('chart.export') }}Excel
|
||||
</el-button>
|
||||
</span>
|
||||
<UserViewDialog
|
||||
v-if="chartDetailsVisible"
|
||||
ref="userViewDialog"
|
||||
:chart="showChartInfo"
|
||||
:chart-table="showChartTableInfo"
|
||||
:open-type="showChartInfoType"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
@ -769,7 +768,7 @@ function findBelowItems(item) {
|
||||
break
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('positionBox igonre')
|
||||
console.error('positionBox igonre', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -912,6 +911,7 @@ export default {
|
||||
chartDetailsVisible: false,
|
||||
showChartInfo: {},
|
||||
showChartTableInfo: {},
|
||||
showChartInfoType: 'details',
|
||||
// 挤占式画布设计
|
||||
baseWidth: 100,
|
||||
baseHeight: 100,
|
||||
@ -1351,6 +1351,7 @@ export default {
|
||||
openChartDetailsDialog(chartInfo) {
|
||||
this.showChartInfo = chartInfo.chart
|
||||
this.showChartTableInfo = chartInfo.tableChart
|
||||
this.showChartInfoType = chartInfo.openType
|
||||
this.chartDetailsVisible = true
|
||||
},
|
||||
exportExcel() {
|
||||
@ -1359,8 +1360,8 @@ export default {
|
||||
exportViewImg() {
|
||||
this.$refs['userViewDialog'].exportViewImg()
|
||||
},
|
||||
showViewDetails(index) {
|
||||
this.$refs.wrapperChild[index].openChartDetailsDialog()
|
||||
showViewDetails(params, index) {
|
||||
this.$refs.wrapperChild[index].openChartDetailsDialog(params)
|
||||
},
|
||||
|
||||
resizeView(index, item) {
|
||||
|
@ -1,5 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="switch-position">
|
||||
<el-radio-group v-model="mobileLayoutInitStatus" size="mini" @change="openMobileLayout">
|
||||
<el-radio-button :label="false">
|
||||
<span style="float: left;">
|
||||
<i class="el-icon-monitor" />
|
||||
</span>
|
||||
</el-radio-button>
|
||||
<el-radio-button :label="true">
|
||||
<span class="icon iconfont icon-yidongduan" />
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div v-show="editControlButton" class="toolbar">
|
||||
<span style="float: right;">
|
||||
<el-button v-if="mobileLayoutStatus" size="mini" @click="editReset">
|
||||
@ -13,55 +25,86 @@
|
||||
</el-button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-show="!editControlButton" class="toolbar">
|
||||
<el-tooltip :content="$t('panel.mobile_layout')">
|
||||
<el-button class="icon iconfont-tb icon-yidongduan" size="mini" circle @click="openMobileLayout" />
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="!canvasStyleData.auxiliaryMatrix" :content="$t('panel.new_element_distribution')+':'+$t('panel.suspension')">
|
||||
<el-button class="icon iconfont-tb icon-xuanfuanniu" size="mini" circle @click="auxiliaryMatrixChange" />
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="canvasStyleData.auxiliaryMatrix" :content="$t('panel.new_element_distribution')+':'+$t('panel.matrix')">
|
||||
<el-button class="icon iconfont-tb icon-shujujuzhen" size="mini" circle @click="auxiliaryMatrixChange" />
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('panel.style')">
|
||||
<el-button class="el-icon-magic-stick" size="mini" circle @click="showPanel" />
|
||||
</el-tooltip>
|
||||
<div class="panel-info-area">
|
||||
<el-tooltip :content="$t('panel.back') ">
|
||||
<span class="icon iconfont icon-jiantou insert" @click="closePanelEdit" />
|
||||
</el-tooltip>
|
||||
<span class="text">
|
||||
{{ panelInfo.name }}
|
||||
</span>
|
||||
</div>
|
||||
<el-tooltip :content="$t('panel.undo') ">
|
||||
<el-button class="el-icon-refresh-right" size="mini" circle @click="undo" />
|
||||
<span class="icon iconfont icon-outline-undo insert" @click="undo" />
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('panel.redo') ">
|
||||
<el-button class="el-icon-refresh-left" size="mini" circle @click="redo" />
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('panel.clean_canvas')">
|
||||
<el-button class="el-icon-document-delete" size="mini" circle @click="clearCanvas" />
|
||||
<span class="icon iconfont icon-outline-redo insert" @click="redo" />
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('panel.fullscreen_preview')">
|
||||
<el-button class="el-icon-view" size="mini" circle @click="clickPreview" />
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('panel.params_setting')">
|
||||
<el-button class="icon iconfont-tb icon-canshu" size="mini" circle @click="openOuterParamsSet" />
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="!canvasStyleData.aidedDesign.showGrid" :content="$t('panel.aided_grid')+':'+$t('panel.aided_grid_close')">
|
||||
<el-button class="icon iconfont-tb icon-wangge-close" size="mini" circle @click="showGridChange" />
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="canvasStyleData.aidedDesign.showGrid" :content="$t('panel.aided_grid')+':'+$t('panel.aided_grid_open')">
|
||||
<el-button class="icon iconfont-tb icon-wangge-open" size="mini" circle @click="showGridChange" />
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('panel.batch_opt')">
|
||||
<el-button class="icon iconfont-tb icon-piliang-copy" size="mini" circle @click="batchOption" />
|
||||
<span class="icon iconfont icon-fangda insert" @click="clickPreview" />
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" />
|
||||
|
||||
<span class="button_self">
|
||||
<el-dropdown :hide-on-click="false" trigger="click" placement="bottom-start" size="mini">
|
||||
<span class="icon iconfont icon-gengduo insert de-icon-base"><span class="icon-font-margin">{{ $t('panel.more') }}</span></span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>
|
||||
<el-dropdown placement="right-start" size="mini" style="width: 100%">
|
||||
<span>
|
||||
<span
|
||||
class="icon iconfont"
|
||||
:class="[canvasStyleData.auxiliaryMatrix?'icon-shujujuzhen':'icon-xuanfuanniu']"
|
||||
/>
|
||||
<span class="icon-font-margin" style="font-size: 12px">{{ $t('panel.new_element_distribution') }}</span>
|
||||
<i class="el-icon-arrow-right el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="auxiliaryMatrixChange">
|
||||
<span :class="[!canvasStyleData.auxiliaryMatrix?'font-active':'']"> {{ $t('panel.suspension') }} </span>
|
||||
<i v-if="!canvasStyleData.auxiliaryMatrix" class=" font-active el-icon-check" />
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="auxiliaryMatrixChange">
|
||||
<span :class="[canvasStyleData.auxiliaryMatrix?'font-active':'']"> {{ $t('panel.matrix') }} </span>
|
||||
<i v-if="canvasStyleData.auxiliaryMatrix" class=" font-active el-icon-check" />
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<span class="icon iconfont-tb" :class="[canvasStyleData.aidedDesign.showGrid?'icon-wangge-open':'icon-wangge-close']" />
|
||||
<span class="icon-font-margin">{{ $t('panel.aided_grid') }}</span>
|
||||
<el-switch v-model="showGridSwitch" size="mini" @change="showGridChange" />
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="openOuterParamsSet">
|
||||
<span class="icon iconfont-tb icon-canshu" />
|
||||
<span class="icon-font-margin">{{ $t('panel.params_setting') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clearCanvas">
|
||||
<span class="icon iconfont-tb icon-qingkong" />
|
||||
<span class="icon-font-margin">{{ $t('panel.clean_canvas') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
<span class="icon iconfont icon-magic-line insert" @click="showPanel"><span class="icon-font-margin">{{ $t('panel.panel_style') }}</span></span>
|
||||
<span class="icon iconfont icon-piliang-copy insert" @click="batchOption"><span class="icon-font-margin">{{ $t('panel.batch_opt') }}</span></span>
|
||||
<span style="float: right;margin-left: 10px">
|
||||
<el-button size="mini" type="primary" :disabled="saveButtonDisabled" @click="save(false)">
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
<el-button size="mini" @click="closePanelEdit">
|
||||
{{ $t('commons.close') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!--关闭弹框-->
|
||||
<el-dialog :visible.sync="closePanelVisible" :title="$t('panel.panel_save_tips')" :show-close="false" width="30%" class="dialog-css">
|
||||
<el-dialog
|
||||
:visible.sync="closePanelVisible"
|
||||
:title="$t('panel.panel_save_tips')"
|
||||
:show-close="false"
|
||||
width="30%"
|
||||
class="dialog-css"
|
||||
>
|
||||
<el-row style="height: 20px">
|
||||
<el-col :span="4">
|
||||
<svg-icon icon-class="warn-tre" style="width: 20px;height: 20px;float: right" />
|
||||
@ -103,6 +146,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showGridSwitch: false,
|
||||
mobileLayoutInitStatus: false,
|
||||
isShowPreview: false,
|
||||
needToChange: [
|
||||
'top',
|
||||
@ -119,6 +164,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
panelInfo() {
|
||||
return this.$store.state.panel.panelInfo
|
||||
},
|
||||
saveButtonDisabled() {
|
||||
return this.changeTimes === 0 || this.snapshotIndex === this.lastSaveSnapshotIndex
|
||||
},
|
||||
@ -147,6 +195,8 @@ export default {
|
||||
eventBus.$on('save', this.save)
|
||||
eventBus.$on('clearCanvas', this.clearCanvas)
|
||||
this.scale = this.canvasStyleData.scale
|
||||
this.mobileLayoutInitStatus = this.mobileLayoutStatus
|
||||
this.showGridSwitch = this.canvasStyleData.aidedDesign.showGrid
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
@ -277,14 +327,18 @@ export default {
|
||||
this.$store.commit('clearPanelLinkageInfo')
|
||||
// 保存到数据库
|
||||
const requestInfo = {
|
||||
id: this.$store.state.panel.panelInfo.id,
|
||||
id: this.panelInfo.id,
|
||||
panelStyle: JSON.stringify(this.canvasStyleData),
|
||||
panelData: JSON.stringify(this.componentData)
|
||||
}
|
||||
const components = deepCopy(this.componentData)
|
||||
components.forEach(view => {
|
||||
if (view.DetailAreaCode) { view.DetailAreaCode = null }
|
||||
if (view.filters && view.filters.length > 0) { view.filters = [] }
|
||||
if (view.DetailAreaCode) {
|
||||
view.DetailAreaCode = null
|
||||
}
|
||||
if (view.filters && view.filters.length > 0) {
|
||||
view.filters = []
|
||||
}
|
||||
if (view.type === 'de-tabs') {
|
||||
view.options.tabList && view.options.tabList.length > 0 && view.options.tabList.forEach(tab => {
|
||||
if (tab.content && tab.content.filters && tab.content.filters.length > 0) {
|
||||
@ -311,6 +365,7 @@ export default {
|
||||
this.$store.commit('setComponentData', [])
|
||||
this.$store.commit('setCanvasStyle', DEFAULT_COMMON_CANVAS_STYLE_STRING)
|
||||
this.$store.commit('recordSnapshot', 'clearCanvas')
|
||||
this.$store.commit('setInEditorStatus', false)
|
||||
},
|
||||
|
||||
handlePreviewChange() {
|
||||
@ -353,18 +408,18 @@ export default {
|
||||
}
|
||||
}
|
||||
const request = {
|
||||
panelId: this.$store.state.panel.panelInfo.id,
|
||||
panelId: this.panelInfo.id,
|
||||
sourceViewId: this.curLinkageView.propValue.viewId,
|
||||
linkageInfo: this.targetLinkageInfo
|
||||
}
|
||||
saveLinkage(request).then(rsp => {
|
||||
// 刷新联动信息
|
||||
getPanelAllLinkageInfo(this.$store.state.panel.panelInfo.id).then(rsp => {
|
||||
getPanelAllLinkageInfo(this.panelInfo.id).then(rsp => {
|
||||
this.$store.commit('setNowPanelTrackInfo', rsp.data)
|
||||
})
|
||||
this.cancelLinkageSettingStatus()
|
||||
// 刷新跳转信息
|
||||
queryPanelJumpInfo(this.$store.state.panel.panelInfo.id).then(rsp => {
|
||||
queryPanelJumpInfo(this.panelInfo.id).then(rsp => {
|
||||
this.$store.commit('setNowPanelJumpInfo', rsp.data)
|
||||
})
|
||||
})
|
||||
@ -372,6 +427,7 @@ export default {
|
||||
cancelMobileLayoutStatue(sourceComponentData) {
|
||||
this.$store.commit('setComponentData', sourceComponentData)
|
||||
this.$store.commit('setMobileLayoutStatus', false)
|
||||
this.mobileLayoutInitStatus = false
|
||||
},
|
||||
cancelLinkage() {
|
||||
this.cancelLinkageSettingStatus()
|
||||
@ -392,8 +448,12 @@ export default {
|
||||
this.$store.commit('setBatchOptStatus', !this.batchOptStatus)
|
||||
},
|
||||
// 启用移动端布局
|
||||
openMobileLayout() {
|
||||
this.$store.commit('openMobileLayout')
|
||||
openMobileLayout(switchVal) {
|
||||
if (switchVal) {
|
||||
this.$store.commit('openMobileLayout')
|
||||
} else {
|
||||
this.mobileLayoutSave()
|
||||
}
|
||||
},
|
||||
editSave() {
|
||||
if (this.mobileLayoutStatus) {
|
||||
@ -438,9 +498,10 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.toolbar {
|
||||
float: right;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
min-width: 400px;
|
||||
|
||||
.canvas-config {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
@ -461,11 +522,12 @@ export default {
|
||||
|
||||
.insert {
|
||||
display: inline-block;
|
||||
font-weight: 400 !important;
|
||||
font-size: 14px !important;
|
||||
font-family: PingFang SC;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
background: #FFF;
|
||||
border: 1px solid #DCDFE6;
|
||||
color: var(--TextPrimary, #606266);
|
||||
-webkit-appearance: none;
|
||||
text-align: center;
|
||||
@ -473,15 +535,14 @@ export default {
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
transition: .1s;
|
||||
font-weight: 500;
|
||||
padding: 9px 15px;
|
||||
font-size: 12px;
|
||||
padding: 5px 5px;
|
||||
border-radius: 3px;
|
||||
margin-left: 10px;
|
||||
margin-left: 5px;
|
||||
|
||||
&:active {
|
||||
color: #3a8ee6;
|
||||
color: #000;
|
||||
border-color: #3a8ee6;
|
||||
background-color: red;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
@ -492,23 +553,24 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.button-show{
|
||||
background-color: #ebf2fe!important;
|
||||
.button-show {
|
||||
background-color: #ebf2fe !important;
|
||||
}
|
||||
|
||||
.button-closed{
|
||||
background-color: #ffffff!important;
|
||||
.button-closed {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
::v-deep .el-switch__core {
|
||||
width: 30px !important;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
>>>.el-switch__core{
|
||||
width:30px!important;
|
||||
height:15px;
|
||||
}
|
||||
/*设置圆*/
|
||||
>>>.el-switch__core::after{
|
||||
width:14px;
|
||||
height:14px;
|
||||
margin-top:-1px;
|
||||
::v-deep .el-switch__core::after {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-top: -1px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
@ -520,4 +582,55 @@ export default {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.switch-position {
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
right: 50%;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.button_self {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.button_self ::v-deep .el-button--mini {
|
||||
padding: 7px 7px !important;
|
||||
}
|
||||
|
||||
.font-active {
|
||||
font-color: #3a8ee6 !important;
|
||||
}
|
||||
|
||||
.icon-active {
|
||||
color: #3a8ee6;
|
||||
}
|
||||
|
||||
.icon-unactivated {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel-info-area {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
|
||||
.text {
|
||||
margin-left: 15px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--TextPrimary, #606266);
|
||||
}
|
||||
;
|
||||
|
||||
.icon-back {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: var(--MenuActiveBG, #409EFF);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.icon-font-margin{
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -33,34 +33,6 @@ import 'tinymce/plugins/nonbreaking'
|
||||
import 'tinymce/plugins/pagebreak'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
// const fonts = [
|
||||
// '宋体=宋体',
|
||||
// '微软雅黑=微软雅黑',
|
||||
// '新宋体=新宋体',
|
||||
// '黑体=黑体',
|
||||
// '楷体=楷体',
|
||||
// '隶书=隶书',
|
||||
// 'Courier New=courier new,courier',
|
||||
// 'AkrutiKndPadmini=Akpdmi-n',
|
||||
// 'Andale Mono=andale mono,times',
|
||||
// 'Arial=arial,helvetica,sans-serif',
|
||||
// 'Arial Black=arial black,avant garde',
|
||||
// 'Book Antiqua=book antiqua,palatino',
|
||||
// 'Comic Sans MS=comic sans ms,sans-serif',
|
||||
// 'Courier New=courier new,courier',
|
||||
// 'Georgia=georgia,palatino',
|
||||
// 'Helvetica=helvetica',
|
||||
// 'Impact=impact,chicago',
|
||||
// 'Symbol=symbol',
|
||||
// 'Tahoma=tahoma,arial,helvetica,sans-serif',
|
||||
// 'Terminal=terminal,monaco',
|
||||
// 'Times New Roman=times new roman,times',
|
||||
// 'Trebuchet MS=trebuchet ms,geneva',
|
||||
// 'Verdana=verdana,geneva',
|
||||
// 'Webdings=webdings',
|
||||
// 'Wingdings=wingdings,zapf dingbats'
|
||||
// ]
|
||||
|
||||
export default {
|
||||
name: 'DeRichText',
|
||||
components: {
|
||||
@ -106,7 +78,6 @@ export default {
|
||||
content_css: '/tinymce/skins/content/default/content.css',
|
||||
plugins: 'advlist autolink link image lists charmap media wordcount table contextmenu directionality pagebreak', // 插件
|
||||
// 工具栏
|
||||
// toolbar: 'undo redo | fontsizeselect fontselect | bold italic forecolor backcolor underline strikethrough | alignleft aligncenter alignright | lists image media table link | bullist numlist ',
|
||||
toolbar: 'undo redo |fontselect fontsizeselect |forecolor backcolor bold italic |underline strikethrough link| formatselect |' +
|
||||
'alignleft aligncenter alignright | bullist numlist |' +
|
||||
' blockquote subscript superscript removeformat | table image media | fullscreen ' +
|
||||
|
@ -115,7 +115,7 @@ export default {
|
||||
this.flvPlayer.load()
|
||||
this.flvPlayer.play()
|
||||
} catch (error) {
|
||||
console.log('flvjs err ignore')
|
||||
console.error('flvjs err ignore', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,20 +26,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// custom skin css
|
||||
import '@/custom-theme.css'
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '@/utils/bus'
|
||||
// import SWF_URL from 'videojs-swf/dist/video-js.swf'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
propValue: {
|
||||
type: String,
|
||||
require: true
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
element: {
|
||||
type: Object
|
||||
},
|
||||
@ -124,15 +120,9 @@ export default {
|
||||
},
|
||||
onPlayerCanplaythrough(player) {
|
||||
},
|
||||
|
||||
// or listen state event
|
||||
playerStateChanged(playerCurrentState) {
|
||||
},
|
||||
|
||||
// player is ready
|
||||
playerReadied(player) {
|
||||
// seek to 10s
|
||||
// player.currentTime(10): the player is readied', player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ export default {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
element: {
|
||||
type: Object
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
element: {
|
||||
type: Object
|
||||
}
|
||||
|
@ -149,7 +149,6 @@ export default {
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
componentIndex: {
|
||||
type: Number,
|
||||
required: false
|
||||
@ -390,7 +389,6 @@ export default {
|
||||
}
|
||||
},
|
||||
'chartType': function(newVal, oldVal) {
|
||||
// this.isPlugin = this.plugins.some(plugin => plugin.value === this.chart.type)
|
||||
if ((newVal === 'map' || newVal === 'buddle-map') && newVal !== oldVal) {
|
||||
this.initAreas()
|
||||
}
|
||||
@ -524,7 +522,7 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
getData(id, cache = true) {
|
||||
getData(id, cache = true, dataBroadcast = false) {
|
||||
if (id) {
|
||||
this.requestStatus = 'waiting'
|
||||
this.message = null
|
||||
@ -549,7 +547,7 @@ export default {
|
||||
// 将视图传入echart组件
|
||||
if (response.success) {
|
||||
this.chart = response.data
|
||||
this.getDataOnly(response.data)
|
||||
this.getDataOnly(response.data, dataBroadcast)
|
||||
this.chart['position'] = this.inTab ? 'tab' : 'panel'
|
||||
// 记录当前数据
|
||||
this.panelViewDetailsInfo[id] = JSON.stringify(this.chart)
|
||||
@ -593,7 +591,7 @@ export default {
|
||||
viewIdMatch(viewIds, viewId) {
|
||||
return !viewIds || viewIds.length === 0 || viewIds.includes(viewId)
|
||||
},
|
||||
openChartDetailsDialog() {
|
||||
openChartDetailsDialog(params) {
|
||||
const tableChart = deepCopy(this.chart)
|
||||
tableChart.customAttr = JSON.parse(this.chart.customAttr)
|
||||
tableChart.customStyle = JSON.parse(this.chart.customStyle)
|
||||
@ -604,7 +602,7 @@ export default {
|
||||
tableChart.customStyle.text.show = false
|
||||
tableChart.customAttr = JSON.stringify(tableChart.customAttr)
|
||||
tableChart.customStyle = JSON.stringify(tableChart.customStyle)
|
||||
eventBus.$emit('openChartDetailsDialog', { chart: this.chart, tableChart: tableChart })
|
||||
eventBus.$emit('openChartDetailsDialog', { chart: this.chart, tableChart: tableChart, openType: params.openType })
|
||||
},
|
||||
chartClick(param) {
|
||||
if (this.drillClickDimensionList.length < this.chart.drillFields.length - 1) {
|
||||
@ -845,7 +843,7 @@ export default {
|
||||
getDataEdit(param) {
|
||||
this.$store.state.styleChangeTimes++
|
||||
if (param.type === 'propChange') {
|
||||
this.getData(param.viewId, false)
|
||||
this.getData(param.viewId, false, true)
|
||||
} else if (param.type === 'styleChange') {
|
||||
this.chart.customAttr = param.viewInfo.customAttr
|
||||
this.chart.customStyle = param.viewInfo.customStyle
|
||||
@ -860,7 +858,7 @@ export default {
|
||||
this.mergeScale()
|
||||
}
|
||||
},
|
||||
getDataOnly(sourceResponseData) {
|
||||
getDataOnly(sourceResponseData, dataBroadcast) {
|
||||
if (this.isEdit) {
|
||||
if ((this.filter.filter && this.filter.filter.length) || (this.filter.linkageFilters && this.filter.linkageFilters.length)) {
|
||||
viewData(this.chart.id, this.panelInfo.id, {
|
||||
@ -869,9 +867,15 @@ export default {
|
||||
queryFrom: 'panel'
|
||||
}).then(response => {
|
||||
this.componentViewsData[this.chart.id] = response.data
|
||||
if (dataBroadcast) {
|
||||
bus.$emit('prop-change-data')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.componentViewsData[this.chart.id] = sourceResponseData
|
||||
if (dataBroadcast) {
|
||||
bus.$emit('prop-change-data')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -921,32 +925,4 @@ export default {
|
||||
z-index: 2;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/*.rect-shape > i {*/
|
||||
/* right: 5px;*/
|
||||
/* color: gray;*/
|
||||
/* position: absolute;*/
|
||||
/*}*/
|
||||
|
||||
/*.rect-shape > > > i:hover {*/
|
||||
/* color: red;*/
|
||||
/*}*/
|
||||
|
||||
/*.rect-shape:hover > > > .icon-fangda {*/
|
||||
/* z-index: 2;*/
|
||||
/* display: block;*/
|
||||
/*}*/
|
||||
|
||||
/*.rect-shape > > > .icon-fangda {*/
|
||||
/* display: none*/
|
||||
/*}*/
|
||||
|
||||
/*.rect-shape:hover > > > .icon-shezhi {*/
|
||||
/* z-index: 2;*/
|
||||
/* display: block;*/
|
||||
/*}*/
|
||||
|
||||
/*.rect-shape > > > .icon-shezhi {*/
|
||||
/* display: none*/
|
||||
/*}*/
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<de-container v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
|
||||
<de-aside-container v-if="showChartCanvas">
|
||||
<de-main-container v-show="showChartCanvas">
|
||||
<div id="chartCanvas" class="canvas-class" :style="customStyle">
|
||||
<div class="canvas-class" :style="commonStyle">
|
||||
<plugin-com
|
||||
@ -17,8 +17,8 @@
|
||||
<label-normal-text v-else-if="chart.type === 'label'" :chart="chart" class="table-class" />
|
||||
</div>
|
||||
</div>
|
||||
</de-aside-container>
|
||||
<de-main-container>
|
||||
</de-main-container>
|
||||
<de-main-container v-show="!showChartCanvas">
|
||||
<table-normal :chart="chartTable" :show-summary="false" class="table-class" />
|
||||
</de-main-container>
|
||||
</de-container>
|
||||
@ -32,7 +32,6 @@ import LabelNormal from '@/views/chart/components/normal/LabelNormal'
|
||||
import DeMainContainer from '@/components/dataease/DeMainContainer'
|
||||
import DeContainer from '@/components/dataease/DeContainer'
|
||||
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
|
||||
// import { export_json_to_excel } from '@/plugins/Export2Excel'
|
||||
import { mapState } from 'vuex'
|
||||
import ChartComponentG2 from '@/views/chart/components/ChartComponentG2'
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
@ -43,7 +42,7 @@ import html2canvas from 'html2canvasde'
|
||||
import { hexColorToRGBA } from '@/views/chart/chart/util'
|
||||
import { deepCopy, exportImg } from '@/components/canvas/utils/utils'
|
||||
export default {
|
||||
name: 'UserView',
|
||||
name: 'UserViewDialog',
|
||||
components: { LabelNormalText, ChartComponentS2, ChartComponentG2, DeMainContainer, DeContainer, DeAsideContainer, ChartComponent, TableNormal, LabelNormal, PluginCom },
|
||||
props: {
|
||||
chart: {
|
||||
@ -53,6 +52,10 @@ export default {
|
||||
chartTable: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
openType: {
|
||||
type: String,
|
||||
default: 'details'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -65,7 +68,10 @@ export default {
|
||||
computed: {
|
||||
|
||||
showChartCanvas() {
|
||||
return this.chart.type !== 'table-normal' && this.chart.type !== 'table-info'
|
||||
return this.openType === 'enlarge'
|
||||
},
|
||||
isOnlyDetails() {
|
||||
return this.chart.type === 'table-normal' || this.chart.type === 'table-info'
|
||||
},
|
||||
customStyle() {
|
||||
let style = {
|
||||
@ -150,13 +156,17 @@ export default {
|
||||
methods: {
|
||||
exportExcel() {
|
||||
const _this = this
|
||||
if (this.showChartCanvas) {
|
||||
html2canvas(document.getElementById('chartCanvas')).then(canvas => {
|
||||
const snapshot = canvas.toDataURL('image/jpeg', 1) // 是图片质量
|
||||
_this.exportExcelDownload(snapshot, canvas.width, canvas.height)
|
||||
})
|
||||
} else {
|
||||
if (this.isOnlyDetails) {
|
||||
_this.exportExcelDownload()
|
||||
} else {
|
||||
if (this.showChartCanvas) {
|
||||
html2canvas(document.getElementById('chartCanvas')).then(canvas => {
|
||||
const snapshot = canvas.toDataURL('image/jpeg', 1)
|
||||
_this.exportExcelDownload(snapshot, canvas.width, canvas.height)
|
||||
})
|
||||
} else {
|
||||
_this.exportExcelDownload()
|
||||
}
|
||||
}
|
||||
},
|
||||
exportViewImg() {
|
||||
@ -199,15 +209,14 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ms-aside-container {
|
||||
height: 50vh;
|
||||
height: 70vh;
|
||||
min-width: 400px;
|
||||
max-width: 400px;
|
||||
padding: 0 0;
|
||||
}
|
||||
.ms-main-container {
|
||||
height: 50vh;
|
||||
height: 70vh;
|
||||
border: 1px solid #E6E6E6;
|
||||
border-left: 0 solid;
|
||||
}
|
||||
.chart-class{
|
||||
height: 100%;
|
||||
|
@ -37,12 +37,10 @@ import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
propValue: {
|
||||
type: String,
|
||||
require: true
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
element: {
|
||||
type: Object
|
||||
},
|
||||
@ -136,20 +134,10 @@ export default {
|
||||
|
||||
setEdit() {
|
||||
this.canEdit = true
|
||||
// // // 聚焦到单元格
|
||||
// setTimeout(() => {
|
||||
// this.$refs['text'].focus()
|
||||
// }, 500)
|
||||
// 全选
|
||||
this.selectText(this.$refs.text)
|
||||
},
|
||||
|
||||
selectText(element) {
|
||||
const selection = window.getSelection()
|
||||
const range = document.createRange()
|
||||
// range.selectNodeContents(element)
|
||||
// selection.removeAllRanges()
|
||||
// selection.addRange(range)
|
||||
},
|
||||
|
||||
removeSelectText() {
|
||||
@ -162,26 +150,27 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: table;
|
||||
|
||||
div {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: table;
|
||||
outline: none;
|
||||
|
||||
div {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.canEdit {
|
||||
cursor: text;
|
||||
height: 100%;
|
||||
}
|
||||
.canEdit {
|
||||
cursor: text;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep a:hover {
|
||||
text-decoration: underline!important;
|
||||
color: blue!important;
|
||||
text-decoration: underline !important;
|
||||
color: blue !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -18,10 +18,11 @@ export const BASE_MOBILE_STYLE = {
|
||||
|
||||
// 组件仪表板样式
|
||||
export const COMMON_BACKGROUND = {
|
||||
enable: true,
|
||||
backgroundType: 'color',
|
||||
enable: false,
|
||||
backgroundColorSelect: true,
|
||||
backgroundType: 'innerImage',
|
||||
color: '#FFFFFF',
|
||||
innerImage: null,
|
||||
innerImage: 'board/blue_1.svg',
|
||||
outerImage: null,
|
||||
alpha: 100,
|
||||
borderRadius: 5,
|
||||
@ -31,9 +32,10 @@ export const COMMON_BACKGROUND = {
|
||||
// 空组件仪表板样式
|
||||
export const COMMON_BACKGROUND_NONE = {
|
||||
enable: false,
|
||||
backgroundType: 'color',
|
||||
backgroundColorSelect: false,
|
||||
backgroundType: 'innerImage',
|
||||
color: '#FFFFFF',
|
||||
innerImage: null,
|
||||
innerImage: 'board/blue_1.svg',
|
||||
outerImage: null,
|
||||
alpha: 100,
|
||||
borderRadius: 0,
|
||||
|
@ -1,13 +1,7 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<Toolbar />
|
||||
|
||||
<Toolbar/>
|
||||
<main>
|
||||
<!-- 左侧组件列表 -->
|
||||
<!-- <section class="left">-->
|
||||
<!-- <ComponentList />-->
|
||||
<!-- </section>-->
|
||||
<!-- 中间画布 -->
|
||||
<section class="center">
|
||||
<div
|
||||
class="content"
|
||||
@ -16,7 +10,7 @@
|
||||
@mousedown="handleMouseDown"
|
||||
@mouseup="deselectCurComponent"
|
||||
>
|
||||
<Editor />
|
||||
<Editor/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -26,20 +20,14 @@
|
||||
|
||||
<script>
|
||||
import Editor from '@/components/Editor/index'
|
||||
import ComponentList from '@/components/ComponentList' // 左侧列表组件
|
||||
import AttrList from '@/components/canvas/components/AttrList' // 右侧属性列表
|
||||
import AnimationList from '@/components/canvas/components/AnimationList' // 右侧动画列表
|
||||
import EventList from '@/components/canvas/components/EventList' // 右侧事件列表
|
||||
import componentList from '@/components/canvas/custom-component/component-list' // 左侧列表数据
|
||||
import Toolbar from '@/components/Toolbar'
|
||||
import { deepCopy } from '@/utils/utils'
|
||||
import { mapState } from 'vuex'
|
||||
import {deepCopy} from '@/utils/utils'
|
||||
import {mapState} from 'vuex'
|
||||
import generateID from '@/utils/generateID'
|
||||
// import { listenGlobalKeyDown } from '@/utils/shortcutKey'
|
||||
|
||||
export default {
|
||||
// eslint-disable-next-line vue/no-unused-components
|
||||
components: { Editor, ComponentList, AttrList, AnimationList, EventList, Toolbar },
|
||||
components: {Editor, Toolbar},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'attr',
|
||||
@ -54,8 +42,6 @@ export default {
|
||||
]),
|
||||
created() {
|
||||
this.restore()
|
||||
// 全局监听按键事件
|
||||
// listenGlobalKeyDown()
|
||||
},
|
||||
methods: {
|
||||
restore() {
|
||||
@ -72,7 +58,6 @@ export default {
|
||||
resetID(data) {
|
||||
if (data) {
|
||||
data.forEach(item => {
|
||||
// eslint-disable-next-line no-undef
|
||||
item.type !== 'custom' && (item.id = uuid.v1())
|
||||
})
|
||||
}
|
||||
@ -95,8 +80,8 @@ export default {
|
||||
component.style.top = e.offsetY
|
||||
component.style.left = e.offsetX
|
||||
component.id = generateID()
|
||||
this.$store.commit('addComponent', { component })
|
||||
this.$store.commit('recordSnapshot','handleDrop')
|
||||
this.$store.commit('addComponent', {component})
|
||||
this.$store.commit('recordSnapshot', 'handleDrop')
|
||||
},
|
||||
|
||||
handleDragOver(e) {
|
||||
@ -110,7 +95,7 @@ export default {
|
||||
|
||||
deselectCurComponent(e) {
|
||||
if (!this.isClickComponent) {
|
||||
this.$store.commit('setCurComponent', { component: null, index: null })
|
||||
this.$store.commit('setCurComponent', {component: null, index: null})
|
||||
}
|
||||
|
||||
// 0 左击 1 滚轮 2 右击
|
||||
@ -124,49 +109,49 @@ export default {
|
||||
|
||||
<style lang="scss">
|
||||
.home {
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
|
||||
main {
|
||||
height: calc(100% - 64px);
|
||||
position: relative;
|
||||
main {
|
||||
height: calc(100% - 64px);
|
||||
position: relative;
|
||||
|
||||
.left {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 262px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: 200px;
|
||||
margin-right: 262px;
|
||||
background: #f5f5f5;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: 20px;
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
.left {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
.right {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 262px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: 200px;
|
||||
margin-right: 262px;
|
||||
background: #f5f5f5;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: 20px;
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -3,8 +3,8 @@ import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
|
||||
export default {
|
||||
state: {
|
||||
snapshotData: [], // 编辑器快照数据
|
||||
snapshotStyleData: [], // 样式改变也记录快照
|
||||
snapshotData: [{}], // 编辑器快照数据
|
||||
snapshotStyleData: [{}], // 样式改变也记录快照
|
||||
snapshotIndex: -1, // 快照索引
|
||||
changeTimes: -1, // 修改次数
|
||||
lastSaveSnapshotIndex: 0, // 最后保存是snapshotIndex的索引
|
||||
@ -34,7 +34,6 @@ export default {
|
||||
|
||||
recordSnapshot(state) {
|
||||
state.changeTimes++
|
||||
// console.log('recordSnapshot')
|
||||
// 添加新的快照
|
||||
state.snapshotData[++state.snapshotIndex] = deepCopy(state.componentData)
|
||||
state.snapshotStyleData[state.snapshotIndex] = deepCopy(state.canvasStyleData)
|
||||
@ -45,11 +44,10 @@ export default {
|
||||
}
|
||||
},
|
||||
refreshSnapshot(state) {
|
||||
// console.log('refreshSnapshot')
|
||||
// 刷新快照
|
||||
state.snapshotData = []
|
||||
state.snapshotStyleData = []
|
||||
state.snapshotIndex = -1
|
||||
state.snapshotData = [deepCopy(state.componentData)]
|
||||
state.snapshotStyleData = [deepCopy(state.canvasStyleData)]
|
||||
state.snapshotIndex = 0
|
||||
state.changeTimes = -1
|
||||
state.lastSaveSnapshotIndex = 0
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
import store from '@/store'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
|
||||
const ctrlKey = 17
|
||||
const commandKey = 91 // mac command
|
||||
const vKey = 86 // 粘贴
|
||||
const cKey = 67 // 复制
|
||||
const xKey = 88 // 剪切
|
||||
@ -27,10 +27,7 @@ export const keycodes = [66, 67, 68, 69, 71, 76, 80, 83, 85, 86, 88, 89, 90]
|
||||
const basemap = {
|
||||
[vKey]: paste,
|
||||
[yKey]: redo,
|
||||
[zKey]: undo,
|
||||
[sKey]: save,
|
||||
[pKey]: preview,
|
||||
[eKey]: clearCanvas
|
||||
[zKey]: undo
|
||||
}
|
||||
|
||||
// 组件锁定状态下可以执行的操作
|
||||
@ -51,33 +48,28 @@ const unlockMap = {
|
||||
[lKey]: lock
|
||||
}
|
||||
|
||||
let isCtrlDown = false
|
||||
// 全局监听按键操作并执行相应命令
|
||||
// export function listenGlobalKeyDown() {
|
||||
// window.onkeydown = (e) => {
|
||||
// const { curComponent } = store.state
|
||||
// if (e.keyCode === ctrlKey) {
|
||||
// isCtrlDown = true
|
||||
// } else if (e.keyCode === deleteKey && curComponent) {
|
||||
// store.commit('deleteComponent')
|
||||
// store.commit('recordSnapshot')
|
||||
// } else if (isCtrlDown) {
|
||||
// if (!curComponent || !curComponent.isLock) {
|
||||
// e.preventDefault()
|
||||
// unlockMap[e.keyCode] && unlockMap[e.keyCode]()
|
||||
// } else if (curComponent && curComponent.isLock) {
|
||||
// e.preventDefault()
|
||||
// lockMap[e.keyCode] && lockMap[e.keyCode]()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// window.onkeyup = (e) => {
|
||||
// if (e.keyCode === ctrlKey) {
|
||||
// isCtrlDown = false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
let isCtrlOrCommandDown = false
|
||||
// Monitor key operations globally and execute corresponding commands
|
||||
export function listenGlobalKeyDown() {
|
||||
window.onkeydown = (e) => {
|
||||
if (!store.state.isInEditor) return
|
||||
const { keyCode } = e
|
||||
if (keyCode === ctrlKey || keyCode === commandKey) {
|
||||
isCtrlOrCommandDown = true
|
||||
} else if (isCtrlOrCommandDown) {
|
||||
if (keyCode === zKey || keyCode === yKey) {
|
||||
e.preventDefault()
|
||||
unlockMap[keyCode]()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.onkeyup = (e) => {
|
||||
if (e.keyCode === ctrlKey || e.keyCode === commandKey) {
|
||||
isCtrlOrCommandDown = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function copy() {
|
||||
store.commit('copy')
|
||||
@ -115,14 +107,6 @@ function decompose() {
|
||||
}
|
||||
}
|
||||
|
||||
function save() {
|
||||
eventBus.$emit('save')
|
||||
}
|
||||
|
||||
function preview() {
|
||||
eventBus.$emit('preview')
|
||||
}
|
||||
|
||||
function deleteComponent() {
|
||||
if (store.state.curComponent) {
|
||||
store.commit('deleteComponent')
|
||||
@ -130,10 +114,6 @@ function deleteComponent() {
|
||||
}
|
||||
}
|
||||
|
||||
function clearCanvas() {
|
||||
eventBus.$emit('clearCanvas')
|
||||
}
|
||||
|
||||
function lock() {
|
||||
store.commit('lock')
|
||||
}
|
||||
|
@ -167,7 +167,6 @@ export function recursionTransObj(template, infoObj, scale, terminal) {
|
||||
if (infoObj[templateKey] && infoObj[templateKey][templateProp]) {
|
||||
// 移动端特殊属性值设置
|
||||
if (terminal === 'mobile' && mobileSpecialProps[templateProp] !== undefined) {
|
||||
// console.log('mobile:' + templateProp + mobileSpecialProps[templateProp])
|
||||
infoObj[templateKey][templateProp] = mobileSpecialProps[templateProp]
|
||||
} else {
|
||||
infoObj[templateKey][templateProp] = getScaleValue(infoObj[templateKey][templateProp], scale)
|
||||
|
@ -130,7 +130,6 @@ export function changeStyleWithScale(value) {
|
||||
export function changeStyleWithScaleHeightInAuto(value) {
|
||||
const scale = store.state.canvasStyleData.scaleHeight ? store.state.canvasStyleData.scaleHeight : 100
|
||||
const result = value * scale / 100
|
||||
// console.log('heightInAuto=>' + scale + ';' + result)
|
||||
return result
|
||||
}
|
||||
|
||||
@ -138,7 +137,6 @@ export function changeStyleWithScaleHeightInAuto(value) {
|
||||
export function changeStyleWithScaleWidthInAuto(value) {
|
||||
const scale = store.state.canvasStyleData.scaleWidth ? store.state.canvasStyleData.scaleWidth : 100
|
||||
const result = value * scale / 100
|
||||
// console.log('widthInAuto=>' + scale + ';' + result)
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,12 @@ export function panelDataPrepare(componentData, componentStyle, callback) {
|
||||
item.mobileStyle = (item.mobileStyle || deepCopy(BASE_MOBILE_STYLE))
|
||||
item.hyperlinks = (item.hyperlinks || deepCopy(HYPERLINKS))
|
||||
item.commonBackground = item.commonBackground || deepCopy(COMMON_BACKGROUND_NONE)
|
||||
// Multi choice of colors and pictures
|
||||
if (item.commonBackground.backgroundType === 'color') {
|
||||
item.commonBackground['backgroundColorSelect'] = item.commonBackground.enable
|
||||
item.commonBackground.enable = false
|
||||
item.commonBackground.backgroundType = 'innerImage'
|
||||
}
|
||||
})
|
||||
// 初始化密度为最高密度
|
||||
componentStyle.aidedDesign.matrixBase = 4
|
||||
|
@ -114,7 +114,6 @@ export default {
|
||||
// this.watchSize()
|
||||
},
|
||||
created() {
|
||||
// console.log('aaaaaa')
|
||||
const { horizontal, vertical } = this.element.style
|
||||
this.$set(this.element.style, 'horizontal', horizontal || 'left')
|
||||
this.$set(this.element.style, 'vertical', vertical || 'center')
|
||||
|
@ -68,7 +68,6 @@ class TimeDateRangeServiceImpl extends WidgetService {
|
||||
initLeftPanel() {
|
||||
const value = JSON.parse(JSON.stringify(leftPanel))
|
||||
return value
|
||||
// console.log('this is first initWidget')
|
||||
}
|
||||
|
||||
initFilterDialog() {
|
||||
|
@ -79,7 +79,6 @@ class TimeDateServiceImpl extends WidgetService {
|
||||
initLeftPanel() {
|
||||
const value = JSON.parse(JSON.stringify(leftPanel))
|
||||
return value
|
||||
// console.log('this is first initWidget')
|
||||
}
|
||||
|
||||
initFilterDialog() {
|
||||
|
@ -72,7 +72,6 @@ class TimeMonthServiceImpl extends WidgetService {
|
||||
initLeftPanel() {
|
||||
const value = JSON.parse(JSON.stringify(leftPanel))
|
||||
return value
|
||||
// console.log('this is first initWidget')
|
||||
}
|
||||
|
||||
initFilterDialog() {
|
||||
|
@ -44,7 +44,6 @@ class TimeQuarterServiceImpl extends WidgetService {
|
||||
initLeftPanel() {
|
||||
const value = JSON.parse(JSON.stringify(leftPanel))
|
||||
return value
|
||||
// console.log('this is first initWidget')
|
||||
}
|
||||
|
||||
initFilterDialog() {
|
||||
|
@ -71,7 +71,6 @@ class TimeYearServiceImpl extends WidgetService {
|
||||
initLeftPanel() {
|
||||
const value = JSON.parse(JSON.stringify(leftPanel))
|
||||
return value
|
||||
// console.log('this is first initWidget')
|
||||
}
|
||||
|
||||
initFilterDialog() {
|
||||
|
@ -3,20 +3,6 @@ function checkDataPermission(el, binding, vnode) {
|
||||
const dataPermission = vnode.privileges
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { value } = binding
|
||||
// // 数据授权采用并集的方式 部门 角色 用户 有一个有权限即可
|
||||
// if (value && value instanceof Array) {
|
||||
// const needPermissions = value
|
||||
// // 满足任意一个即可
|
||||
// const hasPermission = needPermissions.some(needP => {
|
||||
// const result = dataPermission.indexOf(needP) > -1
|
||||
// return result
|
||||
// })
|
||||
// if (!hasPermission) {
|
||||
// el.parentNode && el.parentNode.removeChild(el)
|
||||
// }
|
||||
// } else {
|
||||
// throw new Error(`使用方式: v-data-permission="['1:1']"`)
|
||||
// }
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,8 @@ export default {
|
||||
display: 'Display Setting',
|
||||
ldap: 'LDAP Setting',
|
||||
oidc: 'OIDC Setting',
|
||||
theme: 'Theme Setting'
|
||||
theme: 'Theme Setting',
|
||||
cas: 'CAS Setting'
|
||||
},
|
||||
license: {
|
||||
i18n_no_license_record: 'No License Record',
|
||||
@ -643,7 +644,7 @@ export default {
|
||||
login_type: 'Default login type',
|
||||
empty_front: 'If empty then default value is 10s',
|
||||
empty_msg: 'If empty then default value is 30 days',
|
||||
front_error: 'Valid ranger [0 - 100]',
|
||||
front_error: 'Valid ranger [0 - 300]', // 修改了提示信息
|
||||
msg_error: 'Valid ranger [1 - 365]',
|
||||
SMTP_port: 'SMTP Port',
|
||||
SMTP_account: 'SMTP Account',
|
||||
@ -657,9 +658,13 @@ export default {
|
||||
test_recipients: 'Test recipients',
|
||||
tip: 'Tip: use as test mail recipient only',
|
||||
engine_mode_setting: 'Engine Setting',
|
||||
kettle_setting: 'Kettle Setting'
|
||||
kettle_setting: 'Kettle Setting',
|
||||
cas_selected_warn: 'Selecting CAS will cause you to login again'
|
||||
},
|
||||
chart: {
|
||||
view_reset: 'View Reset',
|
||||
view_reset_tips: 'Discard Changes To View?',
|
||||
export_img: 'Export Img',
|
||||
title_repeat: 'The Title Already Exist',
|
||||
save_snapshot: 'Save Snapshot',
|
||||
datalist: 'Chart',
|
||||
@ -1101,7 +1106,12 @@ export default {
|
||||
tick_count: 'Tick Split',
|
||||
custom_sort: 'Custom',
|
||||
custom_sort_tip: 'Custom sort field first,and only support single field',
|
||||
clean_custom_sort: 'Clean'
|
||||
clean_custom_sort: 'Clean',
|
||||
ds_field_edit: 'Dataset Field Manage',
|
||||
chart_field_edit: 'Chart Field Manage',
|
||||
copy_field: 'Copy Field',
|
||||
calc_field: 'Calculate Field',
|
||||
form_type: 'From Type'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
|
||||
@ -1452,6 +1462,10 @@ export default {
|
||||
sure_bt: 'Confirm'
|
||||
},
|
||||
panel: {
|
||||
more: 'More',
|
||||
level: 'Level',
|
||||
enlarge: 'Enlarge',
|
||||
panel_style: 'Panel Style',
|
||||
multiplexing: 'Multiplexing',
|
||||
panel_off: 'Off the shelf',
|
||||
batch_opt: 'Batch Operation',
|
||||
@ -1646,7 +1660,7 @@ export default {
|
||||
no_drill_field: 'Miss relation field',
|
||||
matrix: 'matrix',
|
||||
suspension: 'suspension',
|
||||
new_element_distribution: 'New element Distribution',
|
||||
new_element_distribution: 'Element Distribution',
|
||||
aided_grid: 'Aided Grid',
|
||||
aided_grid_open: 'Open',
|
||||
aided_grid_close: 'Close',
|
||||
|
@ -471,7 +471,8 @@ export default {
|
||||
display: '顯示設置',
|
||||
ldap: 'LDAP設置',
|
||||
oidc: 'OIDC設置',
|
||||
theme: '主題設置'
|
||||
theme: '主題設置',
|
||||
cas: 'CAS設置'
|
||||
},
|
||||
license: {
|
||||
i18n_no_license_record: '沒有 License 記錄',
|
||||
@ -645,7 +646,7 @@ export default {
|
||||
login_type: '默認登錄方式',
|
||||
empty_front: '為空則默認取值10秒',
|
||||
empty_msg: '為空則默認取值30天',
|
||||
front_error: '請填寫0-100正整數',
|
||||
front_error: '請填寫0-300正整數', // 修改了提示信息
|
||||
msg_error: '請填寫1-365正整數',
|
||||
SMTP_port: 'SMTP端口',
|
||||
SMTP_account: 'SMTP賬戶',
|
||||
@ -659,9 +660,13 @@ export default {
|
||||
test_recipients: '測試收件人',
|
||||
tip: '提示:僅用來作爲測試郵件收件人',
|
||||
engine_mode_setting: '引擎設置',
|
||||
kettle_setting: 'Kettle 設置'
|
||||
kettle_setting: 'Kettle 設置',
|
||||
cas_selected_warn: '選擇CAS方式保存後會註銷當前回話,重新登錄'
|
||||
},
|
||||
chart: {
|
||||
view_reset: '视图重置',
|
||||
view_reset_tips: '放弃对视图的修改?',
|
||||
export_img: '导出图片',
|
||||
title_repeat: '當前標題已存在',
|
||||
save_snapshot: '保存縮略圖',
|
||||
datalist: '視圖',
|
||||
@ -1101,7 +1106,12 @@ export default {
|
||||
tick_count: '刻度間隔數',
|
||||
custom_sort: '自定義',
|
||||
custom_sort_tip: '自定義排序優先級最高,且僅支持單個字段自定義',
|
||||
clean_custom_sort: '清除自定義排序'
|
||||
clean_custom_sort: '清除自定義排序',
|
||||
ds_field_edit: '數據集字段管理',
|
||||
chart_field_edit: '視圖字段管理',
|
||||
copy_field: '復製字段',
|
||||
calc_field: '計算字段',
|
||||
form_type: '類別'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多個 Sheet 頁,默認抽取第一個',
|
||||
@ -1453,6 +1463,10 @@ export default {
|
||||
sure_bt: '確定'
|
||||
},
|
||||
panel: {
|
||||
more: '更多',
|
||||
level: '层级',
|
||||
enlarge: '放大',
|
||||
panel_style: '仪表板样式',
|
||||
multiplexing: '復用',
|
||||
panel_off: '儀表板已下架',
|
||||
batch_opt: '批量操作',
|
||||
@ -1647,7 +1661,7 @@ export default {
|
||||
no_drill_field: '缺少關聯字段',
|
||||
matrix: '矩陣',
|
||||
suspension: '懸浮',
|
||||
new_element_distribution: '當前元素移入分佈方式',
|
||||
new_element_distribution: '元素移入分佈方式',
|
||||
aided_grid: '輔助設計網格',
|
||||
aided_grid_open: '打開',
|
||||
aided_grid_close: '關閉',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user