用户完善,缺查询用户列表
This commit is contained in:
@@ -5,6 +5,7 @@ import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.dc.dc_project.utils.PermissionUtils;
|
||||
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.util.Arrays;
|
||||
@@ -18,56 +19,50 @@ public class CheckPermission implements SaAnnotationHandlerInterface<DcCheckPerm
|
||||
|
||||
@Override
|
||||
public void checkMethod(DcCheckPermission dcCheckPermission, AnnotatedElement annotatedElement) {
|
||||
|
||||
// 获取需要校验的权限数组
|
||||
String[] requiredPermissions = dcCheckPermission.value();
|
||||
|
||||
// 如果没有配置权限,直接通过
|
||||
if (requiredPermissions == null || requiredPermissions.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前用户拥有的权限列表
|
||||
List<String> userPermissions = StpUtil.getPermissionList();
|
||||
userPermissions = userPermissions.stream().map(permission -> {
|
||||
int index = permission.indexOf('_');
|
||||
return index != -1 ? permission.substring(0, index) : permission;
|
||||
}).toList();
|
||||
|
||||
// 如果用户没有任何权限,直接抛出异常
|
||||
if (userPermissions == null || userPermissions.isEmpty()) {
|
||||
throw new SaTokenException("无权限访问:" + Arrays.toString(requiredPermissions));
|
||||
}
|
||||
|
||||
// 检查是否满足任意一个权限(支持前缀匹配)
|
||||
Integer maxDataScopeLevel = null;
|
||||
|
||||
// 遍历需要的权限
|
||||
for (String requiredPermission : requiredPermissions) {
|
||||
if (hasPermission(userPermissions, requiredPermission)) {
|
||||
// 只要满足一个权限即可通过
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 所有权限都不满足,抛出异常
|
||||
throw new SaTokenException("无权限访问:" + Arrays.toString(requiredPermissions));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private boolean hasPermission(List<String> userPermissions, String requiredPermission) {
|
||||
// 遍历用户拥有的权限
|
||||
for (String userPermission : userPermissions) {
|
||||
// 1. 精确匹配:用户权限完全等于需要的权限
|
||||
if (userPermission.equals(requiredPermission)) {
|
||||
return true;
|
||||
}
|
||||
// 提取用户权限的纯权限码和数据级别
|
||||
String userPermCode = PermissionUtils.removeLevel(userPermission);
|
||||
Integer userDataLevel = PermissionUtils.extractLevel(userPermission);
|
||||
|
||||
// 2. 前缀匹配:用户权限是需要权限的前缀
|
||||
// 例如:用户有 "system",需要 "system:user",则通过
|
||||
// 例如:用户有 "system:user",需要 "system:user:list",则通过
|
||||
if (requiredPermission.startsWith(userPermission + ":")) {
|
||||
return true;
|
||||
// 1. 精确匹配
|
||||
if (userPermCode.equals(requiredPermission)) {
|
||||
if (maxDataScopeLevel == null || userDataLevel > maxDataScopeLevel) {
|
||||
maxDataScopeLevel = userDataLevel;
|
||||
}
|
||||
}
|
||||
// 2. 前缀匹配
|
||||
else if (requiredPermission.startsWith(userPermCode + ":")) {
|
||||
if (maxDataScopeLevel == null || userDataLevel > maxDataScopeLevel) {
|
||||
maxDataScopeLevel = userDataLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if (maxDataScopeLevel == null) {
|
||||
throw new SaTokenException("无权限访问:" + Arrays.toString(requiredPermissions));
|
||||
}
|
||||
|
||||
// 将数据权限级别存入 ThreadLocal
|
||||
PermissionUtils.set(maxDataScopeLevel);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public enum DataScopeType {
|
||||
|
||||
ALL("SELF_ONLY", "仅限用户自己所属组织", 3),
|
||||
CUSTOM("SELF_ONLY", "仅限用户自己所属组织", 1),
|
||||
SELF("SELF_AND_DESCENDANTS", "用户自己所属组织及其所有子孙组织", 2),
|
||||
CUSTOM("ALL_COMPANY ", "全公司所有组织", 1);
|
||||
ALL("ALL_COMPANY ", "全公司所有组织", 3);
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
@@ -59,4 +59,13 @@ public enum DataScopeType {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DataScopeType getByLevel(Integer level) {
|
||||
for (DataScopeType value : DataScopeType.values()) {
|
||||
if (value.getLevel().equals(level)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.dc.dc_project.mapper;
|
||||
import com.dc.dc_project.model.pojo.Org;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ADMIN
|
||||
* @description 针对表【sys_org(组织架构表(公司/项目部/试验室))】的数据库操作Mapper
|
||||
@@ -12,6 +14,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
public interface OrgMapper extends BaseMapper<Org> {
|
||||
|
||||
Long getOrgIdByPersonnelId(Long id);
|
||||
|
||||
List<Long> getCListByOrgId(Long pOrgId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package com.dc.dc_project.mapper;
|
||||
|
||||
import com.dc.dc_project.model.dto.user.LoginDto;
|
||||
import com.dc.dc_project.model.dto.user.UserReqDto;
|
||||
import com.dc.dc_project.model.pojo.User;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.dc.dc_project.model.vo.UserVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ADMIN
|
||||
@@ -12,6 +17,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
*/
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
|
||||
List<UserVo> getUserListBySelf(@Param("userReqDto") UserReqDto userReqDto,@Param("pOrgId") Long pOrgId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,6 +51,12 @@ public class Personnel {
|
||||
@TableField(value = "email")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 性别(0=男,1=女)
|
||||
*/
|
||||
@TableField(value = "sex")
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 主要负责(自由文本,如 混凝土试验、材料检测)
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.dc.dc_project.model.vo;
|
||||
|
||||
import com.dc.dc_project.model.pojo.Role;
|
||||
import com.dc.dc_project.model.pojo.User;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
@@ -19,6 +21,8 @@ public class UserVo {
|
||||
*/
|
||||
private String username;
|
||||
|
||||
private Long personnelId;
|
||||
|
||||
/**
|
||||
* 真实姓名
|
||||
*/
|
||||
@@ -27,7 +31,7 @@ public class UserVo {
|
||||
/**
|
||||
* 性别(0=未知,1=男,2=女)
|
||||
*/
|
||||
private Integer gender;
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
@@ -48,6 +52,8 @@ public class UserVo {
|
||||
*/
|
||||
private String orgName;
|
||||
|
||||
private List<Role> roles;
|
||||
|
||||
/**
|
||||
* 账户状态(0=停用,1=启用)
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,9 @@ import com.dc.dc_project.model.dto.OrgDto;
|
||||
import com.dc.dc_project.model.pojo.Org;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ADMIN
|
||||
* @description 针对表【sys_org(组织架构表(公司/项目部/试验室))】的数据库操作Service
|
||||
@@ -18,4 +21,11 @@ public interface OrgService extends IService<Org> {
|
||||
* @return
|
||||
*/
|
||||
ResponseResult newOrg(OrgDto orgDto);
|
||||
|
||||
/**
|
||||
* 获取组织及子组织列表
|
||||
* @param pOrgId
|
||||
* @return
|
||||
*/
|
||||
List<Long> getCListByOrgId(Long pOrgId);
|
||||
}
|
||||
|
||||
@@ -10,4 +10,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
*/
|
||||
public interface PersonnelService extends IService<Personnel> {
|
||||
|
||||
/**
|
||||
* 根据用户id获取人员信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Personnel getOneByUserId(Long userId);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.dc.dc_project.mapper.OrgMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -61,6 +62,11 @@ public class OrgServiceImpl extends ServiceImpl<OrgMapper, Org>
|
||||
}
|
||||
return ResponseResult.success("添加成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getCListByOrgId(Long pOrgId) {
|
||||
List< Long> cList = baseMapper.getCListByOrgId(pOrgId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dc.dc_project.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.dc.dc_project.model.pojo.Personnel;
|
||||
import com.dc.dc_project.service.PersonnelService;
|
||||
@@ -17,6 +18,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class PersonnelServiceImpl extends ServiceImpl<PersonnelMapper, Personnel>
|
||||
implements PersonnelService{
|
||||
|
||||
@Override
|
||||
public Personnel getOneByUserId(Long userId) {
|
||||
LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<Personnel>()
|
||||
.eq(Personnel::getUserId, userId)
|
||||
.eq(Personnel::getIsDeleted, 0);
|
||||
return this.getOne(queryWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.dc.dc_project.common.ResponseResult;
|
||||
import com.dc.dc_project.common.ResultCode;
|
||||
import com.dc.dc_project.enums.DataScopeType;
|
||||
import com.dc.dc_project.mapper.*;
|
||||
import com.dc.dc_project.model.dto.user.LoginDto;
|
||||
import com.dc.dc_project.model.dto.user.UserReqDto;
|
||||
@@ -12,14 +13,18 @@ import com.dc.dc_project.model.pojo.*;
|
||||
import com.dc.dc_project.model.vo.PersonnelVo;
|
||||
import com.dc.dc_project.model.vo.PositionVo;
|
||||
import com.dc.dc_project.model.vo.UserInfoVo;
|
||||
import com.dc.dc_project.model.vo.UserVo;
|
||||
import com.dc.dc_project.service.OrgService;
|
||||
import com.dc.dc_project.service.PermissionService;
|
||||
import com.dc.dc_project.service.PersonnelService;
|
||||
import com.dc.dc_project.service.UserService;
|
||||
import com.dc.dc_project.utils.PermissionUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -42,6 +47,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
||||
private final RoleMapper roleMapper;
|
||||
private final PositionMapper positionMapper;
|
||||
private final PermissionService permissionService;
|
||||
private final OrgService orgService;
|
||||
|
||||
@Override
|
||||
public ResponseResult login(LoginDto loginDto) {
|
||||
@@ -101,8 +107,36 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
||||
|
||||
@Override
|
||||
public ResponseResult UserList(UserReqDto userReqDto, Long userId) {
|
||||
int level = PermissionUtils.getOrDefault(DataScopeType.CUSTOM.getLevel());
|
||||
DataScopeType dataScopeType = DataScopeType.getByLevel(level);
|
||||
|
||||
Personnel personnel = personnelService.getOneByUserId(userId);
|
||||
Long pOrgId = orgMapper.getOrgIdByPersonnelId(personnel.getId());
|
||||
|
||||
List<Long> orgIds = new ArrayList<>();
|
||||
|
||||
List<UserVo> userVos = new ArrayList<>();
|
||||
|
||||
if (dataScopeType != null) {
|
||||
switch (dataScopeType){
|
||||
case DataScopeType.SELF:
|
||||
orgIds.addAll(orgService.getCListByOrgId(pOrgId));
|
||||
break;
|
||||
case DataScopeType.ALL :
|
||||
userVos = baseMapper.getUserListByAll(userReqDto);
|
||||
break;
|
||||
default:
|
||||
if(userReqDto.getOrgId() != null && !userReqDto.getOrgId().equals(pOrgId)){
|
||||
return ResponseResult.error(ResultCode.NO_PERMISSION);
|
||||
}
|
||||
userVos = baseMapper.getUserListByCustom(userReqDto, pOrgId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return ResponseResult.error(ResultCode.FAILURE);
|
||||
}
|
||||
|
||||
userVos = baseMapper.getUserListByAll(userReqDto, orgIds);
|
||||
|
||||
|
||||
return null;
|
||||
|
||||
86
src/main/java/com/dc/dc_project/utils/PermissionUtils.java
Normal file
86
src/main/java/com/dc/dc_project/utils/PermissionUtils.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package com.dc.dc_project.utils;
|
||||
|
||||
public class PermissionUtils {
|
||||
|
||||
private static final ThreadLocal<Integer> DATA_SCOPE_LEVEL = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 设置当前请求的数据权限级别
|
||||
*/
|
||||
public static void set(Integer level) {
|
||||
DATA_SCOPE_LEVEL.set(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的数据权限级别
|
||||
*/
|
||||
public static Integer get() {
|
||||
return DATA_SCOPE_LEVEL.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的数据权限级别(如果没有则返回默认值 0 - 只能查看自己的数据)
|
||||
*/
|
||||
public static Integer getOrDefault(Integer defaultLevel) {
|
||||
Integer level = DATA_SCOPE_LEVEL.get();
|
||||
return level != null ? level : defaultLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除当前请求的数据权限级别
|
||||
*/
|
||||
public static void clear() {
|
||||
DATA_SCOPE_LEVEL.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从权限字符串中提取数据权限级别
|
||||
*
|
||||
* @param permission 权限字符串,如 "system:user:edit_3"
|
||||
* @return 数据权限级别,如果没有后缀则返回 Integer.MAX_VALUE(最高级别)
|
||||
*/
|
||||
public static Integer extractLevel(String permission) {
|
||||
if (permission == null || permission.isEmpty()) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
int lastUnderscoreIndex = permission.lastIndexOf('_');
|
||||
|
||||
if (lastUnderscoreIndex > 0 && lastUnderscoreIndex < permission.length() - 1) {
|
||||
String levelStr = permission.substring(lastUnderscoreIndex + 1);
|
||||
try {
|
||||
return Integer.parseInt(levelStr);
|
||||
} catch (NumberFormatException e) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从权限字符串中移除数据权限级别后缀
|
||||
*
|
||||
* @param permission 权限字符串,如 "system:user:edit_3"
|
||||
* @return 纯权限码,如 "system:user:edit"
|
||||
*/
|
||||
public static String removeLevel(String permission) {
|
||||
if (permission == null || permission.isEmpty()) {
|
||||
return permission;
|
||||
}
|
||||
|
||||
int lastUnderscoreIndex = permission.lastIndexOf('_');
|
||||
|
||||
if (lastUnderscoreIndex > 0 && lastUnderscoreIndex < permission.length() - 1) {
|
||||
String levelStr = permission.substring(lastUnderscoreIndex + 1);
|
||||
try {
|
||||
Integer.parseInt(levelStr);
|
||||
return permission.substring(0, lastUnderscoreIndex);
|
||||
} catch (NumberFormatException e) {
|
||||
return permission;
|
||||
}
|
||||
}
|
||||
|
||||
return permission;
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,7 @@
|
||||
<select id="getOrgIdByPersonnelId" resultType="java.lang.Long">
|
||||
select so.id from sys_org so where id == (select org_id from sys_personnel_org where personnel_id=#{personnelId})
|
||||
</select>
|
||||
<select id="getCListByOrgId" resultType="java.lang.Long">
|
||||
select id from sys_org where parent_id=#{orgId}
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -26,4 +26,41 @@
|
||||
email,org_id,status,last_login_time,remark,
|
||||
created_at,updated_at,is_deleted
|
||||
</sql>
|
||||
<select id="getUserListBySelf" resultType="com.dc.dc_project.model.vo.UserVo">
|
||||
SELECT
|
||||
u.id,
|
||||
u.username,
|
||||
p.name as real_name,
|
||||
p.sex,
|
||||
u.phone,
|
||||
p.email,
|
||||
o.id as org_id,
|
||||
u.status,
|
||||
u.last_login_time,
|
||||
u.remark,
|
||||
p.id AS personnel_id,
|
||||
o.name AS org_name
|
||||
FROM sys_user u
|
||||
LEFT JOIN sys_personnel_org spo ON u.id = spo.user_id
|
||||
LEFT JOIN sys_org o ON spo.org_id = o.id
|
||||
LEFT JOIN sys_personnel p ON u.id = p.user_id
|
||||
<where>
|
||||
<if test="userReqDto.name != null">
|
||||
AND (p.name LIKE CONCAT('%',#{userReqDto.name},'%') OR u.username LIKE CONCAT('%',#{userReqDto.name},'%'))
|
||||
</if>
|
||||
<if test="userReqDto.phone != null">
|
||||
AND u.phone LIKE CONCAT('%',#{userReqDto.phone},'%')
|
||||
</if>
|
||||
<if test="userReqDto.email != null">
|
||||
AND p.email LIKE CONCAT('%',#{userReqDto.email},'%')
|
||||
</if>
|
||||
<if test="userReqDto.status != null">
|
||||
AND u.status = #{userReqDto.status}
|
||||
</if>
|
||||
<if test="pOrgId != null">
|
||||
AND o.id = #{pOrgId}
|
||||
</if>
|
||||
and u.is_deleted = 0
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user