diff --git a/src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java b/src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java new file mode 100644 index 0000000..0c46d72 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java @@ -0,0 +1,94 @@ +package com.zsc.edu.gateway; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.Role; +import com.zsc.edu.gateway.modules.system.entity.User; +import com.zsc.edu.gateway.modules.system.repo.DeptRepository; +import com.zsc.edu.gateway.modules.system.repo.UserRepository; +import com.zsc.edu.gateway.modules.system.service.AuthorityService; +import com.zsc.edu.gateway.modules.system.service.DeptService; +import com.zsc.edu.gateway.modules.system.service.RoleService; +import com.zsc.edu.gateway.modules.system.service.UserService; +import lombok.AllArgsConstructor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Profile; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * 系统初始化程序 + * + * @author harry_yao + */ +@AllArgsConstructor +@Component +@Profile("!test") +public class FirstTimeInitializer implements CommandLineRunner { + + private final AuthorityService authorityService; + private final UserService userService; + private final RoleService roleService; + private final DeptService deptService; + private final DeptRepository deptRepo; + private final PasswordEncoder passwordEncoder; + + @Override + + public void run(String... args) { + if (authorityService.count() == 0L) { + Authority userPerm = new Authority(null, "用户模块", "用户管理", "USER", true, null); + Authority rolePerm = new Authority(null, "角色模块", "角色管理", "ROLE", true, null); + Authority deptPerm = new Authority(null, "部门模块", "部门管理", "DEPT", true, null); + Authority AuthorityPerm = new Authority(null, "权限模块", "权限管理", "Authority", true, null); + authorityService.saveBatch(List.of(userPerm, rolePerm, deptPerm, AuthorityPerm)); + List authorities = new ArrayList<>(); + authorities.add(new Authority(userPerm.getId(), "用户管理", "用户列表", "USER_QUERY", true, null)); + authorities.add(new Authority(userPerm.getId(), "用户管理", "用户新增", "USER_CREATE",true, null)); + authorities.add(new Authority(userPerm.getId(), "用户管理", "用户修改", "USER_UPDATE",true, null)); + authorities.add(new Authority(userPerm.getId(), "用户管理", "用户删除", "USER_DELETE",true, null)); + authorities.add(new Authority(rolePerm.getId(), "角色管理", "角色列表", "ROLE_QUERY", true, null)); + authorities.add(new Authority(rolePerm.getId(), "角色管理", "角色新增", "ROLE_CREATE",true, null)); + authorities.add(new Authority(rolePerm.getId(), "角色管理", "角色修改", "ROLE_UPDATE",true, null)); + authorities.add(new Authority(rolePerm.getId(), "角色管理", "角色删除", "ROLE_DELETE",true, null)); + authorities.add(new Authority(deptPerm.getId(), "部门管理", "部门列表", "DEPT_QUERY", true, null)); + authorities.add(new Authority(deptPerm.getId(), "部门管理", "部门新增", "DEPT_CREATE",true, null)); + authorities.add(new Authority(deptPerm.getId(), "部门管理", "部门修改", "DEPT_UPDATE",true, null)); + authorities.add(new Authority(deptPerm.getId(), "部门管理", "部门删除", "DEPT_DELETE",true, null)); + authorities.add(new Authority(AuthorityPerm.getId(), "权限管理", "权限列表", "AUTHORITY_QUERY", true, null)); + authorities.add(new Authority(AuthorityPerm.getId(), "权限管理", "权限新增", "AUTHORITY_CREATE",true, null)); + authorities.add(new Authority(AuthorityPerm.getId(), "权限管理", "权限修改", "AUTHORITY_UPDATE",true, null)); + authorities.add(new Authority(AuthorityPerm.getId(), "权限管理", "权限删除", "AUTHORITY_DELETE",true, null)); + authorityService.saveBatch(authorities); + } + if (roleService.count() == 0L) { + Role admin = new Role(); + admin.setName("管理员"); + admin.setEnabled(true); + roleService.save(admin); + } + if (deptService.count() == 0L) { + Dept dept = new Dept(); + dept.setName("总公司"); + deptService.save(dept); + } + if (userService.count() == 0L) { + Dept dept = deptService.getOne(new QueryWrapper<>()); + Role role = roleService.getOne(new QueryWrapper<>()); + User user = new User(); + user.setUsername("admin"); + user.setPassword(passwordEncoder.encode("admin")); + user.setPhone("15913375741"); + user.setEmail("admin@zsc.edu.cn"); + user.setName("admin"); + user.setRoleId(role.getId()); + user.setDeptId(dept.getId()); + userService.save(user); + } + + } +} diff --git a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MyMetaObjectHandler.java b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MyMetaObjectHandler.java index 0dc1614..eaaec9e 100644 --- a/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MyMetaObjectHandler.java +++ b/src/main/java/com/zsc/edu/gateway/framework/mybatisplus/MyMetaObjectHandler.java @@ -6,6 +6,7 @@ import com.zsc.edu.gateway.framework.security.UserDetailsImpl; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import java.time.LocalDateTime; @@ -20,17 +21,22 @@ public class MyMetaObjectHandler implements MetaObjectHandler { public void insertFill(MetaObject metaObject) { UserDetailsImpl userInfo = SecurityUtil.getUserInfo(); - - this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class); - this.strictInsertFill(metaObject, "createdBy", userInfo::getUsername, String.class); + if (userInfo.getUsername() == null) { + userInfo.setUsername( "system"); + } + this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); + this.strictInsertFill(metaObject, "createBy", String.class, userInfo.getUsername()); } @Override public void updateFill(MetaObject metaObject) { UserDetailsImpl userInfo = SecurityUtil.getUserInfo(); + if (userInfo.getUsername() == null) { + userInfo.setUsername( "system"); + } this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); - this.strictUpdateFill(metaObject, "updatedBy", userInfo::getUsername, String.class); + this.strictUpdateFill(metaObject, "updateBy", userInfo::getUsername, String.class); } diff --git a/src/main/java/com/zsc/edu/gateway/framework/security/SecurityUtil.java b/src/main/java/com/zsc/edu/gateway/framework/security/SecurityUtil.java index ccef85a..450c27f 100644 --- a/src/main/java/com/zsc/edu/gateway/framework/security/SecurityUtil.java +++ b/src/main/java/com/zsc/edu/gateway/framework/security/SecurityUtil.java @@ -3,17 +3,19 @@ package com.zsc.edu.gateway.framework.security; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import java.util.Objects; + /** * @author Yao */ public class SecurityUtil { public static UserDetailsImpl getUserInfo() { - return getPrincipal(); - } - - private static UserDetailsImpl getPrincipal() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (Objects.isNull(authentication)) { + return new UserDetailsImpl(); + } return (UserDetailsImpl) authentication.getPrincipal(); } + } diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/controller/DeptController.java b/src/main/java/com/zsc/edu/gateway/modules/system/controller/DeptController.java index 1168dd4..d51e15a 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/controller/DeptController.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/controller/DeptController.java @@ -38,6 +38,18 @@ public class DeptController { return service.page(page, query.wrapper()); } + /** + * 返回管理部门列表 hasAuthority('DEPT_QUERY') + * + * @param id 指定部门id + * @return 部门列表 + */ + @GetMapping("/tree") + @PreAuthorize("hasAuthority('DEPT_QUERY')") + public Dept tree(@RequestParam Long id) { + return service.listTree(id); + } + /** * 新建管理部门 hasAuthority('DEPT_CREATE') * @@ -62,6 +74,7 @@ public class DeptController { public Boolean update(@RequestBody DeptDto dto, @PathVariable("id") Long id) { return service.edit(dto, id); } + /*** * 删除管理部门 hasAuthority('DEPT_DELETE') * @param id 部门ID @@ -70,15 +83,14 @@ public class DeptController { @DeleteMapping("/{id}") @PreAuthorize("hasAuthority('DEPT_DELETE')") public Boolean delete(@PathVariable("id") Long id) { - /** - * 是否存在用户绑定此部门 - * */ + // 是否存在用户绑定此部门 boolean hasUser = userService.count(new LambdaQueryWrapper().eq(User::getDeptId, id)) > 0; if (hasUser) { throw new ConstraintException("存在与本部门绑定的用户,请先删除用户"); } return service.removeById(id); } + /** * 更新管理部门状态 * */ diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/controller/UserController.java b/src/main/java/com/zsc/edu/gateway/modules/system/controller/UserController.java index 4bfc75c..8df7501 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/controller/UserController.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/controller/UserController.java @@ -9,10 +9,13 @@ import com.zsc.edu.gateway.modules.system.dto.UserSelfUpdateDto; import com.zsc.edu.gateway.modules.system.dto.UserSelfUpdatePasswordDto; import com.zsc.edu.gateway.modules.system.dto.UserUpdateDto; import com.zsc.edu.gateway.modules.system.entity.Authority; +import com.zsc.edu.gateway.modules.system.entity.Menu; import com.zsc.edu.gateway.modules.system.entity.Role; import com.zsc.edu.gateway.modules.system.entity.User; import com.zsc.edu.gateway.modules.system.query.UserQuery; import com.zsc.edu.gateway.modules.system.service.*; +import com.zsc.edu.gateway.modules.system.utils.TreeUtil; +import com.zsc.edu.gateway.modules.system.vo.MenuVo; import com.zsc.edu.gateway.modules.system.vo.UserDetail; import com.zsc.edu.gateway.modules.system.vo.UserVo; import lombok.AllArgsConstructor; @@ -21,10 +24,7 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.web.bind.annotation.*; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * 用户Controller @@ -42,6 +42,7 @@ public class UserController { private final DeptService deptService; private final RoleAuthService roleAuthService; private final AuthorityService authorityService; + private final MenuService menuService; /** * 登录前,获取csrfToken信息 @@ -182,6 +183,7 @@ public class UserController { public Collection listByDept(@PathVariable("id") Long id) { return service.list(new QueryWrapper().eq("dept_id", id)); } + /** * 根据ID查询用户 * */ @@ -189,6 +191,20 @@ public class UserController { public User detail(@PathVariable("id") Long id) { return service.getById(id); } + + /** + * 根据ID查询用户 + * */ + @GetMapping("/menu") + public List menu() { + List list = menuService.list().stream().map(MenuVo::new).toList(); + return TreeUtil.makeTree( + list, + x -> x.getPid() == null, + (x, y) -> x.getId().equals(y.getPid()), + MenuVo::setChildren + ); + } /** * 发送邮件 * */ diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/entity/Authority.java b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Authority.java index be740f4..4f70aef 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/entity/Authority.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Authority.java @@ -1,6 +1,7 @@ package com.zsc.edu.gateway.modules.system.entity; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -14,17 +15,29 @@ import java.util.Date; */ @Getter @Setter +@AllArgsConstructor @EqualsAndHashCode(callSuper = false) @TableName("sys_authority") public class Authority extends BaseEntity { + + private Long pid; + + /** + * 权限模块 + */ + private String module; /** * 权限名 */ public String name; + /** + * 权限标识符 + */ + public String code; /** * 启用状态 */ - private Boolean enabled = true; + private Boolean enabled; /** * 备注 */ diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/entity/Dept.java b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Dept.java index 93f302e..8fa5392 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/entity/Dept.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Dept.java @@ -27,7 +27,7 @@ public class Dept extends BaseEntity { /** * 子部门数目 */ - private Integer subCount; + private Integer subCount = 0; /** * 名称 @@ -37,7 +37,7 @@ public class Dept extends BaseEntity { /** * 排序 */ - private Integer deptSort; + private Integer deptSort = 1; /** * 状态 diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/entity/Menu.java b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Menu.java new file mode 100644 index 0000000..83935a6 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/system/entity/Menu.java @@ -0,0 +1,66 @@ +package com.zsc.edu.gateway.modules.system.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +/** + * 菜单 + * + * @author harry yao + */ +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@TableName("sys_menu") +public class Menu extends BaseEntity { + /** + * 父菜单id + */ + private Long pid; + /** + * 路由名称 + */ + private String name; + /** + * 菜单路径 + */ + private String path; + /** + * 菜单名称(语言包键名) + */ + private String locale; + /** + * 菜单icon + */ + private String icon; + /** + * 是否需要登录鉴权 + */ + private Boolean requiresAuth=true; + /** + * 是否隐藏菜单 + */ + private Boolean hideInMenu=false; + /** + * 排序 + */ + private Integer menuOrder; + /** + * 访问权限,使用","隔开的权限字符串 + */ + private String permissions; + + public Menu(Long pid, String name, String path, String locale, String icon, Boolean requiresAuth, Boolean hideInMenu, Integer order, String permissions) { + this.pid = pid; + this.name = name; + this.path = path; + this.locale = locale; + this.icon = icon; + this.requiresAuth = requiresAuth; + this.hideInMenu = hideInMenu; + this.menuOrder = order; + this.permissions = permissions; + } +} \ No newline at end of file diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java b/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java index 82715f2..de5c77a 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/entity/User.java @@ -67,7 +67,7 @@ public class User extends BaseEntity { public Long roleId; /** - * 拥有的角色 + * 拥有的当前角色 */ @TableField(exist = false) public Role role; diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/entity/UserRole.java b/src/main/java/com/zsc/edu/gateway/modules/system/entity/UserRole.java index 9ff731f..b77a897 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/entity/UserRole.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/entity/UserRole.java @@ -3,6 +3,7 @@ package com.zsc.edu.gateway.modules.system.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import java.io.Serial; import java.io.Serializable; /** @@ -21,6 +22,4 @@ public class UserRole implements Serializable { * 角色ID */ private Long roleId; - - private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/repo/MenuRepository.java b/src/main/java/com/zsc/edu/gateway/modules/system/repo/MenuRepository.java new file mode 100644 index 0000000..658df91 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/system/repo/MenuRepository.java @@ -0,0 +1,13 @@ +package com.zsc.edu.gateway.modules.system.repo; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zsc.edu.gateway.modules.system.entity.Menu; + +import java.util.Set; + +/** + * @author yao + */ +public interface MenuRepository extends BaseMapper { +} + diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/service/DeptService.java b/src/main/java/com/zsc/edu/gateway/modules/system/service/DeptService.java index e296436..e85ec90 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/service/DeptService.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/service/DeptService.java @@ -34,5 +34,5 @@ public interface DeptService extends IService { * @param id * @return */ -// Dept listTree(Long id); + Dept listTree(Long id); } diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/service/MenuService.java b/src/main/java/com/zsc/edu/gateway/modules/system/service/MenuService.java new file mode 100644 index 0000000..dfc39b4 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/system/service/MenuService.java @@ -0,0 +1,13 @@ +package com.zsc.edu.gateway.modules.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zsc.edu.gateway.modules.system.entity.Menu; + +import java.util.Set; + +/** + * @author zhuang + */ +public interface MenuService extends IService { + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/service/impl/DeptServiceImpl.java b/src/main/java/com/zsc/edu/gateway/modules/system/service/impl/DeptServiceImpl.java index 7561320..9c64492 100644 --- a/src/main/java/com/zsc/edu/gateway/modules/system/service/impl/DeptServiceImpl.java +++ b/src/main/java/com/zsc/edu/gateway/modules/system/service/impl/DeptServiceImpl.java @@ -8,9 +8,13 @@ import com.zsc.edu.gateway.modules.system.mapper.DeptMapper; import com.zsc.edu.gateway.modules.system.repo.DeptRepository; import com.zsc.edu.gateway.modules.system.service.DeptService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zsc.edu.gateway.modules.system.utils.DeptTreeUtil; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; +import java.util.HashSet; +import java.util.List; + /** *

