提交 68d40f40 authored 作者: taojinlong's avatar taojinlong

Merge branch 'v1.10' of github.com:dataease/dataease into v1.10

...@@ -10,5 +10,10 @@ import java.lang.annotation.Target; ...@@ -10,5 +10,10 @@ import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD}) @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface DeCleaner { public @interface DeCleaner {
DePermissionType value(); DePermissionType value();
int paramIndex() default 0;
String key() default "";
} }
...@@ -2,73 +2,178 @@ package io.dataease.auth.aop; ...@@ -2,73 +2,178 @@ package io.dataease.auth.aop;
import io.dataease.auth.annotation.DeCleaner; import io.dataease.auth.annotation.DeCleaner;
import io.dataease.auth.api.dto.CurrentUserDto; import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.util.ReflectUtil;
import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.constants.DePermissionType; import io.dataease.commons.constants.DePermissionType;
import io.dataease.commons.model.AuthURD;
import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.LogUtil; import io.dataease.commons.utils.LogUtil;
import io.dataease.listener.util.CacheUtils; import io.dataease.listener.util.CacheUtils;
import org.aspectj.lang.ProceedingJoinPoint; import org.apache.commons.collections4.CollectionUtils;
import org.aspectj.lang.annotation.Around; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Aspect @Aspect
@Component @Component
public class DeCleanerAnnotationHandler { public class DeCleanerAnnotationHandler {
@Around(value = "@annotation(io.dataease.auth.annotation.DeCleaner)") @AfterReturning(value = "@annotation(io.dataease.auth.annotation.DeCleaner)")
public Object CleanerAround(ProceedingJoinPoint point) { public void CleanerAround(JoinPoint point) {
try { try {
MethodSignature ms = (MethodSignature) point.getSignature(); MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod(); Method method = ms.getMethod();
DeCleaner deCleaner = method.getAnnotation(DeCleaner.class); DeCleaner deCleaner = method.getAnnotation(DeCleaner.class);
DePermissionType type = deCleaner.value(); DePermissionType type = deCleaner.value();
String key = deCleaner.key();
Object[] args = point.getArgs();
Object paramValue = null;
if (ObjectUtils.isNotEmpty(key) && ArrayUtils.isNotEmpty(args)) {
int pi = deCleaner.paramIndex();
Object arg = point.getArgs()[pi];
paramValue = getParamValue(arg, key, 0);
}
switch (type.name()) { switch (type.name()) {
case "DATASOURCE": case "DATASOURCE":
cleanDataSource(); cleanDataSource(paramValue);
break; break;
case "DATASET": case "DATASET":
cleanDataSet(); cleanDataSet(paramValue);
break; break;
default: default:
cleanPanel(); cleanPanel(paramValue);
break; break;
} }
return point.proceed(point.getArgs());
} catch (Throwable e) { } catch (Throwable e) {
LogUtil.error(e.getMessage(), e); LogUtil.error(e.getMessage(), e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public void cleanPanel() {
private void cleanCacheParent(String pid, String type) {
if (StringUtils.isBlank(pid) || StringUtils.isBlank(type)) {
return;
}
CurrentUserDto user = AuthUtils.getUser();
List<String> resourceIds = AuthUtils.parentResources(pid.toString(), type);
if (CollectionUtils.isEmpty(resourceIds))return;
resourceIds.forEach(resourceId -> {
AuthURD authURD = AuthUtils.authURDR(resourceId);
Optional.ofNullable(authURD.getUserIds()).ifPresent(ids -> {
ids.forEach(id -> {
CacheUtils.remove("user_"+type, "user" + id);
});
});
Optional.ofNullable(authURD.getRoleIds()).ifPresent(ids -> {
ids.forEach(id -> {
CacheUtils.remove("role_"+type, "role" + id);
});
});
Optional.ofNullable(authURD.getDeptIds()).ifPresent(ids -> {
ids.forEach(id -> {
List<String> depts = AuthUtils.getAuthModels(id.toString(), "dept", user.getUserId(), user.getIsAdmin());
depts.forEach(deptId -> {
CacheUtils.remove("dept_"+type, "dept" + deptId);
});
});
});
});
}
public void cleanPanel(Object pid) {
CurrentUserDto user = AuthUtils.getUser(); CurrentUserDto user = AuthUtils.getUser();
CacheUtils.remove(AuthConstants.USER_PANEL_NAME, "user" + user.getUserId()); CacheUtils.remove(AuthConstants.USER_PANEL_NAME, "user" + user.getUserId());
CacheUtils.remove(AuthConstants.DEPT_PANEL_NAME, "dept" + user.getDeptId()); CacheUtils.remove(AuthConstants.DEPT_PANEL_NAME, "dept" + user.getDeptId());
user.getRoles().forEach(role -> { user.getRoles().forEach(role -> {
CacheUtils.remove(AuthConstants.ROLE_PANEL_NAME, "role" + role.getId()); CacheUtils.remove(AuthConstants.ROLE_PANEL_NAME, "role" + role.getId());
}); });
Optional.ofNullable(pid).ifPresent(resourceId -> {
cleanCacheParent(resourceId.toString(), "panel");
});
} }
public void cleanDataSet() { public void cleanDataSet(Object pid) {
CurrentUserDto user = AuthUtils.getUser(); CurrentUserDto user = AuthUtils.getUser();
CacheUtils.remove(AuthConstants.USER_DATASET_NAME, "user" + user.getUserId()); CacheUtils.remove(AuthConstants.USER_DATASET_NAME, "user" + user.getUserId());
CacheUtils.remove(AuthConstants.DEPT_DATASET_NAME, "dept" + user.getDeptId()); CacheUtils.remove(AuthConstants.DEPT_DATASET_NAME, "dept" + user.getDeptId());
user.getRoles().forEach(role -> { user.getRoles().forEach(role -> {
CacheUtils.remove(AuthConstants.ROLE_DATASET_NAME, "role" + role.getId()); CacheUtils.remove(AuthConstants.ROLE_DATASET_NAME, "role" + role.getId());
}); });
Optional.ofNullable(pid).ifPresent(resourceId -> {
cleanCacheParent(resourceId.toString(), "dataset");
});
} }
public void cleanDataSource() { public void cleanDataSource(Object pid) {
CurrentUserDto user = AuthUtils.getUser(); CurrentUserDto user = AuthUtils.getUser();
CacheUtils.remove(AuthConstants.USER_LINK_NAME, "user" + user.getUserId()); CacheUtils.remove(AuthConstants.USER_LINK_NAME, "user" + user.getUserId());
CacheUtils.remove(AuthConstants.DEPT_LINK_NAME, "dept" + user.getDeptId()); CacheUtils.remove(AuthConstants.DEPT_LINK_NAME, "dept" + user.getDeptId());
user.getRoles().forEach(role -> { user.getRoles().forEach(role -> {
CacheUtils.remove(AuthConstants.ROLE_LINK_NAME, "role" + role.getId()); CacheUtils.remove(AuthConstants.ROLE_LINK_NAME, "role" + role.getId());
}); });
Optional.ofNullable(pid).ifPresent(resourceId -> {
cleanCacheParent(resourceId.toString(), "link");
});
}
private Object getParamValue(Object arg, String key, int layer) throws Exception{
if (ObjectUtils.isNotEmpty(arg)) return null;
Class<?> parameterType = arg.getClass();
if (parameterType.isPrimitive() || ReflectUtil.isWrapClass(parameterType) || ReflectUtil.isString(parameterType)) {
return arg;
} else if (ReflectUtil.isArray(parameterType)) {
Object result;
for (int i = 0; i < Array.getLength(arg); i++) {
Object o = Array.get(arg, i);
if (ObjectUtils.isNotEmpty((result = getParamValue(o, key, layer)))) {
return result;
}
}
return null;
} else if (ReflectUtil.isCollection(parameterType)) {
Object[] array = ((Collection) arg).toArray();
Object result;
for (int i = 0; i < array.length; i++) {
Object o = array[i];
if (ObjectUtils.isNotEmpty((result = getParamValue(o, key, layer)))) {
return result;
}
}
return null;
} else if (ReflectUtil.isMap(parameterType)) {
Map<String, Object> argMap = (Map) arg;
String[] values = key.split("\\.");
Object o = argMap.get(values[layer]);
return getParamValue(o, key, ++layer);
} else {
// 当作自定义类处理
String[] values = key.split("\\.");
String fieldName = values[layer];
Object fieldValue = ReflectUtil.getFieldValue(arg, values[layer]);
return getParamValue(fieldValue, key, ++layer);
}
} }
} }
...@@ -3,10 +3,10 @@ package io.dataease.auth.aop; ...@@ -3,10 +3,10 @@ package io.dataease.auth.aop;
import io.dataease.auth.annotation.DePermission; import io.dataease.auth.annotation.DePermission;
import io.dataease.auth.annotation.DePermissions; import io.dataease.auth.annotation.DePermissions;
import io.dataease.auth.entity.AuthItem; import io.dataease.auth.entity.AuthItem;
import io.dataease.auth.util.ReflectUtil;
import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.LogUtil; import io.dataease.commons.utils.LogUtil;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException; import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.Logical;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
...@@ -14,9 +14,7 @@ import org.aspectj.lang.annotation.Around; ...@@ -14,9 +14,7 @@ import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -111,13 +109,13 @@ public class DePermissionAnnotationHandler { ...@@ -111,13 +109,13 @@ public class DePermissionAnnotationHandler {
item -> item.getLevel() >= requireLevel).map(AuthItem::getAuthSource).collect(Collectors.toSet()); item -> item.getLevel() >= requireLevel).map(AuthItem::getAuthSource).collect(Collectors.toSet());
Class<?> parameterType = arg.getClass(); Class<?> parameterType = arg.getClass();
if (parameterType.isPrimitive() || isWrapClass(parameterType) || isString(parameterType)) { if (parameterType.isPrimitive() || ReflectUtil.isWrapClass(parameterType) || ReflectUtil.isString(parameterType)) {
boolean permissionValid = resourceIds.contains(arg); boolean permissionValid = resourceIds.contains(arg);
if (permissionValid) if (permissionValid)
return true; return true;
throw new UnauthorizedException("Subject does not have permission[" + annotation.level().name() + ":" throw new UnauthorizedException("Subject does not have permission[" + annotation.level().name() + ":"
+ annotation.type() + ":" + arg + "]"); + annotation.type() + ":" + arg + "]");
} else if (isArray(parameterType)) { } else if (ReflectUtil.isArray(parameterType)) {
for (int i = 0; i < Array.getLength(arg); i++) { for (int i = 0; i < Array.getLength(arg); i++) {
Object o = Array.get(arg, i); Object o = Array.get(arg, i);
if (!access(o, annotation, layer)) { if (!access(o, annotation, layer)) {
...@@ -125,7 +123,7 @@ public class DePermissionAnnotationHandler { ...@@ -125,7 +123,7 @@ public class DePermissionAnnotationHandler {
} }
} }
} else if (isCollection(parameterType)) { } else if (ReflectUtil.isCollection(parameterType)) {
Object[] array = ((Collection) arg).toArray(); Object[] array = ((Collection) arg).toArray();
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
Object o = array[i]; Object o = array[i];
...@@ -133,7 +131,7 @@ public class DePermissionAnnotationHandler { ...@@ -133,7 +131,7 @@ public class DePermissionAnnotationHandler {
return false; return false;
} }
} }
} else if (isMap(parameterType)) { } else if (ReflectUtil.isMap(parameterType)) {
Map<String, Object> argMap = (Map) arg; Map<String, Object> argMap = (Map) arg;
String[] values = value.split("."); String[] values = value.split(".");
Object o = argMap.get(values[layer]); Object o = argMap.get(values[layer]);
...@@ -143,59 +141,13 @@ public class DePermissionAnnotationHandler { ...@@ -143,59 +141,13 @@ public class DePermissionAnnotationHandler {
String[] values = value.split("\\."); String[] values = value.split("\\.");
String fieldName = values[layer]; String fieldName = values[layer];
Object fieldValue = getFieldValue(arg, fieldName); Object fieldValue = ReflectUtil.getFieldValue(arg, fieldName);
return access(fieldValue, annotation, ++layer); return access(fieldValue, annotation, ++layer);
} }
return true; return true;
} }
private Object getFieldValue(Object o, String fieldName) throws Exception {
Class<?> aClass = o.getClass();
while (null != aClass.getSuperclass()) {
Field[] declaredFields = aClass.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i];
String name = field.getName();
if (StringUtils.equals(name, fieldName)) {
field.setAccessible(true);
return field.get(o);
}
}
aClass = aClass.getSuperclass();
}
throw new NoSuchFieldException(fieldName);
}
private final static String[] wrapClasies = {
"java.lang.Boolean",
"java.lang.Character",
"java.lang.Integer",
"java.lang.Byte",
"java.lang.Short",
"java.lang.Long",
"java.lang.Float",
"java.lang.Double",
};
private Boolean isString(Class clz) {
return StringUtils.equals("java.lang.String", clz.getName());
}
private Boolean isArray(Class clz) {
return clz.isArray();
}
private Boolean isCollection(Class clz) {
return Collection.class.isAssignableFrom(clz);
}
private Boolean isMap(Class clz) {
return Map.class.isAssignableFrom(clz);
}
private Boolean isWrapClass(Class clz) {
return Arrays.stream(wrapClasies).anyMatch(item -> StringUtils.equals(item, clz.getName()));
}
} }
...@@ -28,5 +28,7 @@ public interface ExtAuthService { ...@@ -28,5 +28,7 @@ public interface ExtAuthService {
void clearDeptResource(Long deptId); void clearDeptResource(Long deptId);
void clearRoleResource(Long roleId); void clearRoleResource(Long roleId);
List<String> parentResource(String resourceId, String type);
} }
...@@ -8,6 +8,7 @@ import io.dataease.commons.constants.AuthConstants; ...@@ -8,6 +8,7 @@ import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.model.AuthURD; import io.dataease.commons.model.AuthURD;
import io.dataease.commons.utils.LogUtil; import io.dataease.commons.utils.LogUtil;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching; import org.springframework.cache.annotation.Caching;
...@@ -147,6 +148,20 @@ public class ExtAuthServiceImpl implements ExtAuthService { ...@@ -147,6 +148,20 @@ public class ExtAuthServiceImpl implements ExtAuthService {
LogUtil.info("all permission resource of role {} is cleanning...", roleId); LogUtil.info("all permission resource of role {} is cleanning...", roleId);
} }
@Override
public List<String> parentResource(String resourceId, String type) {
String s = extAuthMapper.parentResource(resourceId, type);
if (StringUtils.isNotBlank(s)) {
String[] split = s.split(",");
List<String> results = new ArrayList<>();
for (int i = 0; i < split.length; i++) {
String s1 = split[i];
if (StringUtils.isNotBlank(s1)) {
results.add(s1);
}
}
return CollectionUtils.isEmpty(results) ? null : results;
}
return null;
}
} }
...@@ -95,6 +95,7 @@ public class ShiroServiceImpl implements ShiroService { ...@@ -95,6 +95,7 @@ public class ShiroServiceImpl implements ShiroService {
filterChainDefinitionMap.put("/api/link/resourceDetail/**", "link"); filterChainDefinitionMap.put("/api/link/resourceDetail/**", "link");
filterChainDefinitionMap.put("/api/link/viewDetail/**", "link"); filterChainDefinitionMap.put("/api/link/viewDetail/**", "link");
filterChainDefinitionMap.put("/panel/group/exportDetails", ANON);
filterChainDefinitionMap.put("/dataset/field/linkMultFieldValues", "link"); filterChainDefinitionMap.put("/dataset/field/linkMultFieldValues", "link");
filterChainDefinitionMap.put("/**", "authc"); filterChainDefinitionMap.put("/**", "authc");
......
package io.dataease.auth.util;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
public class ReflectUtil {
public static Object getFieldValue(Object o, String fieldName) throws Exception {
Class<?> aClass = o.getClass();
while (null != aClass.getSuperclass()) {
Field[] declaredFields = aClass.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i];
String name = field.getName();
if (StringUtils.equals(name, fieldName)) {
field.setAccessible(true);
return field.get(o);
}
}
aClass = aClass.getSuperclass();
}
throw new NoSuchFieldException(fieldName);
}
private final static String[] wrapClasies = {
"java.lang.Boolean",
"java.lang.Character",
"java.lang.Integer",
"java.lang.Byte",
"java.lang.Short",
"java.lang.Long",
"java.lang.Float",
"java.lang.Double",
};
public static Boolean isString(Class clz) {
return StringUtils.equals("java.lang.String", clz.getName());
}
public static Boolean isArray(Class clz) {
return clz.isArray();
}
public static Boolean isCollection(Class clz) {
return Collection.class.isAssignableFrom(clz);
}
public static Boolean isMap(Class clz) {
return Map.class.isAssignableFrom(clz);
}
public static Boolean isWrapClass(Class clz) {
return Arrays.stream(wrapClasies).anyMatch(item -> StringUtils.equals(item, clz.getName()));
}
}
package io.dataease.commons.constants;
import java.io.File;
import static io.dataease.commons.utils.StaticResourceUtils.ensureSuffix;
/**
* Author: wangjiahao
* Date: 2022/4/28
* Description:
*/
public class StaticResourceConstants {
public static final String FILE_PROTOCOL = "file://";
public static final String FILE_SEPARATOR = File.separator;
public static final String USER_HOME = "/opt/dataease/data";
public static String WORK_DIR = ensureSuffix(USER_HOME, FILE_SEPARATOR) + "static-resource" + FILE_SEPARATOR;
/**
* Upload prefix.
*/
public final static String UPLOAD_URL_PREFIX = "static-resource";
/**
* url separator.
*/
public static final String URL_SEPARATOR = "/";
}
...@@ -9,6 +9,10 @@ import io.dataease.commons.constants.DePermissionType; ...@@ -9,6 +9,10 @@ import io.dataease.commons.constants.DePermissionType;
import io.dataease.commons.constants.ResourceAuthLevel; import io.dataease.commons.constants.ResourceAuthLevel;
import io.dataease.commons.model.AuthURD; import io.dataease.commons.model.AuthURD;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.auth.dto.request.XpackBaseTreeRequest;
import io.dataease.plugins.xpack.auth.dto.response.XpackVAuthModelDTO;
import io.dataease.plugins.xpack.auth.service.AuthXpackService;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
...@@ -67,6 +71,20 @@ public class AuthUtils { ...@@ -67,6 +71,20 @@ public class AuthUtils {
return userIds; return userIds;
} }
public static List<String> parentResources(String resourceId, String type) {
return extAuthService.parentResource(resourceId, type);
}
public static List<String> getAuthModels(String id, String type, Long userId, Boolean isAdmin) {
AuthXpackService sysAuthService = SpringContextUtil.getBean(AuthXpackService.class);
List<XpackVAuthModelDTO> vAuthModelDTOS = sysAuthService
.searchAuthModelTree(new XpackBaseTreeRequest(id, type, "children"), userId, isAdmin);
List<String> authSources = Optional.ofNullable(vAuthModelDTOS).orElse(new ArrayList<>()).stream()
.map(XpackVAuthModelDTO::getId)
.collect(Collectors.toList());
return authSources;
}
// 获取资源对那些人/角色/组织 有权限 // 获取资源对那些人/角色/组织 有权限
public static AuthURD authURDR(String resourceId) { public static AuthURD authURDR(String resourceId) {
return extAuthService.resourceTarget(resourceId); return extAuthService.resourceTarget(resourceId);
......
package io.dataease.commons.utils; package io.dataease.commons.utils;
import static io.dataease.commons.constants.StaticResourceConstants.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import sun.misc.BASE64Encoder;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/** /**
* Author: wangjiahao * Author: wangjiahao
...@@ -10,9 +16,8 @@ import org.springframework.util.Assert; ...@@ -10,9 +16,8 @@ import org.springframework.util.Assert;
* Description: * Description:
*/ */
public class StaticResourceUtils { public class StaticResourceUtils {
public static final String URL_SEPARATOR = "/";
private static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; private final static String FILE_BASE_PATH = USER_HOME+ FILE_SEPARATOR+UPLOAD_URL_PREFIX;
public static String ensureBoth(@NonNull String string, @NonNull String bothfix) { public static String ensureBoth(@NonNull String string, @NonNull String bothfix) {
return ensureBoth(string, bothfix, bothfix); return ensureBoth(string, bothfix, bothfix);
...@@ -51,4 +56,45 @@ public class StaticResourceUtils { ...@@ -51,4 +56,45 @@ public class StaticResourceUtils {
return StringUtils.removeEnd(string, suffix) + suffix; return StringUtils.removeEnd(string, suffix) + suffix;
} }
/**
*
* @param imgFile local storage path
* @return
*/
public static String getImgFileToBase64(String imgFile) {
//Convert the picture file into byte array and encode it with Base64
InputStream inputStream = null;
byte[] buffer = null;
//Read picture byte array
try {
inputStream = new FileInputStream(FILE_BASE_PATH+FILE_SEPARATOR+imgFile);
int count = 0;
while (count == 0) {
count = inputStream.available();
}
buffer = new byte[count];
inputStream.read(buffer);
} catch (IOException e) {
LogUtil.error(e);
}catch (Exception e){
LogUtil.error(e);
}finally {
if (inputStream != null) {
try {
// Close InputStream
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Encode byte array as Base64
if(buffer!=null){
return new BASE64Encoder().encode(buffer);
}else{
return null;
}
}
} }
package io.dataease.config; package io.dataease.config;
import static io.dataease.commons.constants.StaticResourceConstants.*;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.File;
import java.util.concurrent.TimeUnit;
import static io.dataease.commons.utils.StaticResourceUtils.ensureBoth; import static io.dataease.commons.utils.StaticResourceUtils.ensureBoth;
import static io.dataease.commons.utils.StaticResourceUtils.ensureSuffix; import static io.dataease.commons.utils.StaticResourceUtils.ensureSuffix;
...@@ -18,24 +14,6 @@ import static io.dataease.commons.utils.StaticResourceUtils.ensureSuffix; ...@@ -18,24 +14,6 @@ import static io.dataease.commons.utils.StaticResourceUtils.ensureSuffix;
*/ */
@Configuration @Configuration
public class DeMvcConfig implements WebMvcConfigurer { public class DeMvcConfig implements WebMvcConfigurer {
private static final String FILE_PROTOCOL = "file://";
public static final String FILE_SEPARATOR = File.separator;
public static final String USER_HOME = "/opt/dataease/data";
private static String WORK_DIR = ensureSuffix(USER_HOME, FILE_SEPARATOR) + "static-resource" + FILE_SEPARATOR;
/**
* Upload prefix.
*/
private final static String UPLOAD_URL_PREFIX = "static-resource";
/**
* url separator.
*/
public static final String URL_SEPARATOR = "/";
/** /**
* Configuring static resource path * Configuring static resource path
* *
......
...@@ -23,7 +23,8 @@ public class PanelGroupRequest extends PanelGroupDTO { ...@@ -23,7 +23,8 @@ public class PanelGroupRequest extends PanelGroupDTO {
private String dynamicData; private String dynamicData;
@ApiModelProperty("内部模板ID") @ApiModelProperty("内部模板ID")
private String templateId; private String templateId;
@ApiModelProperty("静态文件")
private String staticResource;
public PanelGroupRequest() { public PanelGroupRequest() {
} }
......
package io.dataease.controller.request.resource;
import lombok.Data;
import java.util.List;
/**
* Author: wangjiahao
* Date: 2022/4/28
* Description:
*/
@Data
public class StaticResourceRequest {
private List<String> resourcePathList;
}
package io.dataease.controller.staticResource; package io.dataease.controller.staticResource;
import io.dataease.controller.request.resource.StaticResourceRequest;
import io.dataease.service.staticResource.StaticResourceService; import io.dataease.service.staticResource.StaticResourceService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.pentaho.ui.xul.stereotype.Controller; import org.pentaho.ui.xul.stereotype.Controller;
...@@ -7,6 +8,7 @@ import org.springframework.web.bind.annotation.*; ...@@ -7,6 +8,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Map;
/** /**
* Author: wangjiahao * Author: wangjiahao
...@@ -21,8 +23,14 @@ public class StaticResourceController { ...@@ -21,8 +23,14 @@ public class StaticResourceController {
StaticResourceService staticResourceService; StaticResourceService staticResourceService;
@PostMapping("upload/{fileId}") @PostMapping("upload/{fileId}")
@ApiOperation("Uploads static file") @ApiOperation("上传静态文件")
public void upload(@PathVariable("fileId") String fileId, @RequestPart("file") MultipartFile file) { public void upload(@PathVariable("fileId") String fileId, @RequestPart("file") MultipartFile file) {
staticResourceService.upload(fileId,file); staticResourceService.upload(fileId,file);
} }
@PostMapping("findResourceAsBase64")
@ApiOperation("查找静态文件并转为Base64")
public Map<String,String> findResourceAsBase64(@RequestBody StaticResourceRequest resourceRequest){
return staticResourceService.findResourceAsBase64(resourceRequest);
}
} }
...@@ -27,4 +27,6 @@ public interface ExtAuthMapper { ...@@ -27,4 +27,6 @@ public interface ExtAuthMapper {
List<AuthItem> dataSourceIdByDept(String deptId); List<AuthItem> dataSourceIdByDept(String deptId);
List<AuthItem> dataSetIdByDept(String deptId); List<AuthItem> dataSetIdByDept(String deptId);
List<AuthItem> panelIdByDept(String deptId); List<AuthItem> panelIdByDept(String deptId);
String parentResource(@Param("resourceId") String resourceId, @Param("type") String type);
} }
...@@ -152,6 +152,10 @@ ...@@ -152,6 +152,10 @@
GROUP BY a.id GROUP BY a.id
</select> </select>
<select id="parentResource" resultType="String" >
select GET_V_AUTH_MODEL_WITH_PARENT(#{resourceId}, #{type})
</select>
</mapper> </mapper>
...@@ -76,7 +76,7 @@ public class XAuthServer { ...@@ -76,7 +76,7 @@ public class XAuthServer {
String authCacheKey = getAuthCacheKey(request); String authCacheKey = getAuthCacheKey(request);
if (StringUtils.isNotBlank(authCacheKey)) { if (StringUtils.isNotBlank(authCacheKey)) {
if (StringUtils.equals("dept", request.getAuthTargetType())) { if (StringUtils.equals("dept", request.getAuthTargetType())) {
List<String> authTargets = getAuthModels(request.getAuthTarget(), request.getAuthTargetType(), List<String> authTargets = AuthUtils.getAuthModels(request.getAuthTarget(), request.getAuthTargetType(),
user.getUserId(), user.getIsAdmin()); user.getUserId(), user.getIsAdmin());
if (CollectionUtils.isNotEmpty(authTargets)) { if (CollectionUtils.isNotEmpty(authTargets)) {
authTargets.forEach(deptId -> { authTargets.forEach(deptId -> {
...@@ -91,16 +91,6 @@ public class XAuthServer { ...@@ -91,16 +91,6 @@ public class XAuthServer {
}); });
} }
private List<String> getAuthModels(String id, String type, Long userId, Boolean isAdmin) {
AuthXpackService sysAuthService = SpringContextUtil.getBean(AuthXpackService.class);
List<XpackVAuthModelDTO> vAuthModelDTOS = sysAuthService
.searchAuthModelTree(new XpackBaseTreeRequest(id, type, "children"), userId, isAdmin);
List<String> authSources = Optional.ofNullable(vAuthModelDTOS).orElse(new ArrayList<>()).stream()
.map(XpackVAuthModelDTO::getId)
.collect(Collectors.toList());
return authSources;
}
private String getAuthCacheKey(XpackSysAuthRequest request) { private String getAuthCacheKey(XpackSysAuthRequest request) {
if (CollectionUtils.isEmpty(cacheTypes)) { if (CollectionUtils.isEmpty(cacheTypes)) {
cacheTypes.add("link"); cacheTypes.add("link");
......
...@@ -44,7 +44,7 @@ public class DataSetGroupService { ...@@ -44,7 +44,7 @@ public class DataSetGroupService {
@Resource @Resource
private SysAuthService sysAuthService; private SysAuthService sysAuthService;
@DeCleaner(DePermissionType.DATASET) @DeCleaner(value = DePermissionType.DATASET, key = "pid")
public DataSetGroupDTO save(DatasetGroup datasetGroup) throws Exception { public DataSetGroupDTO save(DatasetGroup datasetGroup) throws Exception {
checkName(datasetGroup); checkName(datasetGroup);
if (StringUtils.isEmpty(datasetGroup.getId())) { if (StringUtils.isEmpty(datasetGroup.getId())) {
......
...@@ -115,7 +115,7 @@ public class DataSetTableService { ...@@ -115,7 +115,7 @@ public class DataSetTableService {
private static Logger logger = LoggerFactory.getLogger(ClassloaderResponsity.class); private static Logger logger = LoggerFactory.getLogger(ClassloaderResponsity.class);
@DeCleaner(value = DePermissionType.DATASET) @DeCleaner(value = DePermissionType.DATASET, key = "sceneId")
public void batchInsert(List<DataSetTableRequest> datasetTable) throws Exception { public void batchInsert(List<DataSetTableRequest> datasetTable) throws Exception {
for (DataSetTableRequest table : datasetTable) { for (DataSetTableRequest table : datasetTable) {
save(table); save(table);
...@@ -143,7 +143,7 @@ public class DataSetTableService { ...@@ -143,7 +143,7 @@ public class DataSetTableService {
} }
} }
@DeCleaner(value = DePermissionType.DATASET) @DeCleaner(value = DePermissionType.DATASET, key = "sceneId")
public void saveExcel(DataSetTableRequest datasetTable) throws Exception { public void saveExcel(DataSetTableRequest datasetTable) throws Exception {
List<String> datasetIdList = new ArrayList<>(); List<String> datasetIdList = new ArrayList<>();
...@@ -253,7 +253,7 @@ public class DataSetTableService { ...@@ -253,7 +253,7 @@ public class DataSetTableService {
} }
} }
@DeCleaner(value = DePermissionType.DATASET) @DeCleaner(value = DePermissionType.DATASET, key = "sceneId")
public DatasetTable save(DataSetTableRequest datasetTable) throws Exception { public DatasetTable save(DataSetTableRequest datasetTable) throws Exception {
checkName(datasetTable); checkName(datasetTable);
if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql")) { if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql")) {
...@@ -1847,7 +1847,6 @@ public class DataSetTableService { ...@@ -1847,7 +1847,6 @@ public class DataSetTableService {
return dataSetDetail; return dataSetDetail;
} }
@DeCleaner(value = DePermissionType.DATASET)
public ExcelFileData excelSaveAndParse(MultipartFile file, String tableId, Integer editType) throws Exception { public ExcelFileData excelSaveAndParse(MultipartFile file, String tableId, Integer editType) throws Exception {
String filename = file.getOriginalFilename(); String filename = file.getOriginalFilename();
// parse file // parse file
......
...@@ -8,7 +8,6 @@ import io.dataease.commons.utils.LogUtil; ...@@ -8,7 +8,6 @@ import io.dataease.commons.utils.LogUtil;
import io.dataease.commons.utils.TreeUtils; import io.dataease.commons.utils.TreeUtils;
import io.dataease.controller.request.authModel.VAuthModelRequest; import io.dataease.controller.request.authModel.VAuthModelRequest;
import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.controller.request.dataset.DataSetTableRequest;
import io.dataease.controller.request.panel.PanelGroupQueryRequest;
import io.dataease.controller.request.panel.PanelGroupRequest; import io.dataease.controller.request.panel.PanelGroupRequest;
import io.dataease.controller.request.panel.PanelViewDetailsRequest; import io.dataease.controller.request.panel.PanelViewDetailsRequest;
import io.dataease.dto.PanelGroupExtendDataDTO; import io.dataease.dto.PanelGroupExtendDataDTO;
...@@ -17,7 +16,6 @@ import io.dataease.dto.chart.ChartViewDTO; ...@@ -17,7 +16,6 @@ import io.dataease.dto.chart.ChartViewDTO;
import io.dataease.dto.dataset.DataSetTableDTO; import io.dataease.dto.dataset.DataSetTableDTO;
import io.dataease.dto.panel.PanelGroupDTO; import io.dataease.dto.panel.PanelGroupDTO;
import io.dataease.dto.panel.po.PanelViewInsertDTO; import io.dataease.dto.panel.po.PanelViewInsertDTO;
import io.dataease.excel.utils.EasyExcelExporter;
import io.dataease.exception.DataEaseException; import io.dataease.exception.DataEaseException;
import io.dataease.ext.*; import io.dataease.ext.*;
import io.dataease.i18n.Translator; import io.dataease.i18n.Translator;
...@@ -26,6 +24,7 @@ import io.dataease.plugins.common.base.domain.*; ...@@ -26,6 +24,7 @@ import io.dataease.plugins.common.base.domain.*;
import io.dataease.plugins.common.base.mapper.*; import io.dataease.plugins.common.base.mapper.*;
import io.dataease.service.chart.ChartViewService; import io.dataease.service.chart.ChartViewService;
import io.dataease.service.dataset.DataSetTableService; import io.dataease.service.dataset.DataSetTableService;
import io.dataease.service.staticResource.StaticResourceService;
import io.dataease.service.sys.SysAuthService; import io.dataease.service.sys.SysAuthService;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -39,13 +38,9 @@ import org.springframework.util.Assert; ...@@ -39,13 +38,9 @@ import org.springframework.util.Assert;
import org.springframework.util.Base64Utils; import org.springframework.util.Base64Utils;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -100,6 +95,8 @@ public class PanelGroupService { ...@@ -100,6 +95,8 @@ public class PanelGroupService {
private PanelTemplateMapper templateMapper; private PanelTemplateMapper templateMapper;
@Resource @Resource
private ExtPanelGroupExtendDataMapper extPanelGroupExtendDataMapper; private ExtPanelGroupExtendDataMapper extPanelGroupExtendDataMapper;
@Resource
private StaticResourceService staticResourceService;
public List<PanelGroupDTO> tree(PanelGroupRequest panelGroupRequest) { public List<PanelGroupDTO> tree(PanelGroupRequest panelGroupRequest) {
String userId = String.valueOf(AuthUtils.getUser().getUserId()); String userId = String.valueOf(AuthUtils.getUser().getUserId());
...@@ -115,9 +112,8 @@ public class PanelGroupService { ...@@ -115,9 +112,8 @@ public class PanelGroupService {
return TreeUtils.mergeTree(panelGroupDTOList, "default_panel"); return TreeUtils.mergeTree(panelGroupDTOList, "default_panel");
} }
@DeCleaner(DePermissionType.PANEL) @DeCleaner(value = DePermissionType.PANEL, key = "pid")
public PanelGroup saveOrUpdate(PanelGroupRequest request) { public PanelGroup saveOrUpdate(PanelGroupRequest request) {
String userName = AuthUtils.getUser().getUsername();
String panelId = request.getId(); String panelId = request.getId();
if (StringUtils.isNotEmpty(panelId)) { if (StringUtils.isNotEmpty(panelId)) {
panelViewService.syncPanelViews(request); panelViewService.syncPanelViews(request);
...@@ -223,12 +219,12 @@ public class PanelGroupService { ...@@ -223,12 +219,12 @@ public class PanelGroupService {
/** /**
* @Description 查询仪表板信息
* @param panelId * @param panelId
* @return * @return
* @Description 查询仪表板信息
*/ */
public PanelGroupDTO findOne(String panelId) { public PanelGroupDTO findOne(String panelId) {
Assert.notNull(panelId,"Method findOne panelId can not be null"); Assert.notNull(panelId, "Method findOne panelId can not be null");
PanelGroupDTO panelGroup = extPanelGroupMapper.findOneWithPrivileges(panelId, String.valueOf(AuthUtils.getUser().getUserId())); PanelGroupDTO panelGroup = extPanelGroupMapper.findOneWithPrivileges(panelId, String.valueOf(AuthUtils.getUser().getUserId()));
// 默认仪表板取源仪表板样式 // 默认仪表板取源仪表板样式
if (panelGroup != null && StringUtils.isNotEmpty(panelGroup.getSource())) { if (panelGroup != null && StringUtils.isNotEmpty(panelGroup.getSource())) {
...@@ -331,8 +327,9 @@ public class PanelGroupService { ...@@ -331,8 +327,9 @@ public class PanelGroupService {
String templateStyle = null; String templateStyle = null;
String templateData = null; String templateData = null;
String dynamicData = null; String dynamicData = null;
String staticResource = null;
if (PanelConstants.NEW_PANEL_FROM.NEW.equals(newFrom)) { if (PanelConstants.NEW_PANEL_FROM.NEW.equals(newFrom)) {
// do nothing
} else { } else {
//内部模板新建 //内部模板新建
if (PanelConstants.NEW_PANEL_FROM.NEW_INNER_TEMPLATE.equals(newFrom)) { if (PanelConstants.NEW_PANEL_FROM.NEW_INNER_TEMPLATE.equals(newFrom)) {
...@@ -344,6 +341,7 @@ public class PanelGroupService { ...@@ -344,6 +341,7 @@ public class PanelGroupService {
templateStyle = request.getPanelStyle(); templateStyle = request.getPanelStyle();
templateData = request.getPanelData(); templateData = request.getPanelData();
dynamicData = request.getDynamicData(); dynamicData = request.getDynamicData();
staticResource = request.getStaticResource();
} }
Map<String, String> dynamicDataMap = JSON.parseObject(dynamicData, Map.class); Map<String, String> dynamicDataMap = JSON.parseObject(dynamicData, Map.class);
List<PanelViewInsertDTO> panelViews = new ArrayList<>(); List<PanelViewInsertDTO> panelViews = new ArrayList<>();
...@@ -370,6 +368,8 @@ public class PanelGroupService { ...@@ -370,6 +368,8 @@ public class PanelGroupService {
} }
request.setPanelData(templateData); request.setPanelData(templateData);
request.setPanelStyle(templateStyle); request.setPanelStyle(templateStyle);
//Store static resource into the server
staticResourceService.saveFilesToServe(staticResource);
} }
request.setId(newPanelId); request.setId(newPanelId);
request.setCreateTime(System.currentTimeMillis()); request.setCreateTime(System.currentTimeMillis());
...@@ -467,7 +467,7 @@ public class PanelGroupService { ...@@ -467,7 +467,7 @@ public class PanelGroupService {
try { try {
String snapshot = request.getSnapshot(); String snapshot = request.getSnapshot();
List<String[]> details = request.getDetails(); List<String[]> details = request.getDetails();
details.add(0,request.getHeader()); details.add(0, request.getHeader());
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
//明细sheet //明细sheet
HSSFSheet detailsSheet = wb.createSheet("数据"); HSSFSheet detailsSheet = wb.createSheet("数据");
...@@ -494,28 +494,28 @@ public class PanelGroupService { ...@@ -494,28 +494,28 @@ public class PanelGroupService {
for (int j = 0; j < rowData.length; j++) { for (int j = 0; j < rowData.length; j++) {
HSSFCell cell = row.createCell(j); HSSFCell cell = row.createCell(j);
cell.setCellValue(rowData[j]); cell.setCellValue(rowData[j]);
if(i==0){// 头部 if (i == 0) {// 头部
cell.setCellStyle(cellStyle); cell.setCellStyle(cellStyle);
//设置列的宽度 //设置列的宽度
detailsSheet.setColumnWidth(j, 255*20); detailsSheet.setColumnWidth(j, 255 * 20);
} }
} }
} }
} }
} }
if(StringUtils.isNotEmpty(snapshot)){ if (StringUtils.isNotEmpty(snapshot)) {
//截图sheet 1px ≈ 2.33dx ≈ 0.48 dy 8*24 个单元格 //截图sheet 1px ≈ 2.33dx ≈ 0.48 dy 8*24 个单元格
HSSFSheet snapshotSheet = wb.createSheet("图表"); HSSFSheet snapshotSheet = wb.createSheet("图表");
short reDefaultRowHeight = (short)Math.round(request.getSnapshotHeight()*3.5/8); short reDefaultRowHeight = (short) Math.round(request.getSnapshotHeight() * 3.5 / 8);
int reDefaultColumnWidth = (int)Math.round(request.getSnapshotWidth()*0.25/24); int reDefaultColumnWidth = (int) Math.round(request.getSnapshotWidth() * 0.25 / 24);
snapshotSheet.setDefaultColumnWidth(reDefaultColumnWidth); snapshotSheet.setDefaultColumnWidth(reDefaultColumnWidth);
snapshotSheet.setDefaultRowHeight(reDefaultRowHeight); snapshotSheet.setDefaultRowHeight(reDefaultRowHeight);
//画图的顶级管理器,一个sheet只能获取一个(一定要注意这点)i //画图的顶级管理器,一个sheet只能获取一个(一定要注意这点)i
HSSFPatriarch patriarch = snapshotSheet.createDrawingPatriarch(); HSSFPatriarch patriarch = snapshotSheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, reDefaultColumnWidth, reDefaultColumnWidth,(short) 0, 0, (short)8, 24); HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, reDefaultColumnWidth, reDefaultColumnWidth, (short) 0, 0, (short) 8, 24);
anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_DO_RESIZE); anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_DO_RESIZE);
patriarch.createPicture(anchor, wb.addPicture(Base64Utils.decodeFromString(snapshot.replace(DATA_URL_TITLE,"")), HSSFWorkbook.PICTURE_TYPE_JPEG)); patriarch.createPicture(anchor, wb.addPicture(Base64Utils.decodeFromString(snapshot.replace(DATA_URL_TITLE, "")), HSSFWorkbook.PICTURE_TYPE_JPEG));
} }
response.setContentType("application/vnd.ms-excel"); response.setContentType("application/vnd.ms-excel");
//文件名称 //文件名称
......
package io.dataease.service.staticResource; package io.dataease.service.staticResource;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import io.dataease.commons.utils.FileUtils; import io.dataease.commons.utils.FileUtils;
import io.dataease.commons.utils.LogUtil; import io.dataease.commons.utils.LogUtil;
import io.dataease.commons.utils.StaticResourceUtils;
import io.dataease.controller.request.resource.StaticResourceRequest;
import io.dataease.exception.DataEaseException; import io.dataease.exception.DataEaseException;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
/** /**
* Author: wangjiahao * Author: wangjiahao
...@@ -45,4 +51,38 @@ public class StaticResourceService { ...@@ -45,4 +51,38 @@ public class StaticResourceService {
DataEaseException.throwException(e); DataEaseException.throwException(e);
} }
} }
public void saveFilesToServe(String staticResource){
if(StringUtils.isNotEmpty(staticResource)){
Map<String,String> resource = JSON.parseObject(staticResource,Map.class);
for(Map.Entry<String,String> entry:resource.entrySet()){
String path = entry.getKey();
Path uploadPath = Paths.get(staticDir.toString(), path.substring(path.lastIndexOf("/")+1,path.length()));
try{
if (uploadPath.toFile().exists()) {
LogUtil.info("file exists");
}else{
String content = entry.getValue();
if(StringUtils.isNotEmpty(content)){
Files.createFile(uploadPath);
FileCopyUtils.copy(new BASE64Decoder().decodeBuffer(content),Files.newOutputStream(uploadPath));
}
}
}catch (Exception e){
LogUtil.error("template static resource save error"+e.getMessage());
}
}
}
}
public Map<String,String> findResourceAsBase64(StaticResourceRequest resourceRequest){
Map<String,String> result = new HashMap<>();
if(CollectionUtil.isNotEmpty(resourceRequest.getResourcePathList())){
for(String path :resourceRequest.getResourcePathList()){
String value = StaticResourceUtils.getImgFileToBase64(path.substring(path.lastIndexOf("/")+1,path.length()));
result.put(path,value);
}
}
return result;
}
} }
...@@ -24,3 +24,12 @@ export function uploadFileResult(file, callback) { ...@@ -24,3 +24,12 @@ export function uploadFileResult(file, callback) {
}) })
} }
export function findResourceAsBase64(params) {
return request({
url: '/static/resource/findResourceAsBase64',
method: 'post',
data: params,
loading: false
})
}
...@@ -542,9 +542,9 @@ export default { ...@@ -542,9 +542,9 @@ export default {
style['padding'] = (this.element.commonBackground.innerPadding || 0) + 'px' style['padding'] = (this.element.commonBackground.innerPadding || 0) + 'px'
style['border-radius'] = (this.element.commonBackground.borderRadius || 0) + 'px' style['border-radius'] = (this.element.commonBackground.borderRadius || 0) + 'px'
if (this.element.commonBackground.enable) { if (this.element.commonBackground.enable) {
if (this.element.commonBackground.backgroundType === 'innerImage') { if (this.element.commonBackground.backgroundType === 'innerImage' && this.element.commonBackground.innerImage) {
style['background'] = `url(${this.element.commonBackground.innerImage}) no-repeat` style['background'] = `url(${this.element.commonBackground.innerImage}) no-repeat`
} else if (this.element.commonBackground.backgroundType === 'outerImage') { } else if (this.element.commonBackground.backgroundType === 'outerImage' && this.element.commonBackground.outerImage) {
style['background'] = `url(${this.element.commonBackground.outerImage}) no-repeat` style['background'] = `url(${this.element.commonBackground.outerImage}) no-repeat`
} else if (this.element.commonBackground.backgroundType === 'color') { } else if (this.element.commonBackground.backgroundType === 'color') {
style['background-color'] = hexColorToRGBA(this.element.commonBackground.color, this.element.commonBackground.alpha) style['background-color'] = hexColorToRGBA(this.element.commonBackground.color, this.element.commonBackground.alpha)
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
:style="getComponentStyleDefault(config.style)" :style="getComponentStyleDefault(config.style)"
:prop-value="config.propValue" :prop-value="config.propValue"
:is-edit="false" :is-edit="false"
:in-screen="inScreen"
:active="componentActiveFlag" :active="componentActiveFlag"
:element="config" :element="config"
:search-count="searchCount" :search-count="searchCount"
...@@ -104,13 +105,13 @@ export default { ...@@ -104,13 +105,13 @@ export default {
style['padding'] = (this.config.commonBackground.innerPadding || 0) + 'px' style['padding'] = (this.config.commonBackground.innerPadding || 0) + 'px'
style['border-radius'] = (this.config.commonBackground.borderRadius || 0) + 'px' style['border-radius'] = (this.config.commonBackground.borderRadius || 0) + 'px'
if (this.config.commonBackground.enable) { if (this.config.commonBackground.enable) {
if (this.config.commonBackground.backgroundType === 'innerImage') { if (this.config.commonBackground.backgroundType === 'innerImage' && this.config.commonBackground.innerImage) {
let innerImage = this.config.commonBackground.innerImage let innerImage = this.config.commonBackground.innerImage
if (this.screenShot) { if (this.screenShot) {
innerImage = innerImage.replace('svg', 'png') innerImage = innerImage.replace('svg', 'png')
} }
style['background'] = `url(${innerImage}) no-repeat` style['background'] = `url(${innerImage}) no-repeat`
} else if (this.config.commonBackground.backgroundType === 'outerImage') { } else if (this.config.commonBackground.backgroundType === 'outerImage' && this.config.commonBackground.outerImage) {
style['background'] = `url(${this.config.commonBackground.outerImage}) no-repeat` style['background'] = `url(${this.config.commonBackground.outerImage}) no-repeat`
} else if (this.config.commonBackground.backgroundType === 'color') { } else if (this.config.commonBackground.backgroundType === 'color') {
style['background-color'] = hexColorToRGBA(this.config.commonBackground.color, this.config.commonBackground.alpha) style['background-color'] = hexColorToRGBA(this.config.commonBackground.color, this.config.commonBackground.alpha)
......
<template> <template>
<el-row ref="mainPlayer" style="width: 100%;height: 100%"> <el-row ref="mainPlayer" style="width: 100%;height: 100%">
<div v-if="element.streamMediaLinks[element.streamMediaLinks.videoType].url" class="video-container"> <div v-if="element.streamMediaLinks[element.streamMediaLinks.videoType].url" class="video-container">
<video :ref="'player-'+element.id" class="centered-video" name="centeredVideo" :loop="pOption.loop" controls muted /> <video :ref="'player-'+element.id" class="centered-video" name="centeredVideo" :loop="pOption.loop" :controls="inScreen" muted />
<div v-if="editMode==='edit'" class="stream-mask edit-mask" /> <div v-if="editMode==='edit'" class="stream-mask edit-mask" />
<div v-if="mobileLayoutStatus" class="stream-mask mobile-layout-mask"> <div v-if="mobileLayoutStatus" class="stream-mask">
<span style="opacity: 0.7;"> <span style="opacity: 0.7;">
<span style="color: lightgray;">{{ $t('panel.stream_mobile_tips') }}</span> <span style="color: lightgray;">{{ $t('panel.stream_mobile_tips') }}</span>
</span> </span>
...@@ -43,6 +43,11 @@ export default { ...@@ -43,6 +43,11 @@ export default {
h: { h: {
type: Number, type: Number,
default: 200 default: 200
},
inScreen: {
type: Boolean,
required: false,
default: true
} }
}, },
data() { data() {
...@@ -176,8 +181,5 @@ export default { ...@@ -176,8 +181,5 @@ export default {
opacity: 0; opacity: 0;
} }
.mobile-layout-mask{
}
</style> </style>
...@@ -124,7 +124,7 @@ export default { ...@@ -124,7 +124,7 @@ export default {
thirdparty: '第三方登录', thirdparty: '第三方登录',
thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!', thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!',
expires: '登录信息过期,请重新登录', expires: '登录信息过期,请重新登录',
tokenError: '登信息错误,请重新登录', tokenError: '登信息错误,请重新登录',
username_error: '请输入正确的 ID', username_error: '请输入正确的 ID',
password_error: '密码不小于 8 位', password_error: '密码不小于 8 位',
re_login: '重新登录', re_login: '重新登录',
......
...@@ -279,7 +279,7 @@ const data = { ...@@ -279,7 +279,7 @@ const data = {
const ele = element.options.tabList[idx].content const ele = element.options.tabList[idx].content
if (!ele.type || ele.type !== 'view') continue if (!ele.type || ele.type !== 'view') continue
const currentFilters = [] const currentFilters = element.linkageFilters || [] // 当前联动filter
data.dimensionList.forEach(dimension => { data.dimensionList.forEach(dimension => {
const sourceInfo = viewId + '#' + dimension.id const sourceInfo = viewId + '#' + dimension.id
...@@ -312,9 +312,9 @@ const data = { ...@@ -312,9 +312,9 @@ const data = {
state.componentData[index] = element state.componentData[index] = element
} }
if (!element.type || element.type !== 'view') continue if (!element.type || element.type !== 'view') continue
// const currentFilters = element.linkageFilters || [] // 当前联动filter const currentFilters = element.linkageFilters || [] // 当前联动filter
// 联动的视图情况历史条件 // 联动的视图情况历史条件
const currentFilters = [] // const currentFilters = []
data.dimensionList.forEach(dimension => { data.dimensionList.forEach(dimension => {
const sourceInfo = viewId + '#' + dimension.id const sourceInfo = viewId + '#' + dimension.id
......
...@@ -169,6 +169,7 @@ export default { ...@@ -169,6 +169,7 @@ export default {
this.editPanel.panelInfo.panelStyle = this.importTemplateInfo.panelStyle this.editPanel.panelInfo.panelStyle = this.importTemplateInfo.panelStyle
this.editPanel.panelInfo.panelData = this.importTemplateInfo.panelData this.editPanel.panelInfo.panelData = this.importTemplateInfo.panelData
this.editPanel.panelInfo.dynamicData = this.importTemplateInfo.dynamicData this.editPanel.panelInfo.dynamicData = this.importTemplateInfo.dynamicData
this.editPanel.panelInfo.staticResource = this.importTemplateInfo.staticResource
} }
reader.readAsText(file) reader.readAsText(file)
}, },
......
...@@ -139,6 +139,8 @@ import ShareHead from '@/views/panel/GrantAuth/ShareHead' ...@@ -139,6 +139,8 @@ import ShareHead from '@/views/panel/GrantAuth/ShareHead'
import { initPanelData } from '@/api/panel/panel' import { initPanelData } from '@/api/panel/panel'
import { proxyInitPanelData } from '@/api/panel/shareProxy' import { proxyInitPanelData } from '@/api/panel/shareProxy'
import { dataURLToBlob } from '@/components/canvas/utils/utils' import { dataURLToBlob } from '@/components/canvas/utils/utils'
import { findResourceAsBase64, readFile } from '@/api/staticResource/staticResource'
export default { export default {
name: 'PanelViewShow', name: 'PanelViewShow',
components: { Preview, SaveToTemplate, PDFPreExport, ShareHead }, components: { Preview, SaveToTemplate, PDFPreExport, ShareHead },
...@@ -262,25 +264,52 @@ export default { ...@@ -262,25 +264,52 @@ export default {
}, 50) }, 50)
}, },
downloadToTemplate() { downloadToTemplate() {
this.dataLoading = true const _this = this
setTimeout(() => { _this.dataLoading = true
_this.findStaticSource(function(staticResource) {
html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => { html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => {
this.dataLoading = false _this.dataLoading = false
const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.2是图片质量 const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.1是图片质量
if (snapshot !== '') { if (snapshot !== '') {
this.templateInfo = { _this.templateInfo = {
name: this.$store.state.panel.panelInfo.name, name: _this.$store.state.panel.panelInfo.name,
templateType: 'self', templateType: 'self',
snapshot: snapshot, snapshot: snapshot,
panelStyle: JSON.stringify(this.canvasStyleData), panelStyle: JSON.stringify(_this.canvasStyleData),
panelData: JSON.stringify(this.componentData), panelData: JSON.stringify(_this.componentData),
dynamicData: JSON.stringify(this.panelViewDetailsInfo) dynamicData: JSON.stringify(_this.panelViewDetailsInfo),
staticResource: JSON.stringify(staticResource || {})
} }
const blob = new Blob([JSON.stringify(this.templateInfo)], { type: '' }) const blob = new Blob([JSON.stringify(_this.templateInfo)], { type: '' })
FileSaver.saveAs(blob, this.$store.state.panel.panelInfo.name + '-TEMPLATE.DET') FileSaver.saveAs(blob, _this.$store.state.panel.panelInfo.name + '-TEMPLATE.DET')
} }
}) })
}, 50) })
},
// 解析静态文件
findStaticSource(callBack) {
const staticResource = []
// 系统背景文件
if (this.canvasStyleData.panel.imageUrl && this.canvasStyleData.panel.imageUrl.indexOf('static-resource') > -1) {
staticResource.push(this.canvasStyleData.panel.imageUrl)
}
this.componentData.forEach(item => {
if (item.commonBackground && item.commonBackground.outerImage && item.commonBackground.outerImage.indexOf('static-resource') > -1) {
staticResource.push(item.commonBackground.outerImage)
}
})
if (staticResource.length > 0) {
try {
findResourceAsBase64({ resourcePathList: staticResource }).then((rsp) => {
callBack(rsp.data)
})
} catch (e) {
console.log('findResourceAsBase64 error')
callBack()
}
} else {
callBack()
}
}, },
downloadAsImage() { downloadAsImage() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论