package com.aurora.service.impl; import com.aurora.model.dto.LabelOptionDTO; import com.aurora.model.dto.ResourceDTO; import com.aurora.entity.Resource; import com.aurora.entity.RoleResource; import com.aurora.exception.BizException; import com.aurora.handler.FilterInvocationSecurityMetadataSourceImpl; import com.aurora.mapper.ResourceMapper; import com.aurora.mapper.RoleResourceMapper; import com.aurora.service.ResourceService; import com.aurora.util.BeanCopyUtil; import com.aurora.model.vo.ConditionVO; import com.aurora.model.vo.ResourceVO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import static com.aurora.constant.CommonConstant.FALSE; @Service public class ResourceServiceImpl extends ServiceImpl implements ResourceService { @Autowired private RestTemplate restTemplate; @Autowired private ResourceMapper resourceMapper; @Autowired private RoleResourceMapper roleResourceMapper; @Autowired private FilterInvocationSecurityMetadataSourceImpl filterInvocationSecurityMetadataSource; @SuppressWarnings("all") @Transactional(rollbackFor = Exception.class) @Override public void importSwagger() { this.remove(null); roleResourceMapper.delete(null); List resources = new ArrayList<>(); Map data = restTemplate.getForObject("http://localhost:8080/v2/api-docs", Map.class); List> tagList = (List>) data.get("tags"); tagList.forEach(item -> { Resource resource = Resource.builder() .resourceName(item.get("name")) .isAnonymous(FALSE) .createTime(LocalDateTime.now()) .build(); resources.add(resource); }); this.saveBatch(resources); Map permissionMap = resources.stream() .collect(Collectors.toMap(Resource::getResourceName, Resource::getId)); resources.clear(); Map>> path = (Map>>) data.get("paths"); path.forEach((url, value) -> value.forEach((requestMethod, info) -> { String permissionName = info.get("summary").toString(); List tag = (List) info.get("tags"); Integer parentId = permissionMap.get(tag.get(0)); Resource resource = Resource.builder() .resourceName(permissionName) .url(url.replaceAll("\\{[^}]*\\}", "*")) .parentId(parentId) .requestMethod(requestMethod.toUpperCase()) .isAnonymous(FALSE) .createTime(LocalDateTime.now()) .build(); resources.add(resource); })); this.saveBatch(resources); } @Override public void saveOrUpdateResource(ResourceVO resourceVO) { Resource resource = BeanCopyUtil.copyObject(resourceVO, Resource.class); this.saveOrUpdate(resource); filterInvocationSecurityMetadataSource.clearDataSource(); } @Override public void deleteResource(Integer resourceId) { Integer count = roleResourceMapper.selectCount(new LambdaQueryWrapper() .eq(RoleResource::getResourceId, resourceId)); if (count > 0) { throw new BizException("该资源下存在角色"); } List resourceIds = resourceMapper.selectList(new LambdaQueryWrapper() .select(Resource::getId). eq(Resource::getParentId, resourceId)) .stream() .map(Resource::getId) .collect(Collectors.toList()); resourceIds.add(resourceId); resourceMapper.deleteBatchIds(resourceIds); } @Override public List listResources(ConditionVO conditionVO) { List resources = resourceMapper.selectList(new LambdaQueryWrapper() .like(StringUtils.isNotBlank(conditionVO.getKeywords()), Resource::getResourceName, conditionVO.getKeywords())); List parents = listResourceModule(resources); Map> childrenMap = listResourceChildren(resources); List resourceDTOs = parents.stream().map(item -> { ResourceDTO resourceDTO = BeanCopyUtil.copyObject(item, ResourceDTO.class); List child = BeanCopyUtil.copyList(childrenMap.get(item.getId()), ResourceDTO.class); resourceDTO.setChildren(child); childrenMap.remove(item.getId()); return resourceDTO; }).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(childrenMap)) { List childrenList = new ArrayList<>(); childrenMap.values().forEach(childrenList::addAll); List childrenDTOs = childrenList.stream() .map(item -> BeanCopyUtil.copyObject(item, ResourceDTO.class)) .collect(Collectors.toList()); resourceDTOs.addAll(childrenDTOs); } return resourceDTOs; } @Override public List listResourceOption() { List resources = resourceMapper.selectList(new LambdaQueryWrapper() .select(Resource::getId, Resource::getResourceName, Resource::getParentId) .eq(Resource::getIsAnonymous, FALSE)); List parents = listResourceModule(resources); Map> childrenMap = listResourceChildren(resources); return parents.stream().map(item -> { List list = new ArrayList<>(); List children = childrenMap.get(item.getId()); if (CollectionUtils.isNotEmpty(children)) { list = children.stream() .map(resource -> LabelOptionDTO.builder() .id(resource.getId()) .label(resource.getResourceName()) .build()) .collect(Collectors.toList()); } return LabelOptionDTO.builder() .id(item.getId()) .label(item.getResourceName()) .children(list) .build(); }).collect(Collectors.toList()); } private List listResourceModule(List resourceList) { return resourceList.stream() .filter(item -> Objects.isNull(item.getParentId())) .collect(Collectors.toList()); } private Map> listResourceChildren(List resourceList) { return resourceList.stream() .filter(item -> Objects.nonNull(item.getParentId())) .collect(Collectors.groupingBy(Resource::getParentId)); } }