|
@@ -1,28 +1,30 @@
|
|
package com.dragoninfo.dcuc.auth.auth.business.impl;
|
|
package com.dragoninfo.dcuc.auth.auth.business.impl;
|
|
|
|
|
|
import com.dragoninfo.dcuc.app.enumresources.DataResourceEnum;
|
|
import com.dragoninfo.dcuc.app.enumresources.DataResourceEnum;
|
|
|
|
+import com.dragoninfo.dcuc.app.facade.IDataResourceFacade;
|
|
|
|
+import com.dragoninfo.dcuc.app.vo.DataResourceClassifyVo;
|
|
|
|
+import com.dragoninfo.dcuc.app.vo.DataResourceTreeVo;
|
|
import com.dragoninfo.dcuc.auth.auth.business.IDataAuthBusiness;
|
|
import com.dragoninfo.dcuc.auth.auth.business.IDataAuthBusiness;
|
|
-import com.dragoninfo.dcuc.auth.auth.dto.data.DataAuthDTO;
|
|
|
|
-import com.dragoninfo.dcuc.auth.auth.dto.data.DataClassifyDTO;
|
|
|
|
-import com.dragoninfo.dcuc.auth.auth.dto.data.SubDataAuthQueryDTO;
|
|
|
|
-import com.dragoninfo.dcuc.auth.auth.dto.data.SubDataDTO;
|
|
|
|
|
|
+import com.dragoninfo.dcuc.auth.auth.dto.data.*;
|
|
import com.dragoninfo.dcuc.auth.auth.enumresources.SubDataAuthTypeEnum;
|
|
import com.dragoninfo.dcuc.auth.auth.enumresources.SubDataAuthTypeEnum;
|
|
import com.dragoninfo.dcuc.auth.auth.service.IBusService;
|
|
import com.dragoninfo.dcuc.auth.auth.service.IBusService;
|
|
import com.dragoninfo.dcuc.auth.auth.service.IDataAuthService;
|
|
import com.dragoninfo.dcuc.auth.auth.service.IDataAuthService;
|
|
import com.dragoninfo.dcuc.user.user.entity.UserInfo;
|
|
import com.dragoninfo.dcuc.user.user.entity.UserInfo;
|
|
import com.dragoninfo.dcuc.user.user.facade.IUserFacade;
|
|
import com.dragoninfo.dcuc.user.user.facade.IUserFacade;
|
|
import com.dragonsoft.duceap.base.enums.BooleanEnum;
|
|
import com.dragonsoft.duceap.base.enums.BooleanEnum;
|
|
|
|
+import com.dragonsoft.duceap.commons.util.MapUtils;
|
|
import com.dragonsoft.duceap.commons.util.collections.CollectionUtils;
|
|
import com.dragonsoft.duceap.commons.util.collections.CollectionUtils;
|
|
import com.dragonsoft.duceap.commons.util.string.StringUtils;
|
|
import com.dragonsoft.duceap.commons.util.string.StringUtils;
|
|
import com.dragonsoft.duceap.core.search.Searchable;
|
|
import com.dragonsoft.duceap.core.search.Searchable;
|
|
import com.dragonsoft.duceap.core.search.enums.SearchOperator;
|
|
import com.dragonsoft.duceap.core.search.enums.SearchOperator;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
+import org.springframework.util.StopWatch;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -32,12 +34,18 @@ import java.util.stream.Collectors;
|
|
@Slf4j
|
|
@Slf4j
|
|
@Component
|
|
@Component
|
|
public class DataAuthBusiness implements IDataAuthBusiness {
|
|
public class DataAuthBusiness implements IDataAuthBusiness {
|
|
|
|
+
|
|
|
|
+ public static String idJoin = "|";
|
|
|
|
+
|
|
@Autowired
|
|
@Autowired
|
|
private IUserFacade userFacade;
|
|
private IUserFacade userFacade;
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
private IDataAuthService dataAuthService;
|
|
private IDataAuthService dataAuthService;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private IDataResourceFacade dataResourceFacade;
|
|
|
|
+
|
|
@Autowired
|
|
@Autowired
|
|
private IBusService busService;
|
|
private IBusService busService;
|
|
|
|
|
|
@@ -103,6 +111,45 @@ public class DataAuthBusiness implements IDataAuthBusiness {
|
|
return classifyDTOS;
|
|
return classifyDTOS;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public List<DataResourceDTO> userDataTreeByIdcard(String idcard, String authType) {
|
|
|
|
+ List<DataResourceDTO> resourceDTOS = new ArrayList<>();
|
|
|
|
+ //获取有权限的数据
|
|
|
|
+ List<DataClassifyDTO> dataClassifyDTOS = userDataAuthInfoByIdcard(idcard, authType);
|
|
|
|
+ if(CollectionUtils.isEmpty(dataClassifyDTOS)) {
|
|
|
|
+ return resourceDTOS;
|
|
|
|
+ }
|
|
|
|
+ //获取数据资源树
|
|
|
|
+ Map<String, DataResourceTreeVo> allTreeVosMap = getDataResourceTree(dataClassifyDTOS);
|
|
|
|
+
|
|
|
|
+ if(MapUtils.isEmpty(allTreeVosMap)){
|
|
|
|
+ return resourceDTOS;
|
|
|
|
+ }
|
|
|
|
+ //筛选有权限的树节点
|
|
|
|
+ List<DataResourceTreeVo> authTreeVoList = filterAuthTreeNode(dataClassifyDTOS, allTreeVosMap);
|
|
|
|
+
|
|
|
|
+ if(CollectionUtils.isEmpty(authTreeVoList)){
|
|
|
|
+ return resourceDTOS;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //将有权限的节点组装成树结构
|
|
|
|
+ List<DataResourceTreeVo> topTreeNodes = authTreeVoList.stream().filter(item -> item.getPId() == null).collect(Collectors.toList());
|
|
|
|
+ List<DataResourceTreeVo> childTreeNodes = authTreeVoList.stream().filter(item -> item.getPId() != null).collect(Collectors.toList());
|
|
|
|
+ for (DataResourceTreeVo topTreeNode : topTreeNodes) {
|
|
|
|
+ DataResourceTreeDTO topTreeDTO = convertToTreeDTO(topTreeNode, childTreeNodes);
|
|
|
|
+ final List<DataResourceTreeDTO> child = topTreeDTO.getChild();
|
|
|
|
+ if(CollectionUtils.isEmpty(child)){
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ //构建分级分类DTO
|
|
|
|
+ String id = topTreeDTO.getId();
|
|
|
|
+ DataResourceEnum dataEnum = DataResourceEnum.getByCode(id);
|
|
|
|
+ DataResourceDTO dataResourceDTO = new DataResourceDTO(dataEnum.getCode(),dataEnum.getLabel(),dataEnum.getAttrType().getValue());
|
|
|
|
+ dataResourceDTO.setNodes(new ArrayList<DataResourceTreeDTO>(){{addAll(child);}});
|
|
|
|
+ resourceDTOS.add(dataResourceDTO);
|
|
|
|
+ }
|
|
|
|
+ return resourceDTOS;
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
private List<DataClassifyDTO> getDataClassifyDTOS(List<DataAuthDTO> authDTOS) {
|
|
private List<DataClassifyDTO> getDataClassifyDTOS(List<DataAuthDTO> authDTOS) {
|
|
@@ -139,4 +186,119 @@ public class DataAuthBusiness implements IDataAuthBusiness {
|
|
return classifyDTOS;
|
|
return classifyDTOS;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将TreeVo转为DTO
|
|
|
|
+ * @param topTreeNode 顶级节点
|
|
|
|
+ * @param childTreeNodes 有权限的子节点
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private DataResourceTreeDTO convertToTreeDTO(DataResourceTreeVo topTreeNode, List<DataResourceTreeVo> childTreeNodes) {
|
|
|
|
+ DataResourceTreeDTO dto = new DataResourceTreeDTO();
|
|
|
|
+ BeanUtils.copyProperties(topTreeNode,dto,"child");
|
|
|
|
+ String id = topTreeNode.getId();
|
|
|
|
+ List<DataResourceTreeVo> childList = childTreeNodes.stream().filter(item -> item.getPId().equals(id)).collect(Collectors.toList());
|
|
|
|
+ if(CollectionUtils.isEmpty(childList)){
|
|
|
|
+ dto.setChild(null);
|
|
|
|
+ dto.setTreeNode(false);
|
|
|
|
+ }else {
|
|
|
|
+ List<DataResourceTreeDTO> list = new ArrayList<>();
|
|
|
|
+ for (DataResourceTreeVo child : childList) {
|
|
|
|
+ DataResourceTreeDTO childDTO = convertToTreeDTO(child,childTreeNodes);
|
|
|
|
+ list.add(childDTO);
|
|
|
|
+ }
|
|
|
|
+ dto.setChild(list);
|
|
|
|
+ dto.setTreeNode(true);
|
|
|
|
+ }
|
|
|
|
+ return dto;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 过滤有权限的树节点
|
|
|
|
+ * @param dataClassifyDTOS 有权限的分级分类数据
|
|
|
|
+ * @param allTreeVosMap 平铺的树节点
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private List<DataResourceTreeVo> filterAuthTreeNode(List<DataClassifyDTO> dataClassifyDTOS, Map<String, DataResourceTreeVo> allTreeVosMap) {
|
|
|
|
+ List<SubDataDTO> authDatas = dataClassifyDTOS.stream()
|
|
|
|
+ .map(item -> item.getTickedDatas())
|
|
|
|
+ .flatMap(List::stream)
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ Set<String> dataIds = authDatas.stream()
|
|
|
|
+ .map(item -> item.getClassifyCode() + idJoin + item.getDataId())
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
+ Set<String> authDataIds = new HashSet<>();
|
|
|
|
+ dataIds.stream().forEach(id->{
|
|
|
|
+ authDataIds.add(id);
|
|
|
|
+ String dataId = id;
|
|
|
|
+ int index;
|
|
|
|
+ while ((index = dataId.lastIndexOf(idJoin)) != -1){
|
|
|
|
+ authDataIds.add(dataId = dataId.substring(0, index));
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ //过滤有权限的树节点
|
|
|
|
+ return allTreeVosMap.entrySet().stream()
|
|
|
|
+ .filter(item -> authDataIds.contains(item.getKey()))
|
|
|
|
+ .collect(Collectors.mapping(Map.Entry::getValue, Collectors.toList()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取所有数据资源树
|
|
|
|
+ * @param dataClassifyDTOS 有权限的分级分类数据
|
|
|
|
+ * @return 平铺的树节点
|
|
|
|
+ */
|
|
|
|
+ private Map<String, DataResourceTreeVo> getDataResourceTree(List<DataClassifyDTO> dataClassifyDTOS) {
|
|
|
|
+ Set<String> attrTypeSet = dataClassifyDTOS
|
|
|
|
+ .stream()
|
|
|
|
+ .map(dataClassifyDTO -> dataClassifyDTO.getAttrType())
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
+ StopWatch stopWatch = new StopWatch();
|
|
|
|
+ stopWatch.start("get data resource tree");
|
|
|
|
+ //所有数据资源Map
|
|
|
|
+ Map<String, DataResourceTreeVo> allTreeVosMap = new HashMap<>();
|
|
|
|
+ List<CompletableFuture<List<DataResourceTreeVo>>> futureList = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ for (String attrType : attrTypeSet) {
|
|
|
|
+ //future多线程任务
|
|
|
|
+ //将树结构平铺成Map
|
|
|
|
+ //id唯一
|
|
|
|
+ CompletableFuture<List<DataResourceTreeVo>> cf = CompletableFuture.supplyAsync(()->{
|
|
|
|
+ List<DataResourceClassifyVo> dataResource = dataResourceFacade.getAllDataResourceTree(attrType);
|
|
|
|
+ List<DataResourceTreeVo> topTreeVos = dataResource.stream()
|
|
|
|
+ .map(item -> item.getNodes())
|
|
|
|
+ .flatMap(List::stream).collect(Collectors.toList());
|
|
|
|
+ return topTreeVos;
|
|
|
|
+ });
|
|
|
|
+ futureList.add(cf);
|
|
|
|
+ }
|
|
|
|
+ List<DataResourceTreeVo> result = CompletableFuture
|
|
|
|
+ .allOf(futureList.toArray(new CompletableFuture[futureList.size()]))
|
|
|
|
+ .thenApply(e -> futureList.stream().map(CompletableFuture::join).flatMap(List::stream).collect(Collectors.toList()))
|
|
|
|
+ .join();
|
|
|
|
+ convertTreeToMap(result,allTreeVosMap);
|
|
|
|
+ stopWatch.stop();
|
|
|
|
+ log.info("get data resource tree cost time:{}",stopWatch.getTotalTimeMillis());
|
|
|
|
+ return allTreeVosMap;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将树结构平铺成Map
|
|
|
|
+ * id唯一 key
|
|
|
|
+ * @param topTreeVos 顶级树节点
|
|
|
|
+ * @param allTreeVosMap
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private void convertTreeToMap(List<DataResourceTreeVo> topTreeVos, Map<String, DataResourceTreeVo> allTreeVosMap) {
|
|
|
|
+ for (DataResourceTreeVo topTreeVo : topTreeVos) {
|
|
|
|
+ String id = topTreeVo.getId();
|
|
|
|
+ allTreeVosMap.put(id, topTreeVo);
|
|
|
|
+ List<DataResourceTreeVo> child = topTreeVo.getChild();
|
|
|
|
+ if(CollectionUtils.isNotEmpty(child)){
|
|
|
|
+ convertTreeToMap(child, allTreeVosMap);
|
|
|
|
+ //将子级设置为null
|
|
|
|
+ topTreeVo.setChild(null);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|