fix(菜单模块): 优化菜单模块

This commit is contained in:
vertoryao 2024-12-25 16:54:13 +08:00
parent b6c72c9b90
commit 3772c2d33b
7 changed files with 57 additions and 55 deletions

View File

@ -1,9 +1,11 @@
package com.zsc.edu.gateway.framework.security; package com.zsc.edu.gateway.framework.security;
import com.zsc.edu.gateway.exception.StateException; import com.zsc.edu.gateway.exception.StateException;
import com.zsc.edu.gateway.modules.system.entity.Menu;
import com.zsc.edu.gateway.modules.system.entity.RoleAuthority; import com.zsc.edu.gateway.modules.system.entity.RoleAuthority;
import com.zsc.edu.gateway.modules.system.entity.User; import com.zsc.edu.gateway.modules.system.entity.User;
import com.zsc.edu.gateway.modules.system.repo.AuthorityRepository; import com.zsc.edu.gateway.modules.system.repo.AuthorityRepository;
import com.zsc.edu.gateway.modules.system.repo.MenuRepository;
import com.zsc.edu.gateway.modules.system.repo.RoleAuthoritiesRepository; import com.zsc.edu.gateway.modules.system.repo.RoleAuthoritiesRepository;
import com.zsc.edu.gateway.modules.system.repo.UserRepository; import com.zsc.edu.gateway.modules.system.repo.UserRepository;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -14,6 +16,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author harry_yao * @author harry_yao
@ -23,8 +27,9 @@ import java.util.List;
public class JpaUserDetailsServiceImpl implements UserDetailsService { public class JpaUserDetailsServiceImpl implements UserDetailsService {
private final UserRepository userRepo; private final UserRepository userRepo;
private final RoleAuthoritiesRepository roleAuthoritiesRepository; // private final RoleAuthoritiesRepository roleAuthoritiesRepository;
private final AuthorityRepository authorityRepository; private final AuthorityRepository authorityRepository;
private final MenuRepository menuRepository;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -34,19 +39,10 @@ public class JpaUserDetailsServiceImpl implements UserDetailsService {
throw new StateException("用户 '" + username + "' 已被禁用!请联系管理员"); throw new StateException("用户 '" + username + "' 已被禁用!请联系管理员");
} }
List<RoleAuthority> roleAuthorities= roleAuthoritiesRepository.selectByRoleId(user.getRoleId()); // List<RoleAuthority> roleAuthorities= roleAuthoritiesRepository.selectByRoleId(user.getRoleId());
user.role.authorities = authorityRepository.selectAuthoritiesByRoleId(user.getRoleId()); user.role.authorities = authorityRepository.selectAuthoritiesByRoleId(user.getRoleId());
// =roleAuthorities.stream() List<Menu> menus = menuRepository.selectByRoleId(user.getRoleId());
// .map(i -> Authority.valueOf(i.getAuthority())) Set<String> permissions = menus.stream().map(Menu::getPermissions).collect(Collectors.toSet());
// .collect(Collectors.toSet()); return UserDetailsImpl.from(user, permissions);
// .orElseThrow(() ->
// new UsernameNotFoundException("用户 '" + username + "' 不存在!")
// );
// user.getIdentities().stream().filter(identity -> identity.role.enableState == EnableState.启用)
// .forEach(identity -> Hibernate.initialize(identity.role.roleAuthorities));
return UserDetailsImpl.from(user);
} }
} }

View File

