Browse Source

优化登录页和主页代码

reghao 4 years ago
parent
commit
1cbd57c99c

+ 6 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/config/UserDetailsServiceImpl.java

@@ -2,6 +2,7 @@ package cn.reghao.autodop.dmaster.auth.config;
 
 import cn.reghao.autodop.dmaster.auth.model.po.User;
 import cn.reghao.autodop.dmaster.auth.db.repository.UserRepository;
+import cn.reghao.autodop.dmaster.auth.service.UserService;
 import org.springframework.security.authentication.DisabledException;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
@@ -16,15 +17,18 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class UserDetailsServiceImpl implements UserDetailsService {
+    private UserService userService;
     private final UserRepository userRepository;
 
-    public UserDetailsServiceImpl(UserRepository userRepository) {
+    public UserDetailsServiceImpl(UserService userService, UserRepository userRepository) {
+        this.userService = userService;
         this.userRepository = userRepository;
     }
 
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-        User user = userRepository.findByUsername(username);
+        //User user = userRepository.findByUsername(username);
+        User user = userService.getUser(username);
         if (user != null) {
             return user;
         } else {

+ 3 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/controller/UserController.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dmaster.auth.controller;
 
 import cn.reghao.autodop.dmaster.auth.model.*;
-import cn.reghao.autodop.dmaster.auth.model.po.GrantedAuthorityImpl;
+import cn.reghao.autodop.dmaster.auth.model.po.UserAuthority;
 import cn.reghao.autodop.dmaster.auth.model.po.Role;
 import cn.reghao.autodop.dmaster.auth.model.po.User;
 import cn.reghao.autodop.dmaster.auth.service.UserService;
@@ -36,8 +36,8 @@ public class UserController {
     @ApiOperation(value = "创建用户")
     @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
     public String createUser(@Validated User user, @RequestParam("roles") Set<Role> roles) {
-        Set<GrantedAuthorityImpl> authorities = roles.stream()
-                .map(role -> new GrantedAuthorityImpl(role.getTitle()))
+        Set<UserAuthority> authorities = roles.stream()
+                .map(role -> new UserAuthority(role.getTitle()))
                 .collect(Collectors.toSet());
         user.setAuthorities(authorities);
         userService.createUser(user);

+ 2 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/db/query/RoleQuery.java

@@ -1,6 +1,6 @@
 package cn.reghao.autodop.dmaster.auth.db.query;
 
-import cn.reghao.autodop.dmaster.auth.model.po.GrantedAuthorityImpl;
+import cn.reghao.autodop.dmaster.auth.model.po.UserAuthority;
 import cn.reghao.autodop.dmaster.auth.model.po.Role;
 import cn.reghao.autodop.dmaster.auth.model.po.User;
 import cn.reghao.autodop.dmaster.auth.model.vo.RoleVO;
@@ -73,7 +73,7 @@ public class RoleQuery {
     public List<User> getUsersByRole(Role role) {
         String title = role.getTitle();
         Specification<User> specification = ((root, query, cb) -> {
-            SetJoin<User, GrantedAuthorityImpl> setJoin = root.joinSet("authorities");
+            SetJoin<User, UserAuthority> setJoin = root.joinSet("authorities");
             Predicate predicate = cb.equal(setJoin.get("role"), title);
             return cb.and(predicate);
         });

+ 3 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/db/query/UserQuery.java

@@ -1,6 +1,6 @@
 package cn.reghao.autodop.dmaster.auth.db.query;
 
-import cn.reghao.autodop.dmaster.auth.model.po.GrantedAuthorityImpl;
+import cn.reghao.autodop.dmaster.auth.model.po.UserAuthority;
 import cn.reghao.autodop.dmaster.auth.model.po.Role;
 import cn.reghao.autodop.dmaster.auth.model.po.User;
 import cn.reghao.autodop.dmaster.auth.model.vo.UserVO;
@@ -43,9 +43,9 @@ public class UserQuery {
     }
 
     public Set<Role> getUserRoles(User user) {
-        Set<GrantedAuthorityImpl> set = user.getAuthoritiesSet();
+        Set<UserAuthority> set = user.getAuthoritiesSet();
         List<String> roles = set.stream()
-                .map(GrantedAuthorityImpl::getAuthority)
+                .map(UserAuthority::getAuthority)
                 .collect(Collectors.toList());
         Specification<Role> spec = ((root, query, criteriaBuilder) -> root.get("title").in(roles));
         return new HashSet<>(roleRepository.findAll(spec));

+ 0 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/db/repository/RoleRepository.java

@@ -10,5 +10,4 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  */
 public interface RoleRepository extends JpaRepository<Role, Integer>, JpaSpecificationExecutor<Role> {
     Role findByTitle(String title);
-    Role findById(int roleId);
 }

+ 2 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/model/po/Role.java

@@ -22,8 +22,10 @@ import java.util.Set;
 @Entity
 public class Role extends BaseEntity<Integer> {
     @Pattern(regexp = "^\\w+$", message = "只能是数字、英文字符和下划线")
+    @Column(unique = true, nullable = false)
     private String title;
     @Pattern(regexp = "^[\\u4e00-\\u9fa5]{0,}$", message = "只能是中文字符")
+    @Column(nullable = false)
     private String name;
     private String description;
     // 角色可访问的资源,一个角色可访问多个资源

+ 7 - 5
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/model/po/User.java

@@ -34,19 +34,22 @@ public class User extends BaseEntity<Integer> implements UserDetails {
     private String password;
     @Column(nullable = false)
     private String salt;
+    // roles 和 authorities 是同一个东东, 只是 authorities 用于 Spring Security
     @ElementCollection(fetch = FetchType.EAGER)
-    private Set<GrantedAuthorityImpl> authorities;
+    private Set<String> roles;
+    @Transient
+    private Set<UserAuthority> authorities;
     private Boolean isEnabled;
     private Boolean isLocked;
 
     @NotBlank(message = "标题不能为空白字符串")
     private String nickname;
+    private String avatarUrl;
     private String mobilePhone;
     private String email;
     private Integer gender;
-    private String avatarUrl;
 
-    public User(String username, Set<GrantedAuthorityImpl> authorities) {
+    public User(String username, Set<UserAuthority> authorities) {
         this.username = username;
         this.authorities = authorities;
     }
@@ -111,7 +114,6 @@ public class User extends BaseEntity<Integer> implements UserDetails {
 
     /**
      * 权限列表
-     * // TODO 不能向返回的集合添加 GrantedAuthorityImpl 元素
      *
      * @param
      * @return
@@ -122,7 +124,7 @@ public class User extends BaseEntity<Integer> implements UserDetails {
         return authorities;
     }
 
-    public Set<GrantedAuthorityImpl> getAuthoritiesSet() {
+    public Set<UserAuthority> getAuthoritiesSet() {
         return authorities;
     }
 }

+ 5 - 5
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/model/po/GrantedAuthorityImpl.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/model/po/UserAuthority.java

@@ -13,15 +13,15 @@ import javax.persistence.*;
  * @date 2020-06-24 14:44:25
  */
 @Embeddable
-public class GrantedAuthorityImpl implements GrantedAuthority {
+public class UserAuthority implements GrantedAuthority {
     private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
     private final String role;
 
-    public GrantedAuthorityImpl() {
+    public UserAuthority() {
         this.role = "ROLE_USER";
     }
 
-    public GrantedAuthorityImpl(String role) {
+    public UserAuthority(String role) {
         Assert.hasText(role, "A granted authority textual representation is required");
         this.role = role;
     }
@@ -37,8 +37,8 @@ public class GrantedAuthorityImpl implements GrantedAuthority {
             return true;
         }
 
-        if (obj instanceof GrantedAuthorityImpl) {
-            return role.equals(((GrantedAuthorityImpl) obj).role);
+        if (obj instanceof UserAuthority) {
+            return role.equals(((UserAuthority) obj).role);
         }
 
         return false;

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/UserService.java

@@ -9,6 +9,7 @@ import cn.reghao.autodop.dmaster.auth.model.UserRole;
  * @date 2020-06-19 16:36:53
  */
 public interface UserService {
+    User getUser(String username);
     void createUser(User user);
     void modifyUserPassword(Integer userId, String newPassword);
     void modifyUserInfo(UserInfo userInfo);

+ 26 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/UserServiceImpl.java

@@ -3,8 +3,10 @@ package cn.reghao.autodop.dmaster.auth.service;
 import cn.reghao.autodop.common.utils.security.Cryptor;
 import cn.reghao.autodop.common.utils.security.Md5Cryptor;
 import cn.reghao.autodop.common.utils.security.Salt;
+import cn.reghao.autodop.dmaster.auth.db.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.model.*;
-import cn.reghao.autodop.dmaster.auth.model.po.GrantedAuthorityImpl;
+import cn.reghao.autodop.dmaster.auth.model.po.UserAuthority;
+import cn.reghao.autodop.dmaster.auth.model.po.Role;
 import cn.reghao.autodop.dmaster.auth.model.po.User;
 import cn.reghao.autodop.dmaster.auth.db.repository.UserRepository;
 import lombok.extern.slf4j.Slf4j;
@@ -22,15 +24,33 @@ import java.util.stream.Collectors;
 @Slf4j
 @Service
 public class UserServiceImpl implements UserService {
-    private UserRepository userRepository;
-    private Cryptor cryptor;
+    private final UserRepository userRepository;
+    private final RoleRepository roleRepository;
+    private final Cryptor cryptor;
 
-    public UserServiceImpl(UserRepository userRepository)
+    public UserServiceImpl(UserRepository userRepository, RoleRepository roleRepository)
             throws NoSuchAlgorithmException {
         this.userRepository = userRepository;
+        this.roleRepository = roleRepository;
         this.cryptor = new Md5Cryptor();
     }
 
+    @Override
+    public User getUser(String username) {
+        User user = userRepository.findByUsername(username);
+        if (user != null) {
+            setGrantedAuthorities(user);
+        }
+        return user;
+    }
+
+    private void setGrantedAuthorities(User user) {
+        Set<UserAuthority> grantedAuthorities = user.getRoles().stream()
+                .map(UserAuthority::new)
+                .collect(Collectors.toSet());
+        user.setAuthorities(grantedAuthorities);
+    }
+
     @Override
     public void createUser(User user) {
         String username = user.getUsername();
@@ -88,8 +108,8 @@ public class UserServiceImpl implements UserService {
             return;
         }
 
-        Set<GrantedAuthorityImpl> authorities = userRole.getRoles().stream()
-                .map(role -> new GrantedAuthorityImpl(role.getTitle()))
+        Set<UserAuthority> authorities = userRole.getRoles().stream()
+                .map(role -> new UserAuthority(role.getTitle()))
                 .collect(Collectors.toSet());
         userEntity.setAuthorities(authorities);
         userRepository.save(userEntity);

+ 3 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/sys/controller/TestController.java

@@ -1,6 +1,6 @@
 package cn.reghao.autodop.dmaster.sys.controller;
 
-import cn.reghao.autodop.dmaster.auth.model.po.GrantedAuthorityImpl;
+import cn.reghao.autodop.dmaster.auth.model.po.UserAuthority;
 import cn.reghao.autodop.dmaster.auth.model.po.Menu;
 import cn.reghao.autodop.dmaster.auth.model.po.Role;
 import cn.reghao.autodop.dmaster.auth.model.po.User;
@@ -125,8 +125,8 @@ public class TestController {
     }
 
     private void addUsers() {
-        GrantedAuthorityImpl authority = new GrantedAuthorityImpl("ROLE_ADMIN");
-        Set<GrantedAuthorityImpl> authorities = new HashSet<>();
+        UserAuthority authority = new UserAuthority("ROLE_ADMIN");
+        Set<UserAuthority> authorities = new HashSet<>();
         authorities.add(authority);
 
         String username = "admin";

+ 50 - 38
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/HomePageController.java

@@ -2,71 +2,83 @@ package cn.reghao.autodop.dmaster.view.controller;
 
 import cn.reghao.autodop.dmaster.auth.UserContext;
 import cn.reghao.autodop.dmaster.auth.model.po.Menu;
-import cn.reghao.autodop.dmaster.auth.model.po.Role;
 import cn.reghao.autodop.dmaster.auth.model.po.User;
-import cn.reghao.autodop.dmaster.auth.db.repository.RoleRepository;
-import cn.reghao.autodop.dmaster.auth.db.repository.MenuRepository;
+import cn.reghao.autodop.dmaster.view.service.HomeService;
 import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.web.servlet.error.ErrorController;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * @author reghao
  * @date 2021-04-04 21:24:18
  */
-@Api("首页页面")
+@Slf4j
+@Api("登录页和首页")
 @Controller
-public class HomePageController {
-    private final MenuRepository menuRepository;
-    private final RoleRepository roleRepository;
+public class HomePageController implements ErrorController {
+    private final HomeService homeService;
 
-    public HomePageController(MenuRepository menuRepository, RoleRepository roleRepository) {
-        this.menuRepository = menuRepository;
-        this.roleRepository = roleRepository;
+    public HomePageController(HomeService homeService) {
+        this.homeService = homeService;
     }
 
     @GetMapping("/")
     public String index(Model model) {
         User user = UserContext.currentUser();
-        List<Menu> menus = new ArrayList<>();
-        user.getAuthorities().forEach(auth -> {
-            Role role = roleRepository.findByTitle(auth.getAuthority());
-            menus.addAll(role.getMenus());
-        });
-        // TODO 根据用户角色获取相应的 menu
-        //List<Menu> menus = menuRepository.findAll();
-
-        Map<Integer, List<Menu>> map =  menus.stream()
-                .collect(Collectors.groupingBy(Menu::getPid));
-        map.forEach((pid, menuList) -> {
-        });
-
-        // id -> menu
-        Map<Integer, Menu> keyMenu = new HashMap<>(16);
-        menus.forEach(menu -> keyMenu.put(menu.getId(), menu));
-
-        // 封装菜单树形数据
-        Map<Integer, Menu> treeMenu = new HashMap<>(16);
-        keyMenu.forEach((id, menu) -> {
-            Menu parentMenu = keyMenu.get(menu.getPid());
-            if (parentMenu != null) {
-                parentMenu.getChildren().put(menu.getPos(), menu);
-            } else {
-                treeMenu.put(menu.getPos(), menu);
-            }
-        });
+        List<Menu> menus = homeService.userMenus(user.getRoles());
+        Map<Integer, Menu> treeMenu = homeService.treeMenu(menus);
 
         model.addAttribute("user", user);
         model.addAttribute("treeMenu", treeMenu);
         return "/main";
     }
 
+    @GetMapping("/login")
+    public String toLogin(Model model) {
+        model.addAttribute("isCaptcha", false);
+        return "/login";
+    }
+
     @GetMapping("/home")
     public String home(Model model) {
         return "/home/index";
     }
+
+    @Override
+    public String getErrorPath() {
+        return "/error";
+    }
+
+    /**
+     * 处理错误页面
+     *
+     * @param
+     * @return
+     * @date 2021-05-19 下午2:35
+     */
+    @RequestMapping("/error")
+    @ResponseBody
+    public String handleError(Model model, HttpServletRequest request) {
+        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
+        if (statusCode == 404) {
+            return "接口不存在";
+        } else if (statusCode == 400) {
+            return "参数错误";
+        } else if (statusCode == 500) {
+            return "服务器内部错误";
+        }
+        log.error("http status code: " + statusCode);
+
+        model.addAttribute("statusCode", statusCode);
+        model.addAttribute("msg", "页面去火星啦~");
+        return "/404";
+    }
 }

+ 0 - 57
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/LoginPageController.java

@@ -1,57 +0,0 @@
-package cn.reghao.autodop.dmaster.view.controller;
-
-import io.swagger.annotations.Api;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.web.servlet.error.ErrorController;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * @author reghao
- * @date 2021-04-04 21:24:18
- */
-@Slf4j
-@Api(tags = "登录页面")
-@Controller
-public class LoginPageController implements ErrorController {
-    @GetMapping("/login")
-    public String toLogin(Model model) {
-        model.addAttribute("isCaptcha", false);
-        return "/login";
-    }
-
-    @Override
-    public String getErrorPath() {
-        return "/error";
-    }
-
-    /**
-     * 处理错误页面
-     *
-     * @param
-     * @return
-     * @date 2021-05-19 下午2:35
-     */
-    @RequestMapping("/error")
-    @ResponseBody
-    public String handleError(Model model, HttpServletRequest request) {
-        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
-        if (statusCode == 404) {
-            return "接口不存在";
-        } else if (statusCode == 400) {
-            return "参数错误";
-        } else if (statusCode == 500) {
-            return "服务器内部错误";
-        }
-        log.error("http status code: " + statusCode);
-
-        model.addAttribute("statusCode", statusCode);
-        model.addAttribute("msg", "页面去火星啦~");
-        return "/404";
-    }
-}

+ 47 - 4
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/service/HomeService.java

@@ -1,10 +1,12 @@
 package cn.reghao.autodop.dmaster.view.service;
 
+import cn.reghao.autodop.dmaster.auth.db.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.model.po.Menu;
 import cn.reghao.autodop.dmaster.auth.db.repository.MenuRepository;
+import cn.reghao.autodop.dmaster.auth.model.po.Role;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
+import java.util.*;
 
 /**
  * @author reghao
@@ -12,13 +14,54 @@ import java.util.List;
  */
 @Service
 public class HomeService {
+    private final RoleRepository roleRepository;
     private MenuRepository menuRepository;
 
-    public HomeService(MenuRepository menuRepository) {
+    public HomeService(RoleRepository roleRepository, MenuRepository menuRepository) {
+        this.roleRepository = roleRepository;
         this.menuRepository = menuRepository;
     }
 
-    public List<Menu> menuList() {
-        return menuRepository.findAll();
+    /**
+     * 用户拥有的角色可访问的资源
+     *
+     * @param
+     * @return
+     * @date 2021-09-10 下午6:27
+     */
+    public List<Menu> userMenus(Set<String> roles) {
+        List<Menu> menus = new ArrayList<>();
+        roles.forEach(roleTitle -> {
+            Role role = roleRepository.findByTitle(roleTitle);
+            menus.addAll(role.getMenus());
+        });
+
+        return menus;
+    }
+
+    /**
+     * 根据 menu 集合生成页面侧边栏的树形菜单
+     *
+     * @param
+     * @return
+     * @date 2021-09-10 下午6:24
+     */
+    public Map<Integer, Menu> treeMenu(List<Menu> menus) {
+        // id -> menu
+        Map<Integer, Menu> keyMenu = new HashMap<>(16);
+        menus.forEach(menu -> keyMenu.put(menu.getId(), menu));
+
+        // 树形菜单数据
+        Map<Integer, Menu> treeMenu = new HashMap<>(16);
+        keyMenu.forEach((id, menu) -> {
+            Menu parentMenu = keyMenu.get(menu.getPid());
+            if (parentMenu != null) {
+                parentMenu.getChildren().put(menu.getPos(), menu);
+            } else {
+                treeMenu.put(menu.getPos(), menu);
+            }
+        });
+
+        return treeMenu;
     }
 }