1、需求
在多层部门嵌套下,找到当前登录人所属部门并且根据权限配置显示对应的部门及人员;
详细需求:
- 部门最高5层(技术实现支持N层);
- 部门隶属于某个部门;
- 人员属于某个部门,如果部门被删除,人员需要挂在“无部门”下;
- 根据不同权限获取不同部门数据:
- 全部
- 部门及下属
- 个人权限
- 查询结果:当前登录人所属部门及部门链(完整)、部门下人员;
- 支持断档(中间部门被删除);
- 对部门进行操作时,校验用户操作是否合法(是否有权限操作人或部门);
2、直接上代码
/**
* 校验登录人是否配置了权限信息
*/
List<GetDeptListResponse> resList = null;
Integer uid = ThreadLocal.get().getUid();
if(permisson == null || permisson.getDataAuthority() == null) {
throw new ErrorException("未找到登录用户的权限配置信息", 403);
}
/**
* 查询所有部门并且虚拟出一个“无部门”
*/
List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>());
//虚出一个"无部门"
Department noDept = new Department();
noDept.setName("无部门");
noDept.setParentId(SUPER_DEPT_ID);
noDept.setPLevel(1);
noDept.setId(NO_DEPT_ID);
allDeptList.add(noDept);
/**
* 根据不同权限,调用不同的方法
*/
Integer authority = permisson.getDataAuthority();
Department deptModel = null;
if(Constant.AUTH_ALL == authority.intValue()) {
return bulidChildrenNode(allDeptList,deptModel,authority.intValue());
}
//获取本级部门
deptModel = departmentMapper.getDepartMentByUid(uid);
if(deptModel ==null) {
//查不到所属部门,归到无部门
deptModel = noDept;
}
//转换本级及下级部门
List<GetDeptListResponse> childList = bulidChildrenNode(allDeptList,deptModel,authority.intValue());
//拼装上级部门
resList = buildAllNode(allDeptList,deptModel,childList,Constant.AUTH_DEPT_CHILD == authority.intValue());
return resList;
/**
* 查询子部门(根据不同权限,往下查)
* @param list 所有部门
* @param dept 用户所属部门
* @param authority 用户权限
* @return
*/
public List<GetDeptListResponse> bulidChildrenNode(List<Department> list,Department dept,int authority) {
List<GetDeptListResponse> finalNode = new ArrayList<>();
if(Constant.AUTH_ALL == authority) {
for(Department node : list) {
if(node.getParentId() == SUPER_DEPT_ID) {
finalNode.add(selectDeptChildren(new GetDeptListResponse(node),list));
}
}
}else if(Constant.AUTH_DEPT_CHILD == authority) {
GetDeptListResponse deptRes = selectDeptChildren(new GetDeptListResponse(dept),list);
finalNode.add(deptRes);
}else {
//个人权限
GetDeptListResponse deptRes = new GetDeptListResponse(dept);
deptRes.setIsDisabled(0);
OaUser oaUser = oaUserService.getUser(AuthUtil.get().getPhone());
GetDeptListResponse user =new GetDeptListResponse(oaUser);
finalNode.add(user);
}
return finalNode;
}
/**
* 获取部门权限(往下查)
* @param pDept 本级部门,逐级递减
* @param list 所有部门
* @return
*/
private GetDeptListResponse selectDeptChildren(GetDeptListResponse pDept, List<Department> list) {
for(Department it : list) {
if(pDept.getId() == it.getParentId()) {
GetDeptListResponse itemDeptInfo = new GetDeptListResponse(it);
pDept.getChildren().add(selectDeptChildren(itemDeptInfo,list));
}
}
if(pDept.getType() == 1) {
addDeptUser(pDept);
}
return pDept;
}
/**
* 拼装完整部门链(往上查)
* @param list 所有部门
* @param own 本级部门
* @param childList 本级及下级部门
* @param isDeptAuth 是否是部门权限
*/
public List<GetDeptListResponse> buildAllNode(List<Department> list,Department own,List<GetDeptListResponse> childList,boolean isDeptAuth){
List<GetDeptListResponse> allNode = new ArrayList<>();
if(own.getParentId() == SUPER_DEPT_ID) {
if(isDeptAuth) {
allNode.addAll(childList);
return allNode;
}
GetDeptListResponse ownDept=new GetDeptListResponse(own);
ownDept.setIsDisabled(isDeptAuth ? 1 : 0);
ownDept.setChildren(childList);
allNode.add(ownDept);
return allNode;
}
GetDeptListResponse ownDeptRes = null;
if(isDeptAuth) {
ownDeptRes = childList.get(0);
}else {
ownDeptRes = new GetDeptListResponse(own);
ownDeptRes.setIsDisabled(isDeptAuth ? 1 : 0);
ownDeptRes.setChildren(childList);
}
GetDeptListResponse allDeptRes = selectParentNode(ownDeptRes, own, list);
if(allDeptRes == null) {
//找不到顶级(中间断档)
allNode.add(ownDeptRes);
}else {
allNode.add(allDeptRes);
}
return allNode;
}
/**
* 获取部门(往上查)
* @param list 所有部门
* @param ownDeptRes 完整部门链
* @param own 本级部门,逐级递增
* @param isDeptAuth 是否是部门权限
*/
private GetDeptListResponse selectParentNode(GetDeptListResponse ownDeptRes,Department own, List<Department> list) {
for(Department it : list) {
if(own.getParentId() == it.getId()) {
GetDeptListResponse deptRes = new GetDeptListResponse(it);
deptRes.setIsDisabled(0);
deptRes.getChildren().add(ownDeptRes);
if(SUPER_DEPT_ID == it.getParentId()) {
return deptRes;
}else {
return selectParentNode(deptRes, it, list);
}
}
}
return null;
}
/**
* 查询部门用户并且插入到部门链
* @param pDept 当前部门
*/
private void addDeptUser(GetDeptListResponse pDept) {
List<OaUser> qaUserList = null;
if(NO_DEPT_ID == pDept.getId()) {
qaUserList = oaUserMapper.queryByUserToDepartment();
}else {
qaUserList = oaUserService.getUserByDeptId(pDept.getId());
}
if(qaUserList != null && !qaUserList.isEmpty()) {
for (OaUser oaUser : qaUserList) {
GetDeptListResponse user =new GetDeptListResponse(oaUser);
pDept.getChildren().add(user);
}
}
}
/**
* 根据权限获取可操作的成员集合(兼有check作用)
* @param deptId 要操作的部门
* @param memberId 要操作的成员
* @return 可操作的成员集合
*/
public List<Long> getUidsByAuthority(Permisson permisson, Long deptId, Long memberId) {
if(permisson == null || permisson.getDataAuthority() == null) {
throw new ErrorException("未找到登录用户的权限配置信息", 403);
}
if(Constant.AUTH_ALL == permisson.getDataAuthority().intValue()) {
if(deptId ==null && memberId ==null) {
//如果入参条件为空并且登录人是全部权限,直接返回null即可。
return null;
}
}
//支持最大查询的部门树
List<GetDeptListResponse> list = departmentService.getDeptInfoByAuthority(permisson);
List<Long> deptList = new ArrayList<>();
List<Long> uidList = new ArrayList<>();
//查出来所有可以查询的部门和用户,用来校验用户参数是否合法
selectAllNode(true,uidList,deptList, list,deptId);
if(uidList.isEmpty()) {
throw new ErrorException("没有找到符合条件的记录(error = 100003)", 404);
}
if(deptId == null && memberId == null ) {
return uidList;
}
if(memberId != null) {
if(!uidList.contains(memberId)) {
throw new ErrorException("您没有权限看该用户下的信息", 403);
}else {
//如果有权限,并且查的是单人,直接返回该用户即可。
uidList = Lists.newArrayList(memberId);
}
}
if(deptId != null) {
if(!deptList.contains(deptId)) {
throw new ErrorException("您没有权限看该部门下的信息", 403);
}else {
//如果有查看部门的权限,并且查看的部门合法,则需要遍历部门树,拿到可以查询的用户列表
uidList = new ArrayList<>();
selectAllNode(false,uidList,deptList, list, deptId);
}
}
if(uidList.isEmpty()) {
throw new ErrorException("没有找到符合条件的记录(error = 100003)", 404);
}
return uidList;
}
/**
* 查询部门树,获取可操作的成员和部门
* @param isAuth 是否有权限
* @param uidList 可操作的成员
* @param deptList 可操作的部门
* @param list 可操作的部门树
* @param deptId 要操作的部门
*/
private void selectAllNode(boolean isAuth,List<Long> uidList, List<Long> deptList, List<GetDeptListResponse> list,Long deptId) {
for (GetDeptListResponse node : list) {
if(deptId == null || node.getId() == deptId) {
isAuth = true;
}
if(node.getIsDisabled() == 1 && isAuth) {
if(node.getType() == 2 ) {
uidList.add(node.getId());
}else {
deptList.add(node.getId());
}
}
if(node.getType() == 1 && !node.getChildren().isEmpty()) {
selectAllNode(isAuth,uidList,deptList, node.getChildren(),deptId);
}
}
}
/**
* 返回Model
*/
class GetDeptListResponse {
public GetDeptListResponse() {}
public GetDeptListResponse(Department node) {
this.id = node.getId();
this.name = node.getName();
this.type = 1;
}
public GetDeptListResponse(OaUser node) {
this.children = null;
this.id = node.getUid();
this.name = node.getName();
this.type = 2;
}
@ApiModelProperty(value = "Id")
private long id;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "1是部门,2是用户")
private int type = 1;
@ApiModelProperty(value = "1可选,0不可选")
private int isDisabled = 1;
@ApiModelProperty(value = "下级部门列表")
private List<GetDeptListResponse> children =new ArrayList<>();
}