17 changed files with 581 additions and 30 deletions
-
21common/src/main/java/com/canvas/web/config/CsPermissionConfig.java
-
42system/src/main/java/com/canvas/web/modules/system/controller/MenuController.java
-
1system/src/main/java/com/canvas/web/modules/system/controller/UserController.java
-
3system/src/main/java/com/canvas/web/modules/system/domain/Menu.java
-
41system/src/main/java/com/canvas/web/modules/system/repository/MenuRepository.java
-
22system/src/main/java/com/canvas/web/modules/system/repository/RoleRepository.java
-
48system/src/main/java/com/canvas/web/modules/system/service/MenuService.java
-
47system/src/main/java/com/canvas/web/modules/system/service/RoleService.java
-
19system/src/main/java/com/canvas/web/modules/system/service/dto/MenuDto.java
-
27system/src/main/java/com/canvas/web/modules/system/service/dto/MenuQueryCriteria.java
-
16system/src/main/java/com/canvas/web/modules/system/service/dto/MenuSmallDto.java
-
17system/src/main/java/com/canvas/web/modules/system/service/dto/RoleQueryCriteria.java
-
218system/src/main/java/com/canvas/web/modules/system/service/impl/MenuServiceImpl.java
-
61system/src/main/java/com/canvas/web/modules/system/service/impl/RoleServiceImpl.java
-
12system/src/main/java/com/canvas/web/modules/system/service/mapstruct/MenuSmallMapper.java
-
5system/src/main/java/com/canvas/web/modules/system/service/mapstruct/RoleMapper.java
-
11system/src/main/java/com/canvas/web/modules/system/service/mapstruct/RoleSmallMapper.java
@ -0,0 +1,21 @@ |
|||
package com.canvas.web.config; |
|||
|
|||
|
|||
import com.canvas.web.utils.SecurityUtils; |
|||
import org.springframework.security.core.GrantedAuthority; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Service(value = "cs") |
|||
public class CsPermissionConfig { |
|||
|
|||
public Boolean check(String ...permissions){ |
|||
// 获取当前用户的所有权限 |
|||
List<String> csPermissions= SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); |
|||
// 判断当前用户的所有权限是否包含接口上定义的权限 |
|||
return csPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(csPermissions::contains); |
|||
} |
|||
} |
@ -0,0 +1,42 @@ |
|||
package com.canvas.web.modules.system.controller; |
|||
|
|||
|
|||
import com.canvas.web.annotation.rest.AnonymousGetMapping; |
|||
import com.canvas.web.enums.ResponseEnum; |
|||
import com.canvas.web.modules.system.service.MenuService; |
|||
import com.canvas.web.modules.system.service.mapstruct.MenuMapper; |
|||
import com.canvas.web.utils.Response; |
|||
import io.swagger.annotations.Api; |
|||
import io.swagger.annotations.ApiOperation; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.security.access.prepost.PreAuthorize; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
@RestController |
|||
@RequiredArgsConstructor |
|||
@Api(tags = "菜单管理") |
|||
@RequestMapping("/api/menus") |
|||
public class MenuController { |
|||
|
|||
private final MenuService menuService; |
|||
private final MenuMapper menuMapper; |
|||
|
|||
@ApiOperation("返回全部菜单") |
|||
@AnonymousGetMapping("/lazy") |
|||
//@GetMapping(value = "lazy") |
|||
//@PreAuthorize("") |
|||
public Response<Object> query(@RequestParam(required=false) Long pid){ |
|||
return Response.success(menuService.getMenus(pid)); |
|||
} |
|||
|
|||
@ApiOperation("新增权限-下拉列表-获取所有菜单") |
|||
@AnonymousGetMapping("/dropdown/menu") |
|||
public Response<Object> queryDropDow(){ |
|||
return Response.success(menuService.queryAll()); |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,48 @@ |
|||
package com.canvas.web.modules.system.service; |
|||
|
|||
import com.canvas.web.modules.system.domain.Menu; |
|||
import com.canvas.web.modules.system.service.dto.MenuDto; |
|||
import com.canvas.web.modules.system.service.dto.MenuQueryCriteria; |
|||
import com.canvas.web.modules.system.service.dto.MenuSmallDto; |
|||
|
|||
import java.util.List; |
|||
import java.util.Set; |
|||
|
|||
public interface MenuService { |
|||
|
|||
//根据id查询 |
|||
MenuDto findById(long id); |
|||
|
|||
|
|||
//创建菜单 |
|||
void create(Menu resources); |
|||
|
|||
|
|||
//编辑 |
|||
void update(Menu resources); |
|||
|
|||
//获取所有子节点 |
|||
Set<Menu> getChildMenus(List<Menu> menuList,Set<Menu> menuSet); |
|||
|
|||
//构建菜单树 |
|||
List<MenuDto> buildTree(List<MenuDto> menuDtos); |
|||
|
|||
//根据id查询 |
|||
Menu findOne(Long id); |
|||
|
|||
//删除 |
|||
void delete(Set<Menu> menuSet); |
|||
|
|||
//懒加载菜单数据 |
|||
List<MenuDto> getMenus(Long pid); |
|||
|
|||
|
|||
//根据当前用户获取菜单 |
|||
List<MenuDto> findByUser(Long currentUserId); |
|||
|
|||
//查询全部数据,可带查询条件 |
|||
List<MenuDto> queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception; |
|||
|
|||
//获取所有菜单 |
|||
List<MenuSmallDto> queryAll(); |
|||
} |
@ -1,33 +1,50 @@ |
|||
package com.canvas.web.modules.system.service; |
|||
|
|||
import com.canvas.web.modules.system.domain.Role; |
|||
import com.canvas.web.modules.system.service.dto.RoleDto; |
|||
import com.canvas.web.modules.system.service.dto.RoleQueryCriteria; |
|||
import com.canvas.web.modules.system.service.dto.RoleSmallDto; |
|||
import com.canvas.web.modules.system.service.dto.UserDto; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.security.core.GrantedAuthority; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Set; |
|||
|
|||
public interface RoleService { |
|||
|
|||
/** |
|||
* 获取用户权限信息 |
|||
* @param user 用户信息 |
|||
* @return 权限信息 |
|||
*/ |
|||
//获取用户权限信息 |
|||
List<GrantedAuthority> mapToGrantedAuthorities(UserDto user); |
|||
|
|||
/** |
|||
* 根据用户ID查询 |
|||
* @param id 用户ID |
|||
* @return / |
|||
*/ |
|||
//根据用户ID查询用户 |
|||
List<RoleSmallDto> findByUsersId(Long id); |
|||
|
|||
/** |
|||
* 根据角色查询角色级别 |
|||
* @param roles / |
|||
* @return / |
|||
*/ |
|||
|
|||
//根据角色查询角色级别 |
|||
Integer findByRoles(Set<Role> roles); |
|||
|
|||
//根据id 查询菜单 |
|||
List<Role> findInMenuId(ArrayList<Long> longs); |
|||
|
|||
//创建角色 |
|||
void create(Role resources); |
|||
|
|||
//物理删除 |
|||
void delete(Set<Long> ids); |
|||
|
|||
//修改绑定的菜单 |
|||
void updateMenu(Role resources, RoleDto roleDTO); |
|||
|
|||
//根据菜单Id查询 |
|||
List<Role> findInMenuId(List<Long> menuIds); |
|||
|
|||
//无条件查询全部数据 |
|||
List<RoleDto> queryAll(); |
|||
|
|||
//带查询条件分页查询全部数据 |
|||
Object queryAll(RoleQueryCriteria criteria, Pageable pageable); |
|||
|
|||
//带查询条件查询全部数据 |
|||
List<RoleDto> queryAll(RoleQueryCriteria criteria); |
|||
} |
@ -0,0 +1,27 @@ |
|||
package com.canvas.web.modules.system.service.dto; |
|||
|
|||
|
|||
import com.canvas.web.annotation.Query; |
|||
import lombok.Data; |
|||
|
|||
import java.sql.Timestamp; |
|||
import java.util.List; |
|||
|
|||
@Data |
|||
public class MenuQueryCriteria { |
|||
|
|||
|
|||
@Query(blurry = "title,component,permission") |
|||
private String blurry; |
|||
|
|||
@Query(type = Query.Type.BETWEEN) |
|||
private List<Timestamp> createTime; |
|||
|
|||
@Query(type = Query.Type.IS_NULL,propName = "pid") |
|||
private Boolean pidIsNull; |
|||
|
|||
@Query |
|||
private Long pid; |
|||
|
|||
|
|||
} |
@ -0,0 +1,16 @@ |
|||
package com.canvas.web.modules.system.service.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
|
|||
@Data |
|||
public class MenuSmallDto implements Serializable { |
|||
|
|||
private Long id; |
|||
|
|||
private Long pid; |
|||
|
|||
private String title; |
|||
} |
@ -0,0 +1,17 @@ |
|||
package com.canvas.web.modules.system.service.dto; |
|||
|
|||
import com.canvas.web.annotation.Query; |
|||
import lombok.Data; |
|||
|
|||
import java.sql.Timestamp; |
|||
import java.util.List; |
|||
|
|||
|
|||
@Data |
|||
public class RoleQueryCriteria { |
|||
@Query(blurry = "name,description") |
|||
private String blurry; |
|||
|
|||
@Query(type = Query.Type.BETWEEN) |
|||
private List<Timestamp> createTime; |
|||
} |
@ -0,0 +1,218 @@ |
|||
package com.canvas.web.modules.system.service.impl; |
|||
|
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.canvas.web.enums.ResponseEnum; |
|||
import com.canvas.web.exception.BaseException; |
|||
import com.canvas.web.modules.system.domain.Menu; |
|||
import com.canvas.web.modules.system.domain.Role; |
|||
import com.canvas.web.modules.system.domain.User; |
|||
import com.canvas.web.modules.system.repository.MenuRepository; |
|||
import com.canvas.web.modules.system.repository.UserRepository; |
|||
import com.canvas.web.modules.system.service.MenuService; |
|||
import com.canvas.web.modules.system.service.RoleService; |
|||
import com.canvas.web.modules.system.service.dto.MenuDto; |
|||
import com.canvas.web.modules.system.service.dto.MenuQueryCriteria; |
|||
import com.canvas.web.modules.system.service.dto.MenuSmallDto; |
|||
import com.canvas.web.modules.system.service.mapstruct.MenuMapper; |
|||
import com.canvas.web.modules.system.service.mapstruct.MenuSmallMapper; |
|||
import com.canvas.web.utils.QueryHelp; |
|||
import com.canvas.web.utils.RedisUtils; |
|||
import com.canvas.web.utils.StringUtils; |
|||
import com.canvas.web.utils.ValidationUtil; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.cache.annotation.CacheConfig; |
|||
import org.springframework.cache.annotation.Cacheable; |
|||
import org.springframework.data.domain.Sort; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Set; |
|||
import java.util.stream.Collectors; |
|||
|
|||
|
|||
@Service |
|||
@RequiredArgsConstructor |
|||
@CacheConfig(cacheNames = "menu") |
|||
public class MenuServiceImpl implements MenuService { |
|||
|
|||
private final MenuRepository menuRepository; |
|||
private final MenuSmallMapper menuSmallMapper; |
|||
private final UserRepository userRepository; |
|||
private final MenuMapper menuMapper; |
|||
private final RoleService roleService; |
|||
private final RedisUtils redisUtils; |
|||
|
|||
@Override |
|||
@Cacheable(key = "'id:'+#p0") |
|||
public MenuDto findById(long id) { |
|||
Menu menu = menuRepository.findById(id).orElseGet(Menu::new); |
|||
ValidationUtil.isNull(menu.getId(), "Menu", "id", id); |
|||
return menuMapper.toDto(menu); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void create(Menu resources) { |
|||
if (menuRepository.findByTitle(resources.getTitle()) != null) { |
|||
throw new BaseException("菜单实体存在异常", ResponseEnum.MENU_ADD_ERROR_EXIST.getMessage()); |
|||
} |
|||
if (StringUtils.isNotBlank(resources.getComponentName())) { |
|||
if (menuRepository.findByComponentName(resources.getComponentName()) != null) { |
|||
throw new BaseException("菜单组件名称存在异常", ResponseEnum.ERROR.getMessage()); |
|||
} |
|||
} |
|||
if (resources.getPid().equals(0L)) { |
|||
resources.setPid(null); |
|||
} |
|||
if (resources.getIFrame()) { |
|||
String http = "http://", https = "https://"; |
|||
if (!resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https)); |
|||
throw new BaseException("外链必须以://或者https://"); |
|||
} |
|||
menuRepository.save(resources); |
|||
resources.setSubCount(0); |
|||
updateSubCnt(resources.getId()); |
|||
} |
|||
|
|||
public void updateSubCnt(Long menuId){ |
|||
if (menuId!=null){ |
|||
int count=menuRepository.countByPid(menuId); |
|||
menuRepository.updateSubCntById(count,menuId); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void update(Menu resources) { |
|||
if(resources.getId().equals(resources.getPid())) { |
|||
throw new BaseException("上级不能为自己"); |
|||
} |
|||
Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new); |
|||
ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId()); |
|||
|
|||
if(resources.getIFrame()){ |
|||
String http = "http://", https = "https://"; |
|||
if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) { |
|||
throw new BaseException("外链必须以http://或者https://开头"); |
|||
} |
|||
} |
|||
Menu menu1 = menuRepository.findByTitle(resources.getTitle()); |
|||
|
|||
if(menu1 != null && !menu1.getId().equals(menu.getId())){ |
|||
throw new BaseException("title",resources.getTitle()); |
|||
} |
|||
|
|||
if(resources.getPid().equals(0L)){ |
|||
resources.setPid(null); |
|||
} |
|||
|
|||
// 记录的父节点ID |
|||
Long oldPid = menu.getPid(); |
|||
Long newPid = resources.getPid(); |
|||
|
|||
if(StringUtils.isNotBlank(resources.getComponentName())){ |
|||
menu1 = menuRepository.findByComponentName(resources.getComponentName()); |
|||
if(menu1 != null && !menu1.getId().equals(menu.getId())){ |
|||
throw new BaseException("componentName",resources.getComponentName()); |
|||
} |
|||
} |
|||
menu.setTitle(resources.getTitle()); |
|||
menu.setComponent(resources.getComponent()); |
|||
menu.setPath(resources.getPath()); |
|||
menu.setIcon(resources.getIcon()); |
|||
menu.setIFrame(resources.getIFrame()); |
|||
menu.setPid(resources.getPid()); |
|||
menu.setMenuSort(resources.getMenuSort()); |
|||
menu.setCache(resources.getCache()); |
|||
menu.setHidden(resources.getHidden()); |
|||
menu.setComponentName(resources.getComponentName()); |
|||
menu.setPermission(resources.getPermission()); |
|||
menu.setType(resources.getType()); |
|||
menuRepository.save(menu); |
|||
// 计算父级菜单节点数目 |
|||
updateSubCnt(oldPid); |
|||
updateSubCnt(newPid); |
|||
// 清理缓存 |
|||
delCaches(resources.getId()); |
|||
} |
|||
|
|||
public void delCaches(Long id){ |
|||
List<User> users=userRepository.findByMenuId(id); |
|||
redisUtils.del("menu::id:"+id); |
|||
redisUtils.delByKeys("menu::user:",users.stream().map(User::getId).collect(Collectors.toSet())); |
|||
// 清除 Role 缓存 |
|||
List<Role> roles = roleService.findInMenuId(new ArrayList<Long>(){{ |
|||
add(id); |
|||
}}); |
|||
redisUtils.delByKeys("role::id:",roles.stream().map(Role::getId).collect(Collectors.toSet())); |
|||
} |
|||
|
|||
@Override |
|||
public Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet) { |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public List<MenuDto> buildTree(List<MenuDto> menuDtos) { |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public Menu findOne(Long id) { |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public void delete(Set<Menu> menuSet) { |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public List<MenuDto> getMenus(Long pid) { |
|||
List<Menu> menus; |
|||
if (pid!=null && pid.equals(0L)){ |
|||
menus=menuRepository.findByPid(pid); |
|||
}else { |
|||
menus = menuRepository.findByPidIsNull(); |
|||
} |
|||
return menuMapper.toDto(menus); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
@Override |
|||
public List<MenuDto> findByUser(Long currentUserId) { |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public List<MenuDto> queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception { |
|||
Sort sort= Sort.by(Sort.Direction.ASC,"menuSort"); |
|||
if (Boolean.TRUE.equals(isQuery)){ |
|||
criteria.setPidIsNull(true); |
|||
List<Field> fields= QueryHelp.getAllFields(criteria.getClass(),new ArrayList<>()); |
|||
for (Field field:fields){ |
|||
field.setAccessible(true); |
|||
Object val = field.get(criteria); |
|||
if("pidIsNull".equals(field.getName())){ |
|||
continue; |
|||
} |
|||
if (ObjectUtil.isNotNull(val)) { |
|||
criteria.setPidIsNull(null); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
return menuMapper.toDto(menuRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort)); |
|||
} |
|||
|
|||
//新增权限获取下拉列表菜单 |
|||
@Override |
|||
public List<MenuSmallDto> queryAll() { |
|||
return menuSmallMapper.toDto(menuRepository.findDropDownList()); |
|||
} |
|||
} |
@ -0,0 +1,12 @@ |
|||
package com.canvas.web.modules.system.service.mapstruct; |
|||
|
|||
|
|||
import com.canvas.web.base.BaseMapper; |
|||
import com.canvas.web.modules.system.domain.Menu; |
|||
import com.canvas.web.modules.system.service.dto.MenuSmallDto; |
|||
import org.mapstruct.Mapper; |
|||
import org.mapstruct.ReportingPolicy; |
|||
|
|||
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) |
|||
public interface MenuSmallMapper extends BaseMapper<MenuSmallDto, Menu> { |
|||
} |
@ -1,9 +1,12 @@ |
|||
package com.canvas.web.modules.system.service.mapstruct; |
|||
|
|||
|
|||
import com.canvas.web.base.BaseMapper; |
|||
import com.canvas.web.modules.system.domain.Role; |
|||
import com.canvas.web.modules.system.service.dto.RoleDto; |
|||
import org.mapstruct.Mapper; |
|||
import org.mapstruct.ReportingPolicy; |
|||
|
|||
@Mapper(componentModel = "spring", uses = {MenuMapper.class, OrgMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE) |
|||
public interface RoleMapper { |
|||
public interface RoleMapper extends BaseMapper<RoleDto, Role> { |
|||
} |
@ -0,0 +1,11 @@ |
|||
package com.canvas.web.modules.system.service.mapstruct; |
|||
|
|||
import com.canvas.web.base.BaseMapper; |
|||
import com.canvas.web.modules.system.domain.Role; |
|||
import com.canvas.web.modules.system.service.dto.RoleSmallDto; |
|||
import org.mapstruct.Mapper; |
|||
import org.mapstruct.ReportingPolicy; |
|||
|
|||
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) |
|||
public interface RoleSmallMapper extends BaseMapper<RoleSmallDto, Role> { |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue