first update
This commit is contained in:
parent
2cebdf5895
commit
571bfc27b3
94
src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java
Normal file
94
src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java
Normal file
@ -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<Authority> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<User>().eq(User::getDeptId, id)) > 0;
|
||||
if (hasUser) {
|
||||
throw new ConstraintException("存在与本部门绑定的用户,请先删除用户");
|
||||
}
|
||||
return service.removeById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新管理部门状态
|
||||
* */
|
||||
|
@ -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<User> listByDept(@PathVariable("id") Long id) {
|
||||
return service.list(new QueryWrapper<User>().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<MenuVo> menu() {
|
||||
List<MenuVo> 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
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 发送邮件
|
||||
* */
|
||||
|
@ -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;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -67,7 +67,7 @@ public class User extends BaseEntity {
|
||||
public Long roleId;
|
||||
|
||||
/**
|
||||
* 拥有的角色
|
||||
* 拥有的当前角色
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
public Role role;
|
||||
|
@ -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;
|
||||
}
|
@ -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<Menu> {
|
||||
}
|
||||
|
@ -34,5 +34,5 @@ public interface DeptService extends IService<Dept> {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
// Dept listTree(Long id);
|
||||
Dept listTree(Long id);
|
||||
}
|
||||
|
@ -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<Menu> {
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 部门 服务实现类
|
||||
@ -52,15 +56,15 @@ public class DeptServiceImpl extends ServiceImpl<DeptRepository, Dept> implement
|
||||
return updateById(dept);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Dept listTree(Long deptId) {
|
||||
// Dept rootDept;
|
||||
// List<Dept> all = list(null);
|
||||
// HashSet<Dept> 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<Dept> all = this.list();
|
||||
HashSet<Dept> deptList = new HashSet<>(all);
|
||||
rootDept = DeptTreeUtil.initTree(deptList);
|
||||
if (deptId != null) {
|
||||
return rootDept.id.equals(deptId) ? rootDept : DeptTreeUtil.getChildNode(rootDept.children, deptId);
|
||||
}
|
||||
return rootDept;
|
||||
}
|
||||
}
|
||||
|
@ -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<MenuRepository, Menu> implements MenuService {
|
||||
}
|
@ -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<Dept> 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<Dept> initTrees(List<Dept> list){
|
||||
Map<Long, Dept> deptMap = list.stream().collect(Collectors.toMap(Dept::getId, dept -> dept));
|
||||
HashSet<Dept> 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<Dept> getTree(HashSet<Dept> list, long parentId){
|
||||
//获取所有子节点
|
||||
HashSet<Dept> childTreeList = getChildTree(list, parentId);
|
||||
for (Dept dept:childTreeList) {
|
||||
dept.setChildren(getTree(list, dept.getId()));
|
||||
}
|
||||
return childTreeList;
|
||||
}
|
||||
|
||||
public static HashSet<Dept> getChildTree(HashSet<Dept> list, long id){
|
||||
HashSet<Dept> 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<Dept> 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<Long> getDeptPath(Dept dept) {
|
||||
HashSet<Long> result = new HashSet<>();
|
||||
result.add(dept.getId());
|
||||
Stack<Dept> deptStack = new Stack<>();
|
||||
Set<Dept> 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;
|
||||
}
|
||||
}
|
@ -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 <E> 泛型实体对象
|
||||
* @return 合成好的树
|
||||
*/
|
||||
public static <E> List<E> makeTree(List<E> list, Predicate<E> rootCheck, BiFunction<E, E, Boolean> parentCheck, BiConsumer<E, List<E>> 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 <E> 泛型实体对象
|
||||
* @return 合成好的子树
|
||||
*/
|
||||
private static <E> List<E> makeChildren(E parent, List<E> allData, BiFunction<E, E, Boolean> parentCheck, BiConsumer<E, List<E>> 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 <E> 泛型实体对象
|
||||
*/
|
||||
public static <E> List<E> flat(List<E> tree, Function<E, List<E>> getSubChildren, Consumer<E> setSubChildren) {
|
||||
List<E> 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 <E> 泛型实体对象
|
||||
*/
|
||||
public static <E> void forPreOrder(List<E> tree, Consumer<E> consumer, Function<E, List<E>> setSubChildren) {
|
||||
for (E l : tree) {
|
||||
consumer.accept(l);
|
||||
List<E> 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 <E> 泛型实体对象
|
||||
*/
|
||||
public static <E> void forLevelOrder(List<E> tree, Consumer<E> consumer, Function<E, List<E>> setSubChildren) {
|
||||
Queue<E> queue = new LinkedList<>(tree);
|
||||
while (!queue.isEmpty()) {
|
||||
E item = queue.poll();
|
||||
consumer.accept(item);
|
||||
List<E> 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 <E> 泛型实体对象
|
||||
*/
|
||||
public static <E> void forPostOrder(List<E> tree, Consumer<E> consumer, Function<E, List<E>> setSubChildren) {
|
||||
for (E item : tree) {
|
||||
List<E> 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 <E> 泛型实体对象
|
||||
*/
|
||||
public static <E> List<E> sort(List<E> tree, Comparator<? super E> comparator, Function<E, List<E>> getChildren) {
|
||||
for (E item : tree) {
|
||||
List<E> childList = getChildren.apply(item);
|
||||
if (Objects.nonNull(childList) && !childList.isEmpty()) {
|
||||
sort(childList,comparator,getChildren);
|
||||
}
|
||||
}
|
||||
tree.sort(comparator);
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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<MenuVo> 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();
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -3,16 +3,6 @@
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zsc.edu.gateway.modules.system.repo.AuthorityRepository">
|
||||
<!-- <resultMap id="AuthorityMap" type="com.zsc.bill.modules.system.entity.Authority">-->
|
||||
<!-- <id column="id" jdbcType="BIGINT" property="id"/>-->
|
||||
<!-- <result column="name" jdbcType="VARCHAR" property="name"/>-->
|
||||
<!-- <result column="create_by" jdbcType="VARCHAR" property="createBy"/>-->
|
||||
<!-- <result column="update_by" jdbcType="VARCHAR" property="updateBy"/>-->
|
||||
<!-- <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>-->
|
||||
<!-- <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>-->
|
||||
<!-- <result column="enabled" jdbcType="BOOLEAN" property="enabled"/>-->
|
||||
<!-- <result column="remark" jdbcType="VARCHAR" property="remark"/>-->
|
||||
<!-- </resultMap>-->
|
||||
|
||||
<select id="selectAuthoritiesByRoleId" resultType="authority">
|
||||
select sa.* from sys_authority sa
|
||||
@ -21,7 +11,7 @@
|
||||
</select>
|
||||
|
||||
<select id="getAuthorityIdByName" resultType="java.lang.Long">
|
||||
select sa.id from sys_authority sa
|
||||
where sa.name=#{authName}
|
||||
select sa.id from sys_authority sa where sa.name=#{authName}
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.edu.zsc.study.repository.DeptRepository">
|
||||
<mapper namespace="com.zsc.edu.gateway.modules.system.repo.DeptRepository">
|
||||
|
||||
</mapper>
|
||||
|
@ -1,15 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zsc.edu.gateway.modules.system.repo.RoleAuthoritiesRepository">
|
||||
<!-- <resultMap id="BaseResultMap" type="com.zsc.edu.gateway.modules.system.entity.RoleAuthority">-->
|
||||
<!-- <result column="role_id" jdbcType="BIGINT" property="roleId"/>-->
|
||||
<!-- <result column="authority" jdbcType="BIGINT" property="authority"/>-->
|
||||
<!-- </resultMap>-->
|
||||
|
||||
<!-- <select id="selectByRoleId" parameterType="java.lang.Long" resultMap="BaseResultMap">-->
|
||||
<!-- select * from sys_role_authorities sra where sra.role_id = #{roleId}-->
|
||||
<!-- </select>-->
|
||||
|
||||
|
||||
|
||||
</mapper>
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zsc.edu.gateway.modules.system.mapper.RoleMapper">
|
||||
<mapper namespace="com.zsc.edu.gateway.modules.system.repo.RoleRepository">
|
||||
|
||||
</mapper>
|
||||
|
@ -1,24 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zsc.edu.gateway.modules.system.repo.UserRepository">
|
||||
<resultMap id="BaseResultMap" type="com.zsc.edu.gateway.modules.system.entity.User">
|
||||
<id column="id" jdbcType="BIGINT" property="id"/>
|
||||
<result column="username" jdbcType="VARCHAR" property="username"/>
|
||||
<result column="password" jdbcType="VARCHAR" property="password"/>
|
||||
<result column="role_id" jdbcType="BIGINT" property="roleId"/>
|
||||
<result column="dept_id" jdbcType="BIGINT" property="deptId"/>
|
||||
<result column="email" jdbcType="VARCHAR" property="email"/>
|
||||
<result column="phone" jdbcType="VARCHAR" property="phone"/>
|
||||
<result column="name" jdbcType="INTEGER" property="name"/>
|
||||
<result column="avatar" jdbcType="VARCHAR" property="avatar"/>
|
||||
<result column="address" jdbcType="VARCHAR" property="address"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="enabled" jdbcType="BIT" property="enableState"/>
|
||||
<collection property="role" ofType="com.zsc.edu.gateway.modules.system.entity.Role">
|
||||
<id column="id" jdbcType="BIGINT" property="id"/>
|
||||
<result column="name" jdbcType="VARCHAR" property="name"/>
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
|
||||
<resultMap id="BaseResultMap1" type="com.zsc.edu.gateway.modules.system.vo.UserVo">
|
||||
<id column="id" jdbcType="BIGINT" property="id"/>
|
||||
<result column="username" jdbcType="VARCHAR" property="username"/>
|
||||
@ -35,19 +19,21 @@
|
||||
id, username, password, email, phone, create_time
|
||||
</sql>
|
||||
|
||||
<select id="selectByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
|
||||
<select id="selectByUsername" parameterType="java.lang.String" resultMap="BaseResultMap1">
|
||||
select
|
||||
*
|
||||
from sys_user
|
||||
left join study.sys_role sr on sys_user.role_id = sr.id
|
||||
where username = #{username,jdbcType=VARCHAR}
|
||||
</select>
|
||||
|
||||
<select id="page" resultType="com.zsc.edu.gateway.modules.system.vo.UserVo" resultMap="BaseResultMap1">
|
||||
select
|
||||
*
|
||||
from sys_user
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
<select id="detail" resultType="com.zsc.edu.gateway.modules.system.vo.UserVo" resultMap="BaseResultMap1">
|
||||
select
|
||||
*
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.zsc.edu.gateway.modules.system.service.impl;
|
||||
|
||||
import com.zsc.edu.gateway.modules.system.entity.Menu;
|
||||
import com.zsc.edu.gateway.modules.system.service.MenuService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
class MenuServiceImplTest {
|
||||
|
||||
@Autowired
|
||||
private MenuService menuService;
|
||||
|
||||
@Test
|
||||
public void insertRootMenu() {
|
||||
Menu dashboard = new Menu(null, "Dashboard", "/dashboard", "dashboard", "icon-dashboard", true, false, 1, "*");
|
||||
Menu system = new Menu(null, "System", "/system", "menu.system", "icon-computer", true, false, 2, "*");
|
||||
Menu user = new Menu(null, "User", "/user", "menu.user", "icon-user", true, false, 3, "*");
|
||||
Menu message = new Menu(null, "Message", "/message", "消息管理", "icon-message", true, false, 4, "*");
|
||||
menuService.saveBatch(List.of(dashboard, system, user, message));
|
||||
Menu workplace = new Menu(dashboard.getId(), "Workplace", "workplace", "工作台", "icon-dashboard", true, false, 1, "*");
|
||||
Menu role = new Menu(system.getId(), "Role", "role", "角色管理", null, true, false, 1, "*");
|
||||
Menu dept = new Menu(system.getId(), "Dept", "dept", "部门管理", null, true, false, 2, "*");
|
||||
Menu users = new Menu(system.getId(), "User", "user", "用户管理", null, true, false, 3, "*");
|
||||
Menu authority = new Menu(system.getId(), "Authority", "authority", "权限管理", null, true, false, 4, "*");
|
||||
Menu menu = new Menu(system.getId(), "Menu", "menu", "菜单管理", null, true, false, 5, "*");
|
||||
Menu notice = new Menu(message.getId(), "Notice", "notice", "通知管理", null, true, false, 1, "*");
|
||||
Menu bulletin = new Menu(message.getId(), "Bulletin", "bulletin", "公告管理", null, true, false, 2, "*");
|
||||
menuService.saveBatch(List.of(workplace, role, dept, users, authority, menu, notice, bulletin));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user