* 部门 服务实现类 @@ -52,15 +56,15 @@ public class DeptServiceImpl extends ServiceImpl implement return updateById(dept); } -// @Override -// public Dept listTree(Long deptId) { -// Dept rootDept; -// List all = list(null); -// HashSet deptList = new HashSet<>(all); -// rootDept = DeptTreeUtil.initTree(deptList); -// if (deptId != null) { -// return rootDept.id.equals(deptId) ? rootDept : DeptTreeUtil.getChildNode(rootDept.children, deptId); -// } -// return rootDept; -// } + @Override + public Dept listTree(Long deptId) { + Dept rootDept; + List all = this.list(); + HashSet deptList = new HashSet<>(all); + rootDept = DeptTreeUtil.initTree(deptList); + if (deptId != null) { + return rootDept.id.equals(deptId) ? rootDept : DeptTreeUtil.getChildNode(rootDept.children, deptId); + } + return rootDept; + } } diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/service/impl/MenuServiceImpl.java b/src/main/java/com/zsc/edu/gateway/modules/system/service/impl/MenuServiceImpl.java new file mode 100644 index 0000000..6fd1821 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/system/service/impl/MenuServiceImpl.java @@ -0,0 +1,18 @@ +package com.zsc.edu.gateway.modules.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zsc.edu.gateway.modules.system.entity.Menu; +import com.zsc.edu.gateway.modules.system.repo.MenuRepository; +import com.zsc.edu.gateway.modules.system.service.MenuService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Set; + +/** + * @author zhuang + */ +@AllArgsConstructor +@Service +public class MenuServiceImpl extends ServiceImpl implements MenuService { +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/utils/DeptTreeUtil.java b/src/main/java/com/zsc/edu/gateway/modules/system/utils/DeptTreeUtil.java new file mode 100644 index 0000000..eddfe84 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/system/utils/DeptTreeUtil.java @@ -0,0 +1,96 @@ +package com.zsc.edu.gateway.modules.system.utils; + + +import com.zsc.edu.gateway.exception.NotExistException; +import com.zsc.edu.gateway.modules.system.entity.Dept; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Yao + */ +public class DeptTreeUtil { + + public static Dept initTree(HashSet list){ + Dept rootDept = list.stream() + // .filter(dept -> dept.id.equals(deptId)) + .filter(dept -> dept.getPid() == null) + .findFirst() + .orElseThrow(NotExistException::new); + rootDept.setChildren(DeptTreeUtil.getTree(list, rootDept.getId())); + return rootDept; + } + + public static Set initTrees(List list){ + Map deptMap = list.stream().collect(Collectors.toMap(Dept::getId, dept -> dept)); + HashSet result = new HashSet<>(); + list.forEach(dept -> { + Dept parent = deptMap.get(dept.getPid()); + if (Objects.nonNull(parent)) { + parent.getChildren().add(dept); + } else { + result.add(dept); + } + }); + return result; + } + + public static HashSet getTree(HashSet list, long parentId){ + //获取所有子节点 + HashSet childTreeList = getChildTree(list, parentId); + for (Dept dept:childTreeList) { + dept.setChildren(getTree(list, dept.getId())); + } + return childTreeList; + } + + public static HashSet getChildTree(HashSet list, long id){ + HashSet childTree = new HashSet<>(); + for (Dept dept: list) { + if(dept.getPid() != null && dept.getPid() == id){ + childTree.add(dept); + } + } + return childTree; + } + + /** + * 从部门树中获取子树 + * @param list + * @return + */ + public static Dept getChildNode(Set list, long id) { + for (Dept child: list) { + if (child.getId() == id) { + return child; + } else if (child.getChildren() != null && !child.getChildren().isEmpty()) { + return getChildNode(child.getChildren(), id); + } + } + return null; + } + + /** + * 从部门获取本身及子部门的所有id + * @param dept + * @return + */ + public static HashSet getDeptPath(Dept dept) { + HashSet result = new HashSet<>(); + result.add(dept.getId()); + Stack deptStack = new Stack<>(); + Set children = dept.getChildren(); + if (!children.isEmpty()) { + deptStack.addAll(children); + while (!deptStack.isEmpty()) { + Dept child = deptStack.pop(); + result.add(child.getId()); + if (!child.getChildren().isEmpty()) { + deptStack.addAll(child.getChildren()); + } + } + } + return result; + } +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/utils/TreeUtil.java b/src/main/java/com/zsc/edu/gateway/modules/system/utils/TreeUtil.java new file mode 100644 index 0000000..ba07e62 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/system/utils/TreeUtil.java @@ -0,0 +1,148 @@ +package com.zsc.edu.gateway.modules.system.utils; + +import java.util.*; +import java.util.function.*; +import java.util.stream.Collectors; + +/** + * @Description: 树操作方法工具类 + * @Copyright: Copyright (c) 赵侠客 + * @Date: 2024-07-22 10:42 + * @Version: 1.0 + */ +public class TreeUtil { + /** + * 将list合成树 + * + * @param list 需要合成树的List + * @param rootCheck 判断E中为根节点的条件,如:x->x.getPId()==-1L , x->x.getParentId()==null,x->x.getParentMenuId()==0 + * @param parentCheck 判断E中为父节点条件,如:(x,y)->x.getId().equals(y.getPId()) + * @param setSubChildren E中设置下级数据方法,如:Menu::setSubMenus + * @param 泛型实体对象 + * @return 合成好的树 + */ + public static List makeTree(List list, Predicate rootCheck, BiFunction parentCheck, BiConsumer> setSubChildren) { + return list.stream() + .filter(rootCheck) + .peek(x -> setSubChildren.accept(x, makeChildren(x, list, parentCheck, setSubChildren))) + .collect(Collectors.toList()); + } + /** + * 创建子树 + * + * @param parent 父节点 + * @param allData 需要合成树的原始List + * @param parentCheck 判断E中为父节点条件,如:(x,y)->x.getId().equals(y.getPId()) + * @param children E中设置下级数据方法,如:Menu::setSubMenus + * @param 泛型实体对象 + * @return 合成好的子树 + */ + private static List makeChildren(E parent, List allData, BiFunction parentCheck, BiConsumer> children) { + return allData.stream() + .filter(x -> parentCheck.apply(parent, x)) + .peek(x -> children.accept(x, makeChildren(x, allData, parentCheck, children))) + .collect(Collectors.toList()); + } + + /** + * 将树打平成tree + * @param tree 需要打平的树 + * @param getSubChildren 设置下级数据方法,如:Menu::getSubMenus,x->x.setSubMenus(null) + * @param setSubChildren 将下级数据置空方法,如:x->x.setSubMenus(null) + * @return 打平后的数据 + * @param 泛型实体对象 + */ + public static List flat(List tree, Function> getSubChildren, Consumer setSubChildren) { + List res = new ArrayList<>(); + forPostOrder( + tree, + item -> { + setSubChildren.accept(item); + res.add(item); + }, + getSubChildren + ); + return res; + } + + + /** + * 前序遍历 + * + * @param tree 需要遍历的树 + * @param consumer 遍历后对单个元素的处理方法,如:x-> System.out.println(x)、 System.out::println打印元素 + * @param setSubChildren 设置下级数据方法,如:Menu::getSubMenus,x->x.setSubMenus(null) + * @param 泛型实体对象 + */ + public static void forPreOrder(List tree, Consumer consumer, Function> setSubChildren) { + for (E l : tree) { + consumer.accept(l); + List es = setSubChildren.apply(l); + if (Objects.nonNull(es) && !es.isEmpty()) { + forPreOrder(es, consumer, setSubChildren); + } + } + } + + + /** + * 层序遍历 + * + * @param tree 需要遍历的树 + * @param consumer 遍历后对单个元素的处理方法,如:x-> System.out.println(x)、 System.out::println打印元素 + * @param setSubChildren 设置下级数据方法,如:Menu::getSubMenus,x->x.setSubMenus(null) + * @param 泛型实体对象 + */ + public static void forLevelOrder(List tree, Consumer consumer, Function> setSubChildren) { + Queue queue = new LinkedList<>(tree); + while (!queue.isEmpty()) { + E item = queue.poll(); + consumer.accept(item); + List childList = setSubChildren.apply(item); + if (Objects.nonNull(childList) && !childList.isEmpty()) { + queue.addAll(childList); + } + } + } + + + /** + * 后序遍历 + * + * @param tree 需要遍历的树 + * @param consumer 遍历后对单个元素的处理方法,如:x-> System.out.println(x)、 System.out::println打印元素 + * @param setSubChildren 设置下级数据方法,如:Menu::getSubMenus,x->x.setSubMenus(null) + * @param 泛型实体对象 + */ + public static void forPostOrder(List tree, Consumer consumer, Function> setSubChildren) { + for (E item : tree) { + List childList = setSubChildren.apply(item); + if (Objects.nonNull(childList) && !childList.isEmpty()) { + forPostOrder(childList, consumer, setSubChildren); + } + consumer.accept(item); + } + } + + /** + * 对树所有子节点按comparator排序 + * + * @param tree 需要排序的树 + * @param comparator 排序规则Comparator,如:Comparator.comparing(MenuVo::getRank)按Rank正序 ,(x,y)->y.getRank().compareTo(x.getRank()),按Rank倒序 + * @param getChildren 获取下级数据方法,如:MenuVo::getSubMenus + * @return 排序好的树 + * @param 泛型实体对象 + */ + public static List sort(List tree, Comparator comparator, Function> getChildren) { + for (E item : tree) { + List childList = getChildren.apply(item); + if (Objects.nonNull(childList) && !childList.isEmpty()) { + sort(childList,comparator,getChildren); + } + } + tree.sort(comparator); + return tree; + } + + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/system/vo/MenuVo.java b/src/main/java/com/zsc/edu/gateway/modules/system/vo/MenuVo.java new file mode 100644 index 0000000..2767ad1 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/system/vo/MenuVo.java @@ -0,0 +1,82 @@ +package com.zsc.edu.gateway.modules.system.vo; + +import com.zsc.edu.gateway.modules.system.entity.Menu; +import lombok.Data; + +import java.util.List; + +/** + * 菜单 + * + * @author harry yao + */ +@Data +public class MenuVo { + /** + * 菜单id + */ + private Long id; + /** + * 父菜单id + */ + private Long pid; + /** + * 路由名称 + */ + private String name; + /** + * 菜单路径 + */ + private String path; + + private Meta meta; + + /** + * 子菜单 + */ + private List children = null; + + public MenuVo(Menu menu) { + this.id = menu.getId(); + this.pid = menu.getPid(); + this.name = menu.getName(); + this.path = menu.getPath(); + this.meta = new Meta(menu); + } +} +@Data +class Meta { + /** + * 菜单名称(语言包键名) + */ + private String locale; + /** + * 菜单icon + */ + private String icon; + /** + * 是否需要登录鉴权 + */ + private Boolean requiresAuth; + /** + * 是否隐藏菜单 + */ + private Boolean hideInMenu; + /** + * 排序 + */ + private Integer order; + /** + * 访问权限,使用","隔开的权限字符串 + */ + private String permissions; + + public Meta(Menu menu) { + this.locale = menu.getLocale(); + this.icon = menu.getIcon(); + this.requiresAuth = menu.getRequiresAuth(); + this.hideInMenu = menu.getHideInMenu(); + this.order = menu.getMenuOrder(); + this.permissions = menu.getPermissions(); + } +} \ No newline at end of file diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index ea6d883..fc009c1 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -9,14 +9,17 @@ mybatis-plus: spring: datasource: - url: jdbc:postgresql://localhost:5432/gateway?ssl=false&TimeZone=Asia/Shanghai - username: root - password: 123123 + url: jdbc:postgresql://43.139.10.64:15432/gateway?ssl=false&TimeZone=Asia/Shanghai + username: gitea + password: gitea driver-class-name: org.postgresql.Driver servlet: multipart: max-file-size: 40MB max-request-size: 40MB + jackson: + # 属性为空不序列化 + default-property-inclusion: non_null mail: # 配置 SMTP 服务器地址 host: smtp.qq.com diff --git a/src/main/resources/mappers/AuthorityMapper.xml b/src/main/resources/mappers/AuthorityMapper.xml index b8856f3..43b7048 100644 --- a/src/main/resources/mappers/AuthorityMapper.xml +++ b/src/main/resources/mappers/AuthorityMapper.xml @@ -3,16 +3,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - + \ No newline at end of file diff --git a/src/main/resources/mappers/DeptMapper.xml b/src/main/resources/mappers/DeptMapper.xml index f1a3d6c..764042d 100644 --- a/src/main/resources/mappers/DeptMapper.xml +++ b/src/main/resources/mappers/DeptMapper.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main/resources/mappers/RoleAuthoritiesReposity.xml b/src/main/resources/mappers/RoleAuthoritiesReposity.xml index d47228b..0c872c2 100644 --- a/src/main/resources/mappers/RoleAuthoritiesReposity.xml +++ b/src/main/resources/mappers/RoleAuthoritiesReposity.xml @@ -1,15 +1,5 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/mappers/RoleMapper.xml b/src/main/resources/mappers/RoleMapper.xml index bf013c0..699d8b6 100644 --- a/src/main/resources/mappers/RoleMapper.xml +++ b/src/main/resources/mappers/RoleMapper.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main/resources/mappers/UserMapper.xml b/src/main/resources/mappers/UserMapper.xml index 904519a..e042786 100644 --- a/src/main/resources/mappers/UserMapper.xml +++ b/src/main/resources/mappers/UserMapper.xml @@ -1,24 +1,8 @@ - - - - - - - - - - - - - - - - - - + + @@ -35,19 +19,21 @@ id, username, password, email, phone, create_time - select * from sys_user left join study.sys_role sr on sys_user.role_id = sr.id where username = #{username,jdbcType=VARCHAR} + +