Browse Source

User 使用 @OneToOne 映射 Role, User 有且只能有一个 Role

reghao 1 year ago
parent
commit
e69f925ca4

+ 4 - 2
web/src/main/java/cn/reghao/devops/web/admin/account/controller/HomeController.java

@@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * @author reghao
@@ -55,13 +56,14 @@ public class HomeController {
             throw new Exception("未登录");
         }
 
-        boolean isAdmin = user.getRole().contains(RoleType.ROLE_ADMIN.name());
+        boolean isAdmin = user.getRole().getName().equals(RoleType.ROLE_ADMIN.name());
         if (isAdmin) {
             String unreadMessage = sysMessageService.getUnreadCount();
             model.addAttribute("unreadMessage", unreadMessage);
         }
 
-        List<Menu> menus = homeService.userMenus(user.getRole());
+        // TODO 此处直接传入 Role 对象, 然后调用 Role#getMenus 会抛出 LazyInitializationException 异常
+        List<Menu> menus = homeService.userMenus(Set.of(user.getRole().getName()));
         Map<Integer, Menu> treeMenu = homeService.treeMenu(menus);
         model.addAttribute("user", user);
         model.addAttribute("treeMenu", treeMenu);

+ 6 - 0
web/src/main/java/cn/reghao/devops/web/admin/account/db/repository/UserRepository.java

@@ -1,13 +1,19 @@
 package cn.reghao.devops.web.admin.account.db.repository;
 
 import cn.reghao.devops.web.admin.account.model.po.User;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2019-08-29 10:52:14
  */
 public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
     User findByUsername(String username);
+    int countByRole_id(int id);
+    Page<User> findAllByRole_id(int id, Pageable pageable);
 }

+ 1 - 1
web/src/main/java/cn/reghao/devops/web/admin/account/model/po/Role.java