@ -1,7 +1,6 @@
package com.zsc.edu.gateway.framework.security; package com.zsc.edu.gateway.framework.security;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.zsc.edu.gateway.common.enums.EnableState;
import com.zsc.edu.gateway.modules.system.entity.Authority; import com.zsc.edu.gateway.modules.system.entity.Authority;
import com.zsc.edu.gateway.modules.system.entity.Dept; import com.zsc.edu.gateway.modules.system.entity.Dept;
import com.zsc.edu.gateway.modules.system.entity.Role; import com.zsc.edu.gateway.modules.system.entity.Role;
@ -34,8 +33,9 @@ public class UserDetailsImpl implements UserDetails {
public Dept dept; public Dept dept;
public Role role; public Role role;
public Set<Authority> authorities; public Set<Authority> authorities;
public Set<String> permissions;
public UserDetailsImpl(Long id, String username, String password, String name, Boolean enableState, Dept dept, Role role, Set<Authority> authorities) { public UserDetailsImpl(Long id, String username, String password, String name, Boolean enableState, Dept dept, Role role, Set<Authority> authorities, Set<String> permissions) {
this.id = id; this.id = id;
this.username = username; this.username = username;
this.password = password; this.password = password;
@ -44,9 +44,10 @@ public class UserDetailsImpl implements UserDetails {
this.dept = dept; this.dept = dept;
this.role = role; this.role = role;
this.authorities = authorities; this.authorities = authorities;
this.permissions = permissions;
} }
public static UserDetailsImpl from(User user) { public static UserDetailsImpl from(User user, Set<String> permissions) {
return new UserDetailsImpl( return new UserDetailsImpl(
user.id, user.id,
user.username, user.username,
@ -55,13 +56,15 @@ public class UserDetailsImpl implements UserDetails {
user.enableState, user.enableState,
user.dept, user.dept,
user.role, user.role,
user.role.authorities user.role.authorities,
permissions
); );
} }
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities.stream().map(authority -> new SimpleGrantedAuthority(authority.getName())).collect(Collectors.toSet()); // return authorities.stream().map(authority -> new SimpleGrantedAuthority(authority.getName())).collect(Collectors.toSet());
return permissions.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet());
} }
@Override @Override

View File

