feat(X-Pack): 定时报告-支持数据权限设置

This commit is contained in:
fit2cloud-chenyw
2026-03-10 15:09:36 +08:00
committed by fit2cloud-chenyw
parent 00548d8331
commit 405da0f81e
17 changed files with 371 additions and 5 deletions

View File

@@ -108,11 +108,7 @@
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-java.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.angus</groupId>
<artifactId>angus-mail</artifactId>

View File

@@ -0,0 +1,29 @@
package io.dataease.visualization.dao.perext;
import io.dataease.dataset.dao.auto.entity.CoreDatasetGroup;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface ResourcePermissionMapper {
@Select("select `component_data` from data_visualization_info where id = #{id}")
String queryResourceData(@Param("id") Long id);
@Select("""
<script>
select cdg.* from core_dataset_group cdg
where EXISTS
(SELECT 1 FROM core_chart_view cv WHERE cv.table_id = cdg.id and cv.id IN
<foreach item='item' index='index' collection='viewIds' open='(' separator=',' close=')'>
#{item}
</foreach>
)
</script>
""")
List<CoreDatasetGroup> queryDataSetList(@Param("viewIds") List<Long> viewIds);
}

View File

@@ -0,0 +1,141 @@
package io.dataease.visualization.manage;
import com.fasterxml.jackson.core.type.TypeReference;
import io.dataease.api.dataset.union.DatasetTableInfoDTO;
import io.dataease.api.dataset.union.UnionDTO;
import io.dataease.api.report.bo.DatasetPermissionTemplate;
import io.dataease.api.report.bo.TableSysVariable;
import io.dataease.dataset.dao.auto.entity.CoreDatasetGroup;
import io.dataease.dataset.utils.DatasetTableTypeConstants;
import io.dataease.extensions.datasource.dto.DatasetTableDTO;
import io.dataease.utils.JsonUtil;
import io.dataease.visualization.dao.perext.ResourcePermissionMapper;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Component
public class ResourcePermissionManage {
@Resource
private ResourcePermissionMapper resourcePermissionMapper;
public static final String regex2 = "\\$f2cde\\[(.*?)\\]";
public List<DatasetPermissionTemplate> queruDatasetPermissionTemplate(Long resourceId) {
String componentDataText = resourcePermissionMapper.queryResourceData(resourceId);
TypeReference<List<Map<String, Object>>> tokenType = new TypeReference<>() {
};
List<Map<String, Object>> componentData = JsonUtil.parseList(componentDataText, tokenType);
List<Map<String, Object>> userViewList = getUserViewList(componentData);
List<Long> viewIds = userViewList.stream().filter(item -> ObjectUtils.isNotEmpty(item.get("id"))).map(item -> Long.parseLong(item.get("id").toString())).collect(Collectors.toList());
List<CoreDatasetGroup> datasetGroups = resourcePermissionMapper.queryDataSetList(viewIds);
return getDatasetPermissionTemplate(datasetGroups);
}
private static boolean isParams(String paramId) {
if (Arrays.asList("sysParams.userId", "sysParams.userEmail", "sysParams.userName").contains(paramId)) {
return true;
}
boolean isLong = false;
try {
Long.valueOf(paramId);
isLong = true;
} catch (Exception e) {
isLong = false;
}
if (paramId.length() >= 18 && isLong) {
return true;
}
return false;
}
private List<Map<String, Object>> getUserViewList(List<Map<String, Object>> componentData) {
List<Map<String, Object>> userViewList = new ArrayList<>();
Stack<Map<String, Object>> stack = new Stack<>();
stack.addAll(componentData);
while (!stack.isEmpty()) {
Map<String, Object> node = stack.pop();
if ("UserView".equals(node.get("component"))) {
userViewList.add(node);
}
if ("DeTabs".equals(node.get("component"))) {
Object propValueObj = null;
List<Map<String, Object>> tabComponentList = null;
if (ObjectUtils.isNotEmpty(propValueObj = node.get("propValue")) && CollectionUtils.isNotEmpty(tabComponentList = (List<Map<String, Object>>) propValueObj)) {
List<Map<String, Object>> innerComponentList = tabComponentList.stream().filter(item -> ObjectUtils.isNotEmpty(item.get("componentData"))).flatMap(propValueItem -> {
List<Map<String, Object>> mapList = (List<Map<String, Object>>) propValueItem.get("componentData");
return mapList.stream();
}).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(innerComponentList)) {
stack.addAll(innerComponentList);
}
}
}
}
return userViewList;
}
private List<DatasetPermissionTemplate> getDatasetPermissionTemplate(List<CoreDatasetGroup> datasetGroups) {
TypeReference<List<UnionDTO>> typeReference = new TypeReference<>() {
};
List<DatasetPermissionTemplate> templateList = new ArrayList<>();
datasetGroups.forEach(group -> {
DatasetPermissionTemplate template = new DatasetPermissionTemplate();
template.setDatasetId(group.getId());
String info = group.getInfo();
List<UnionDTO> unionList = JsonUtil.parseList(info, typeReference);
Stack<UnionDTO> stack = new Stack<>();
stack.addAll(unionList);
Set<Long> dsIdSet = new HashSet<>();
List<TableSysVariable> tableSysVariables = new ArrayList<>();
while (!stack.isEmpty()) {
UnionDTO union = stack.pop();
DatasetTableDTO currentDs = union.getCurrentDs();
dsIdSet.add(currentDs.getDatasourceId());
Long currentTableId = currentDs.getId();
if (ObjectUtils.isNotEmpty(currentDs.getType()) && currentDs.getType().equals(DatasetTableTypeConstants.DATASET_TABLE_SQL)) {
String tableInfoText = currentDs.getInfo();
DatasetTableInfoDTO tableInfoDTO = JsonUtil.parseObject(tableInfoText, DatasetTableInfoDTO.class);
String s = new String(Base64.getDecoder().decode(tableInfoDTO.getSql()));
Pattern pattern = Pattern.compile(regex2);
Matcher matcher = pattern.matcher(s);
List<String> sysVariables = new ArrayList<>();
while (matcher.find()) {
String paramId = matcher.group().substring(7, matcher.group().length() - 1);
if (!isParams(paramId)) {
continue;
}
sysVariables.add(paramId);
}
if (CollectionUtils.isNotEmpty(sysVariables)) {
TableSysVariable tableSysVariable = new TableSysVariable();
tableSysVariable.setTableId(currentTableId);
tableSysVariable.setSysVariables(sysVariables);
tableSysVariables.add(tableSysVariable);
}
}
if (CollectionUtils.isNotEmpty(union.getChildrenDs())) {
stack.addAll(union.getChildrenDs());
}
}
template.setDsIdSet(dsIdSet);
template.setTableSysVariables(tableSysVariables);
templateList.add(template);
});
return templateList;
}
}

