refactor: 解决冲突

This commit is contained in:
taojinlong 2022-06-16 23:03:07 +08:00
commit 6c9191e9bd
178 changed files with 3925 additions and 1445 deletions

72
.github/workflows/codeql-analysis.yml vendored Normal file
View 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

View File

@ -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
[![Star History Chart](https://api.star-history.com/svg?repos=dataease/dataease&type=Date)](https://star-history.com/#dataease/dataease&Date)
## License
Copyright (c) 2014-2022 飞致云 FIT2CLOUD, All rights reserved.

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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) {
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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));

View File

@ -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");

View File

@ -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);

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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());
}
}

View File

@ -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")

View File

@ -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);

View File

@ -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>

View File

@ -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 );

View File

@ -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>

View File

@ -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);
}
}

View 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 "已经切换默认登录方式";
}
}

View File

@ -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);
}
}

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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()

View File

@ -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()

View File

@ -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"));
}
}
}
}

View File

@ -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());
}
// 过滤来自仪表板的条件

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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());

View File

@ -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()) {
// 原有视图的目录结构

View File

@ -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());

View File

@ -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);

View File

@ -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

View File

@ -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)) {

View File

@ -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};
// 针对公共资源的操作

View File

@ -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");
}

View File

@ -25,6 +25,5 @@ public class PrincipalHandshakeHandler extends DefaultHandshakeHandler {
return new DePrincipal(userId);
}
return null;
//return super.determineUser(request, wsHandler, attributes);
}
}

View File

@ -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()
}*/
}

View File

@ -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

View 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);

View File

@ -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`;

View File

@ -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.

View File

@ -159,3 +159,4 @@ I18N_TIME=操作时间
I18N_DRIVER_NOT_DELETE=使用中的驱动不允许删除
I18N_DRIVER_REPEAT_NAME=名称重复
I18N_DRIVER_NOT_FOUND=未找到驱动

View File

@ -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=未找到驅動

View File

@ -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",

File diff suppressed because one or more lines are too long

179
frontend/public/vendor/vendor.dll.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -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',

View File

@ -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 }

View File

@ -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 }

View File

@ -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',

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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) {

View File

@ -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)

View File

@ -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)
}
}
}

View File

@ -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() {

View File

@ -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) {

View File

@ -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>

View File

@ -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 ' +

View File

@ -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)
}
}
}

View File

@ -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)
}
}
}

View File

@ -25,7 +25,6 @@ export default {
type: Array,
default: () => []
},
// eslint-disable-next-line vue/require-default-prop
element: {
type: Object
}

View File

@ -7,7 +7,6 @@
<script>
export default {
props: {
// eslint-disable-next-line vue/require-default-prop
element: {
type: Object
}

View File

@ -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>

View File

@ -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%;

View File

@ -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>

View File

@ -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,

View File

@ -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>

View File

@ -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
},

View File

@ -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')
}

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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')

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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)
}

View File

@ -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',

View File

@ -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