@ -22,49 +22,49 @@ public class AuthorityController {
private AuthorityService service; private AuthorityService service;
/** /**
* 返回权限列表 hasAuthority('AUTHORITY_QUERY') * 返回权限列表 hasAuthority('SYSTEM:AUTHORITY:QUERY')
* *
* @param query 查询表单 * @param query 查询表单
* @return 权限列表 * @return 权限列表
*/ */
@GetMapping @GetMapping
@PreAuthorize("hasAuthority('AUTHORITY_QUERY')") @PreAuthorize("hasAuthority('SYSTEM:AUTHORITY:QUERY')")
public Page<Authority> query(AuthorityQuery query, Page<Authority> page) { public Page<Authority> query(AuthorityQuery query, Page<Authority> page) {
return service.page(page, query.wrapper()); return service.page(page, query.wrapper());
} }
/** /**
* 新建权限 hasAuthority('AUTHORITY_CREATE') * 新建权限 hasAuthority('SYSTEM:AUTHORITY:CREATE')
* *
* @param dto 表单数据 * @param dto 表单数据
* @return Authority 新建的权限 * @return Authority 新建的权限
*/ */
@PostMapping @PostMapping
@PreAuthorize("hasAuthority('AUTHORITY_CREATE')") @PreAuthorize("hasAuthority('SYSTEM:AUTHORITY:CREATE')")
public Authority create(@RequestBody AuthorityDto dto) { public Authority create(@RequestBody AuthorityDto dto) {
return service.create(dto); return service.create(dto);
} }
/** /**
* 更新权限 hasAuthority('AUTHORITY_UPDATE') * 更新权限 hasAuthority('SYSTEM:AUTHORITY:UPDATE')
* *
* @param dto 表单数据 * @param dto 表单数据
* @param id 权限ID * @param id 权限ID
* @return Dept 更新后的权限信息 * @return Dept 更新后的权限信息
*/ */
@PatchMapping("/{id}") @PatchMapping("/{id}")
@PreAuthorize("hasAuthority('AUTHORITY_UPDATE')") @PreAuthorize("hasAuthority('SYSTEM:AUTHORITY:UPDATE')")
public Boolean update(@RequestBody AuthorityDto dto, @PathVariable("id") Long id) { public Boolean update(@RequestBody AuthorityDto dto, @PathVariable("id") Long id) {
return service.update(dto, id); return service.update(dto, id);
} }
/*** /***
* 删除权限 hasAuthority('AUTHORITY_DELETE') * 删除权限 hasAuthority('SYSTEM:AUTHORITY:DELETE')
* @param id 权限ID * @param id 权限ID
* @return Boolean 是否删除成功 * @return Boolean 是否删除成功
*/ */
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
@PreAuthorize("hasAuthority('AUTHORITY_DELETE')") @PreAuthorize("hasAuthority('SYSTEM:AUTHORITY:DELETE')")
public Boolean delete(@PathVariable("id") Long id) { public Boolean delete(@PathVariable("id") Long id) {
return service.removeById(id); return service.removeById(id);
} }
@ -72,7 +72,7 @@ public class AuthorityController {
* 更新权限启用状态 * 更新权限启用状态
* */ * */
@PatchMapping("/toggle/{id}") @PatchMapping("/toggle/{id}")
@PreAuthorize("hasAuthority('AUTHORITY_TOGGLE')") @PreAuthorize("hasAuthority('SYSTEM:AUTHORITY:TOGGLE')")
public Boolean toggle(@PathVariable("id") Long id) { public Boolean toggle(@PathVariable("id") Long id) {
return service.toggle(id); return service.toggle(id);
} }

View File

@ -27,61 +27,61 @@ public class DeptController {
private final UserService userService; private final UserService userService;
/** /**
* 返回管理部门列表 hasAuthority('DEPT_QUERY') * 返回管理部门列表 hasAuthority('SYSTEM:DEPT:QUERY')
* *
* @param query 查询表单 * @param query 查询表单
* @return 部门列表 * @return 部门列表
*/ */
@GetMapping @GetMapping
@PreAuthorize("hasAuthority('DEPT_QUERY')") @PreAuthorize("hasAuthority('SYSTEM:DEPT:QUERY')")
public Page<Dept> query(DeptQuery query, Page<Dept> page) { public Page<Dept> query(DeptQuery query, Page<Dept> page) {
return service.page(page, query.wrapper()); return service.page(page, query.wrapper());
} }
/** /**
* 返回管理部门列表 hasAuthority('DEPT_QUERY') * 返回管理部门列表 hasAuthority('SYSTEM:DEPT:QUERY')
* *
* @param id 指定部门id * @param id 指定部门id
* @return 部门列表 * @return 部门列表
*/ */
@GetMapping("/tree") @GetMapping("/tree")
@PreAuthorize("hasAuthority('DEPT_QUERY')") @PreAuthorize("hasAuthority('SYSTEM:DEPT:QUERY')")
public Dept tree(@RequestParam Long id) { public Dept tree(@RequestParam Long id) {
return service.listTree(id); return service.listTree(id);
} }
/** /**
* 新建管理部门 hasAuthority('DEPT_CREATE') * 新建管理部门 hasAuthority('SYSTEM:DEPT:CREATE')
* *
* @param dto 表单数据 * @param dto 表单数据
* @return Dept 新建的管理部门 * @return Dept 新建的管理部门
*/ */
@PostMapping @PostMapping
@PreAuthorize("hasAuthority('DEPT_CREATE')") @PreAuthorize("hasAuthority('SYSTEM:DEPT:CREATE')")
public Dept create(@RequestBody DeptDto dto) { public Dept create(@RequestBody DeptDto dto) {
return service.create(dto); return service.create(dto);
} }
/** /**
* 更新管理部门 hasAuthority('DEPT_UPDATE') * 更新管理部门 hasAuthority('SYSTEM:DEPT:UPDATE')
* *
* @param dto 表单数据 * @param dto 表单数据
* @param id 部门ID * @param id 部门ID
* @return Dept 更新后的部门 * @return Dept 更新后的部门
*/ */
@PatchMapping("/{id}") @PatchMapping("/{id}")
@PreAuthorize("hasAuthority('DEPT_UPDATE')") @PreAuthorize("hasAuthority('SYSTEM:DEPT:UPDATE')")
public Boolean update(@RequestBody DeptDto dto, @PathVariable("id") Long id) { public Boolean update(@RequestBody DeptDto dto, @PathVariable("id") Long id) {
return service.edit(dto, id); return service.edit(dto, id);
} }
/*** /***
* 删除管理部门 hasAuthority('DEPT_DELETE') * 删除管理部门 hasAuthority('SYSTEM:DEPT:DELETE')
* @param id 部门ID * @param id 部门ID
* @return Boolean 是否删除成功 * @return Boolean 是否删除成功
*/ */
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
@PreAuthorize("hasAuthority('DEPT_DELETE')") @PreAuthorize("hasAuthority('SYSTEM:DEPT:DELETE')")
public Boolean delete(@PathVariable("id") Long id) { public Boolean delete(@PathVariable("id") Long id) {
// 是否存在用户绑定此部门 // 是否存在用户绑定此部门
boolean hasUser = userService.count(new LambdaQueryWrapper<User>().eq(User::getDeptId, id)) > 0; boolean hasUser = userService.count(new LambdaQueryWrapper<User>().eq(User::getDeptId, id)) > 0;
@ -95,7 +95,7 @@ public class DeptController {
* 更新管理部门状态 * 更新管理部门状态
* */ * */
@PatchMapping("/toggle/{id}") @PatchMapping("/toggle/{id}")
@PreAuthorize("hasAuthority('DEPT_TOGGLE')") @PreAuthorize("hasAuthority('SYSTEM:DEPT:TOGGLE')")
public Boolean toggle(@PathVariable("id") Long id) { public Boolean toggle(@PathVariable("id") Long id) {
return service.toggle(id); return service.toggle(id);
} }

View File

@ -31,38 +31,38 @@ public class RoleController {
private final RoleAuthService roleAuthService; private final RoleAuthService roleAuthService;
/** /**
* 返回所有角色列表 hasAuthority('ROLE_QUERY') * 返回所有角色列表 hasAuthority('SYSTEM:ROLE:QUERY')
* *
* @return 所有角色列表 * @return 所有角色列表
*/ */
@GetMapping @GetMapping
@PreAuthorize("hasAuthority('ROLE_QUERY')") @PreAuthorize("hasAuthority('SYSTEM:ROLE:QUERY')")
public Page<Role> query(RoleQuery query, Page<Role> page) { public Page<Role> query(RoleQuery query, Page<Role> page) {
return service.page(page, query.wrapper()); return service.page(page, query.wrapper());
} }
/** /**
* 新建角色 hasAuthority('ROLE_CREATE') * 新建角色 hasAuthority('SYSTEM:ROLE:CREATE')
* *
* @param dto 表单数据 * @param dto 表单数据
* @return Role 新建的角色 * @return Role 新建的角色
*/ */
@PostMapping @PostMapping
@PreAuthorize("hasAuthority('ROLE_CREATE')") @PreAuthorize("hasAuthority('SYSTEM:ROLE:CREATE')")
public Boolean create(@RequestBody RoleDto dto) { public Boolean create(@RequestBody RoleDto dto) {
Role role= service.create(dto); Role role= service.create(dto);
return role != null; return role != null;
} }
/** /**
* 更新角色 hasAuthority('ROLE_UPDATE') * 更新角色 hasAuthority('SYSTEM:ROLE:UPDATE')
* *
* @param dto 表单数据 * @param dto 表单数据
* @param id ID * @param id ID
* @return Role 更新后的角色 * @return Role 更新后的角色
*/ */
@PatchMapping("{id}") @PatchMapping("{id}")
@PreAuthorize("hasAuthority('ROLE_UPDATE')") @PreAuthorize("hasAuthority('SYSTEM:ROLE:UPDATE')")
public Boolean update(@RequestBody RoleDto dto, @PathVariable("id") Long id) { public Boolean update(@RequestBody RoleDto dto, @PathVariable("id") Long id) {
// Role role = roleMapper.toEntity(dto); // Role role = roleMapper.toEntity(dto);
// role.setId(id); // role.setId(id);
@ -70,48 +70,48 @@ public class RoleController {
} }
/** /**
* 切换角色"启动/禁用"状态 hasAuthority('ROLE_UPDATE') * 切换角色"启动/禁用"状态 hasAuthority('SYSTEM:ROLE:UPDATE')
* *
* @param id ID * @param id ID
* @return Role 更新后的角色 * @return Role 更新后的角色
*/ */
@PatchMapping("{id}/toggle") @PatchMapping("{id}/toggle")
@PreAuthorize("hasAuthority('ROLE_UPDATE')") @PreAuthorize("hasAuthority('SYSTEM:ROLE:UPDATE')")
public Boolean toggle(@PathVariable("id") Long id) { public Boolean toggle(@PathVariable("id") Long id) {
return service.toggle(id); return service.toggle(id);
} }
/** /**
* 查询角色详情 hasAuthority('ROLE_QUERY') * 查询角色详情 hasAuthority('SYSTEM:ROLE:QUERY')
* *
* @param id ID * @param id ID
* @return Role 角色详情 * @return Role 角色详情
*/ */
@GetMapping("{id}") @GetMapping("{id}")
@PreAuthorize("hasAuthority('ROLE_QUERY')") @PreAuthorize("hasAuthority('SYSTEM:ROLE:QUERY')")
public RoleVo detail(@PathVariable Long id) { public RoleVo detail(@PathVariable Long id) {
return service.detail(id); return service.detail(id);
} }
/** /**
* 删除角色 hasAuthority('ROLE_DELETE') * 删除角色 hasAuthority('SYSTEM:ROLE:DELETE')
* *
* @param id ID * @param id ID
* @return Role 更新后的角色 * @return Role 更新后的角色
*/ */
@DeleteMapping("{id}") @DeleteMapping("{id}")
@PreAuthorize("hasAuthority('ROLE_DELETE')") @PreAuthorize("hasAuthority('SYSTEM:ROLE:DELETE')")
public Boolean delete(@PathVariable Long id) { public Boolean delete(@PathVariable Long id) {
return service.delete(id); return service.delete(id);
} }
/** /**
* 为角色添加权限 hasAuthority('ROLE_AUTHED') * 为角色添加权限 hasAuthority('SYSTEM:ROLE:AUTHED')
* *
* @return RoleAuthority 新的角色权限 * @return RoleAuthority 新的角色权限
*/ */
@PostMapping("/saveAuth/{id}") @PostMapping("/saveAuth/{id}")
@PreAuthorize("hasAuthority('ROLE_AUTHED')") @PreAuthorize("hasAuthority('SYSTEM:ROLE:AUTHED')")
public Boolean addAuthed(@PathVariable Long id, @RequestBody Set<AuthorityCreateDto> authorities) { public Boolean addAuthed(@PathVariable Long id, @RequestBody Set<AuthorityCreateDto> authorities) {
return service.saveRoleAuths(id,authorities); return service.saveRoleAuths(id,authorities);
} }

View File

@ -19,6 +19,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.Set;
/** /**
* @author pengzheng * @author pengzheng
*/ */
@ -80,7 +82,7 @@ abstract public class BaseServiceTest {
.password(passwordEncoder.encode("user1")) .password(passwordEncoder.encode("user1"))
.build(); .build();
userRepo.insert(user2); userRepo.insert(user2);
userDetails = UserDetailsImpl.from(user1); userDetails = UserDetailsImpl.from(user1, Set.of());
dataInit = true; dataInit = true;
deptRepoStatic = deptRepo; deptRepoStatic = deptRepo;

View File

@ -23,6 +23,7 @@ import org.springframework.test.web.servlet.MockMvc;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
/** /**
* @author pengzheng * @author pengzheng
@ -60,6 +61,6 @@ abstract public class MockMvcConfigBase {
Role role = RoleBuilder.aRole().authorities(new HashSet<>()).build(); Role role = RoleBuilder.aRole().authorities(new HashSet<>()).build();
// Role role = RoleBuilder.aRole().authorities(new HashSet<>(Arrays.asList(Authority))).build(); // Role role = RoleBuilder.aRole().authorities(new HashSet<>(Arrays.asList(Authority))).build();
user = UserBuilder.anUser().username("admin").dept(dept).role(role).build(); user = UserBuilder.anUser().username("admin").dept(dept).role(role).build();
userDetails = UserDetailsImpl.from(user); userDetails = UserDetailsImpl.from(user, Set.of());
} }
} }