View File

@@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
import io.dataease.api.dataset.union.DatasetTableInfoDTO;
import io.dataease.api.dataset.union.UnionDTO;
import io.dataease.api.report.bo.DatasetPermissionTemplate;
import io.dataease.api.template.dto.TemplateManageFileDTO;
import io.dataease.api.template.dto.VisualizationTemplateExtendDataDTO;
import io.dataease.api.visualization.DataVisualizationApi;
@@ -68,6 +69,7 @@ import io.dataease.visualization.dao.auto.mapper.VisualizationWatermarkMapper;
import io.dataease.visualization.dao.ext.mapper.ExtDataVisualizationMapper;
import io.dataease.visualization.manage.CoreBusiManage;
import io.dataease.visualization.manage.CoreVisualizationManage;
import io.dataease.visualization.manage.ResourcePermissionManage;
import io.dataease.visualization.utils.VisualizationUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
@@ -1142,4 +1144,11 @@ public class DataVisualizationServer implements DataVisualizationApi {
}
return result;
}
@Resource
private ResourcePermissionManage resourcePermissionManage;
@Override
public List<DatasetPermissionTemplate> queruDatasetPermissionTemplate(Long resourceId) {
return resourcePermissionManage.queruDatasetPermissionTemplate(resourceId);
}
}

View File

@@ -0,0 +1,21 @@
package io.dataease.api.report.bo;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import java.util.List;
import java.util.Set;
@Data
public class DatasetPermissionTemplate {
private Long datasetId;
private Set<Long> dsIdSet;
private List<TableSysVariable> tableSysVariables;
public boolean hasSysVariable() {
return CollectionUtils.isNotEmpty(tableSysVariables);
}
}

View File

@@ -0,0 +1,17 @@
package io.dataease.api.report.bo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class TableSysVariable {
private Long tableId;
private List<String> sysVariables;
}

View File

@@ -3,6 +3,7 @@ package io.dataease.api.visualization;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.api.report.bo.DatasetPermissionTemplate;
import io.dataease.api.visualization.dto.VisualizationViewTableDTO;
import io.dataease.api.visualization.request.DataVisualizationBaseRequest;
import io.dataease.api.visualization.request.VisualizationAppExportRequest;
@@ -14,6 +15,7 @@ import io.dataease.auth.DeApiPath;
import io.dataease.auth.DePermit;
import io.dataease.model.BusiNodeRequest;
import io.dataease.model.BusiNodeVO;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
@@ -170,4 +172,7 @@ public interface DataVisualizationApi {
@Operation(summary = "导出图片日志记录")
void exportLogImg(@RequestBody DataVisualizationBaseRequest request) throws Exception;
@Hidden
List<DatasetPermissionTemplate> queruDatasetPermissionTemplate(Long resourceId);
}

View File

@@ -0,0 +1,11 @@
package io.dataease.api.permissions.auth.api;
import io.dataease.api.permissions.auth.dto.ResourcePermissionRequest;
import io.dataease.api.permissions.auth.vo.ResourcePermissionVO;
import java.util.List;
public interface ResourceAuthApi {
List<ResourcePermissionVO> queryResourcePermission(ResourcePermissionRequest request);
}

View File

@@ -0,0 +1,17 @@
package io.dataease.api.permissions.auth.dto;
import io.dataease.api.permissions.user.vo.UserReciVO;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class ResourcePermissionRequest implements Serializable {
private List<Long> resourceIds;
private Integer resourceType;
private List<UserReciVO> targets;
}

View File

@@ -0,0 +1,14 @@
package io.dataease.api.permissions.auth.vo;
import io.dataease.api.permissions.user.vo.UserReciVO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
public class ResourcePermissionVO extends UserReciVO implements Serializable {
private Long resourceId;
private boolean enable;
}

View File

@@ -0,0 +1,10 @@
package io.dataease.api.permissions.dataset.api;
import io.dataease.api.permissions.dataset.vo.RowColPermissionItem;
import java.util.List;
public interface RowColPermissionApi {
List<RowColPermissionItem> query(List<Long> datastetIds);
}

View File

@@ -0,0 +1,15 @@
package io.dataease.api.permissions.dataset.bo;
import io.dataease.api.permissions.dataset.vo.ColPermissionInfo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class ColPermissionBo implements Serializable {
private boolean enable;
private List<ColPermissionInfo> columns;
}

View File

@@ -0,0 +1,18 @@
package io.dataease.api.permissions.dataset.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class ColPermissionInfo implements Serializable {
private boolean selected;
private Long id;
private String opt;
private Object desensitizationRule;
}

View File

@@ -0,0 +1,29 @@
package io.dataease.api.permissions.dataset.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class RowColPermissionItem implements Serializable {
private Long id;
private boolean enable;
private String authTargetType;
private String authTargetId;
private Long datasetId;
private String permissionText;
private List<Long> whiteListUserIds;
private String type;
private List<ColPermissionInfo> colPermissionInfos;
}

View File

@@ -244,4 +244,8 @@ public interface UserApi {
@GetMapping("/lang")
String userLang();
@Hidden
List<UserReciVO> getFormatRecipient(Long oid, List<Long> uidList, List<Long> ridList);
}

View File

@@ -0,0 +1,26 @@
package io.dataease.api.permissions.user.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserReciVO implements Serializable {
private Long userId;
private List<Long> roleIds;
private boolean hasRootRole;
private List<Long> commonRoleIds;
public UserReciVO(Long userId) {
this.userId = userId;
}
}

View File

@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
import java.util.Map;
import static io.dataease.constant.AuthResourceEnum.SYSTEM;
@@ -68,4 +69,7 @@ public interface SysVariablesApi {
@PostMapping("/value/batchDel")
void batchDel(@RequestBody List<Long> ids);
@Hidden
Map<Long, Map<String, String>> queryBatchSysVariable(List<Long> uids);
}