@@ -30,7 +30,7 @@ public class Role extends BaseEntity {
     @Length(max = 100, message = "角色描述的长度不超过 100 个中文字符")
     private String description;
     // Role 端维护 Role 和 Menu 之间的关系
-    @ManyToMany
+    @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(name = "sys_role_menu",
             joinColumns = @JoinColumn(name = "role_id"),
             inverseJoinColumns = @JoinColumn(name = "menu_id"))

+ 9 - 5
web/src/main/java/cn/reghao/devops/web/admin/account/model/po/User.java

@@ -37,9 +37,11 @@ public class User extends BaseEntity implements UserDetails {
     private String salt;
     private LocalDateTime createAt;
 
-    @ElementCollection(fetch = FetchType.EAGER)
+    /*@ElementCollection(fetch = FetchType.EAGER)
     @CollectionTable(name = "sys_user_role")
-    private Set<String> role;
+    private Set<String> role;*/
+    @OneToOne
+    private Role role;
     private Boolean enabled = true;
     private Boolean locked = false;
 
@@ -50,12 +52,12 @@ public class User extends BaseEntity implements UserDetails {
     private String email;
     private Integer gender;
 
-    public User(String username, String encodedPassword, String salt, Set<String> roles) {
+    public User(String username, String encodedPassword, String salt, Role role) {
         this.username = username;
         this.encodedPassword = encodedPassword;
         this.salt = salt;
         this.createAt = LocalDateTime.now();
-        this.role = roles;
+        this.role = role;
         this.enabled = true;
         this.locked = false;
         this.screenName = username;
@@ -130,6 +132,8 @@ public class User extends BaseEntity implements UserDetails {
      */
     @Override
     public Collection<? extends GrantedAuthority> getAuthorities() {
-        return role.stream().map(UserAuthority::new).collect(Collectors.toSet());
+        //return role.stream().map(UserAuthority::new).collect(Collectors.toSet());
+        UserAuthority userAuthority = new UserAuthority(role.getName());
+        return Set.of(userAuthority);
     }
 }

+ 11 - 0
web/src/main/java/cn/reghao/devops/web/admin/account/model/vo/RoleVO.java

@@ -17,6 +17,7 @@ public class RoleVO {
     private String description;
     private String createTime;
     private String updateTime;
+    private int total;
 
     public RoleVO(Role role) {
         this.id = role.getId();
@@ -24,5 +25,15 @@ public class RoleVO {
         this.description = role.getDescription();
         this.createTime = DateTimeConverter.format(role.getCreateTime());
         this.updateTime = DateTimeConverter.format(role.getUpdateTime());
+        this.total = 0;
+    }
+
+    public RoleVO(Role role, int total) {
+        this.id = role.getId();
+        this.name = role.getName().split("ROLE_")[1].toLowerCase(Locale.ROOT);
+        this.description = role.getDescription();
+        this.createTime = DateTimeConverter.format(role.getCreateTime());
+        this.updateTime = DateTimeConverter.format(role.getUpdateTime());
+        this.total = total;
     }
 }

+ 4 - 4
web/src/main/java/cn/reghao/devops/web/admin/account/service/UserContext.java

@@ -43,19 +43,19 @@ public class UserContext {
 
     public static String getUserRole() {
         User user = getUser();
-        if (user != null && !user.getRole().isEmpty()) {
-            return user.getRole().iterator().next();
+        if (user != null) {
+            return user.getRole().getName();
         }
 
         return "";
     }
 
-    public static Set<String> getUserRoles() {
+    /*public static Set<String> getUserRoles() {
         User user = getUser();
         if (user != null) {
             return user.getRole();
         }
 
         return Collections.emptySet();
-    }
+    }*/
 }

+ 2 - 3
web/src/main/java/cn/reghao/devops/web/admin/account/service/impl/AccountServiceImpl.java

@@ -64,7 +64,7 @@ public class AccountServiceImpl implements AccountService {
             String password = createAccountDto.getPassword();
             String salt = RandomString.getSalt(64);
             String encodedPassword = passwordEncoder.encode(password + salt);
-            user = new User(username, encodedPassword, salt, Set.of(role.getName()));
+            user = new User(username, encodedPassword, salt, role);
             userRepository.save(user);
             return Result.success();
         }
@@ -119,8 +119,7 @@ public class AccountServiceImpl implements AccountService {
             return Result.fail("只有 admin 用户才能拥有 admin role");
         }
 
-        userEntity.getRole().clear();
-        userEntity.getRole().add(role.getName());
+        userEntity.setRole(role);
         userRepository.save(userEntity);
         accountSessionService.deactiveSession(userEntity);
         return Result.success();

+ 7 - 3
web/src/main/java/cn/reghao/devops/web/admin/account/service/impl/RoleServiceImpl.java

@@ -96,8 +96,12 @@ public class RoleServiceImpl implements RoleService {
             rolePage = roleRepository.findAll(pageRequest);
         }
 
-        List<RoleVO> list = rolePage.getContent().stream().map(RoleVO::new).collect(Collectors.toList());
-        return new PageImpl<>(list, pageRequest, rolePage.getTotalElements());
+        return rolePage.map(role -> {
+            int total = userRepository.countByRole_id(role.getId());
+            return new RoleVO(role, total);
+        });
+        /*List<RoleVO> list = rolePage.getContent().stream().map(RoleVO::new).collect(Collectors.toList());
+        return new PageImpl<>(list, pageRequest, rolePage.getTotalElements());*/
     }
 
     @Override
@@ -142,7 +146,7 @@ public class RoleServiceImpl implements RoleService {
         });
 
         PageRequest pageRequest = PageRequest.of(0, 100);
-        Page<User> page = userRepository.findAll(specification, pageRequest);
+        Page<User> page = userRepository.findAllByRole_id(roleId, pageRequest);
         return page.getContent();
     }
 

+ 3 - 2
web/src/main/java/cn/reghao/devops/web/mgr/app/service/PermissionCheck.java

@@ -1,5 +1,6 @@
 package cn.reghao.devops.web.mgr.app.service;
 
+import cn.reghao.devops.web.admin.account.model.po.Role;
 import cn.reghao.devops.web.mgr.build.model.constant.EnvType;
 import cn.reghao.devops.web.admin.account.model.constant.RoleType;
 import cn.reghao.devops.web.admin.account.model.po.User;
@@ -17,8 +18,8 @@ public class PermissionCheck {
         if (user == null) {
             throw new Exception("未登录");
         } else {
-            Set<String> roles = user.getRole();
-            boolean isAdmin = roles.contains(RoleType.ROLE_ADMIN.name());
+            Role role = user.getRole();
+            boolean isAdmin = role.getName().equals(RoleType.ROLE_ADMIN.name());
             if (EnvType.prod.name().equals(env) && !isAdmin) {
                 throw new Exception("没有权限");
             }

+ 5 - 5
web/src/main/java/cn/reghao/devops/web/util/DefaultSetting.java

@@ -24,13 +24,13 @@ public class DefaultSetting {
     }
 
     public static String getDefaultAppType() {
-        String defaultAppType = AppType.java.getName();
-        Set<String> roles = UserContext.getUserRoles();
-        if (roles.contains(RoleType.ROLE_JAVA.name())) {
+        String defaultAppType = AppType.dotnet.getName();
+        String role = UserContext.getUserRole();
+        if (role.equals(RoleType.ROLE_JAVA.name())) {
             defaultAppType = AppType.java.getName();
-        } else if (roles.contains(RoleType.ROLE_DOTNET.name())) {
+        } else if (role.equals(RoleType.ROLE_DOTNET.name())) {
             defaultAppType = AppType.dotnet.getName();
-        } else if (roles.contains(RoleType.ROLE_NPM.name())) {
+        } else if (role.equals(RoleType.ROLE_NPM.name())) {
             defaultAppType = AppType.npm.getName();
         }
 

+ 1 - 0
web/src/main/resources/templates/admin/role/index.html

@@ -49,6 +49,7 @@
                     <td th:text="${item.description}">描述</td>
                     <td th:text="${item.createTime}">创建时间</td>
                     <td>
+                        <span style="color: red" th:text="${item.total}"></span>
                         <a class="open-popup" th:attr="data-title=@{'拥有 ' + ${item.name} + ' 角色的用户'},
                         data-url=@{'/rbac/role/users/'+${item.id}}" data-size="640,480" href="#">查看</a>
                     </td>