From 0f4bd88dc893e317d47c45a0d1bae8c723a3b27f Mon Sep 17 00:00:00 2001 From: lhx Date: Mon, 24 Nov 2025 18:07:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=AE=8C=E5=96=84=EF=BC=8C?= =?UTF-8?q?=E7=BC=BA=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/aop/CheckPermission.java | 61 ++++++------- .../dc/dc_project/enums/DataScopeType.java | 13 ++- .../com/dc/dc_project/mapper/OrgMapper.java | 4 + .../com/dc/dc_project/mapper/UserMapper.java | 6 ++ .../dc/dc_project/model/pojo/Personnel.java | 6 ++ .../com/dc/dc_project/model/vo/UserVo.java | 8 +- .../com/dc/dc_project/service/OrgService.java | 10 +++ .../dc_project/service/PersonnelService.java | 6 ++ .../service/impl/OrgServiceImpl.java | 6 ++ .../service/impl/PersonnelServiceImpl.java | 8 ++ .../service/impl/UserServiceImpl.java | 34 ++++++++ .../dc/dc_project/utils/PermissionUtils.java | 86 +++++++++++++++++++ src/main/resources/mapper/OrgMapper.xml | 3 + src/main/resources/mapper/UserMapper.xml | 37 ++++++++ 14 files changed, 252 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/dc/dc_project/utils/PermissionUtils.java diff --git a/src/main/java/com/dc/dc_project/common/aop/CheckPermission.java b/src/main/java/com/dc/dc_project/common/aop/CheckPermission.java index 43f72e9..d29b81f 100644 --- a/src/main/java/com/dc/dc_project/common/aop/CheckPermission.java +++ b/src/main/java/com/dc/dc_project/common/aop/CheckPermission.java @@ -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 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; + // 遍历用户拥有的权限 + for (String userPermission : userPermissions) { + // 提取用户权限的纯权限码和数据级别 + String userPermCode = PermissionUtils.removeLevel(userPermission); + Integer userDataLevel = PermissionUtils.extractLevel(userPermission); + + // 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; + } + } } } - // 所有权限都不满足,抛出异常 - throw new SaTokenException("无权限访问:" + Arrays.toString(requiredPermissions)); - - - } - - private boolean hasPermission(List userPermissions, String requiredPermission) { - for (String userPermission : userPermissions) { - // 1. 精确匹配:用户权限完全等于需要的权限 - if (userPermission.equals(requiredPermission)) { - return true; - } - - // 2. 前缀匹配:用户权限是需要权限的前缀 - // 例如:用户有 "system",需要 "system:user",则通过 - // 例如:用户有 "system:user",需要 "system:user:list",则通过 - if (requiredPermission.startsWith(userPermission + ":")) { - return true; - } + if (maxDataScopeLevel == null) { + throw new SaTokenException("无权限访问:" + Arrays.toString(requiredPermissions)); } - return false; + // 将数据权限级别存入 ThreadLocal + PermissionUtils.set(maxDataScopeLevel); } + + } diff --git a/src/main/java/com/dc/dc_project/enums/DataScopeType.java b/src/main/java/com/dc/dc_project/enums/DataScopeType.java index 3a67505..56ecc00 100644 --- a/src/main/java/com/dc/dc_project/enums/DataScopeType.java +++ b/src/main/java/com/dc/dc_project/enums/DataScopeType.java @@ -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; + } } diff --git a/src/main/java/com/dc/dc_project/mapper/OrgMapper.java b/src/main/java/com/dc/dc_project/mapper/OrgMapper.java index 1272408..84a1774 100644 --- a/src/main/java/com/dc/dc_project/mapper/OrgMapper.java +++ b/src/main/java/com/dc/dc_project/mapper/OrgMapper.java @@ -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 { Long getOrgIdByPersonnelId(Long id); + + List getCListByOrgId(Long pOrgId); } diff --git a/src/main/java/com/dc/dc_project/mapper/UserMapper.java b/src/main/java/com/dc/dc_project/mapper/UserMapper.java index 894ea26..2b5ee1d 100644 --- a/src/main/java/com/dc/dc_project/mapper/UserMapper.java +++ b/src/main/java/com/dc/dc_project/mapper/UserMapper.java @@ -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 { + List getUserListBySelf(@Param("userReqDto") UserReqDto userReqDto,@Param("pOrgId") Long pOrgId); } diff --git a/src/main/java/com/dc/dc_project/model/pojo/Personnel.java b/src/main/java/com/dc/dc_project/model/pojo/Personnel.java index cb1e88c..d9c2994 100644 --- a/src/main/java/com/dc/dc_project/model/pojo/Personnel.java +++ b/src/main/java/com/dc/dc_project/model/pojo/Personnel.java @@ -51,6 +51,12 @@ public class Personnel { @TableField(value = "email") private String email; + /** + * 性别(0=男,1=女) + */ + @TableField(value = "sex") + private Integer sex; + /** * 主要负责(自由文本,如 混凝土试验、材料检测) */ diff --git a/src/main/java/com/dc/dc_project/model/vo/UserVo.java b/src/main/java/com/dc/dc_project/model/vo/UserVo.java index b599051..cc2f821 100644 --- a/src/main/java/com/dc/dc_project/model/vo/UserVo.java +++ b/src/main/java/com/dc/dc_project/model/vo/UserVo.java @@ -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 roles; + /** * 账户状态(0=停用,1=启用) */ diff --git a/src/main/java/com/dc/dc_project/service/OrgService.java b/src/main/java/com/dc/dc_project/service/OrgService.java index 01e420f..b7b1ac8 100644 --- a/src/main/java/com/dc/dc_project/service/OrgService.java +++ b/src/main/java/com/dc/dc_project/service/OrgService.java @@ -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 { * @return */ ResponseResult newOrg(OrgDto orgDto); + + /** + * 获取组织及子组织列表 + * @param pOrgId + * @return + */ + List getCListByOrgId(Long pOrgId); } diff --git a/src/main/java/com/dc/dc_project/service/PersonnelService.java b/src/main/java/com/dc/dc_project/service/PersonnelService.java index 9f30860..2adce4c 100644 --- a/src/main/java/com/dc/dc_project/service/PersonnelService.java +++ b/src/main/java/com/dc/dc_project/service/PersonnelService.java @@ -10,4 +10,10 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface PersonnelService extends IService { + /** + * 根据用户id获取人员信息 + * @param userId + * @return + */ + Personnel getOneByUserId(Long userId); } diff --git a/src/main/java/com/dc/dc_project/service/impl/OrgServiceImpl.java b/src/main/java/com/dc/dc_project/service/impl/OrgServiceImpl.java index 6b761e6..1612ac3 100644 --- a/src/main/java/com/dc/dc_project/service/impl/OrgServiceImpl.java +++ b/src/main/java/com/dc/dc_project/service/impl/OrgServiceImpl.java @@ -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 } return ResponseResult.success("添加成功"); } + + @Override + public List getCListByOrgId(Long pOrgId) { + List< Long> cList = baseMapper.getCListByOrgId(pOrgId); + } } diff --git a/src/main/java/com/dc/dc_project/service/impl/PersonnelServiceImpl.java b/src/main/java/com/dc/dc_project/service/impl/PersonnelServiceImpl.java index db3bf5c..d436f19 100644 --- a/src/main/java/com/dc/dc_project/service/impl/PersonnelServiceImpl.java +++ b/src/main/java/com/dc/dc_project/service/impl/PersonnelServiceImpl.java @@ -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 implements PersonnelService{ + @Override + public Personnel getOneByUserId(Long userId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(Personnel::getUserId, userId) + .eq(Personnel::getIsDeleted, 0); + return this.getOne(queryWrapper); + } } diff --git a/src/main/java/com/dc/dc_project/service/impl/UserServiceImpl.java b/src/main/java/com/dc/dc_project/service/impl/UserServiceImpl.java index c0412d1..a960148 100644 --- a/src/main/java/com/dc/dc_project/service/impl/UserServiceImpl.java +++ b/src/main/java/com/dc/dc_project/service/impl/UserServiceImpl.java @@ -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 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 @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 orgIds = new ArrayList<>(); + + List 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; diff --git a/src/main/java/com/dc/dc_project/utils/PermissionUtils.java b/src/main/java/com/dc/dc_project/utils/PermissionUtils.java new file mode 100644 index 0000000..52f2da4 --- /dev/null +++ b/src/main/java/com/dc/dc_project/utils/PermissionUtils.java @@ -0,0 +1,86 @@ +package com.dc.dc_project.utils; + +public class PermissionUtils { + + private static final ThreadLocal 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; + } +} \ No newline at end of file diff --git a/src/main/resources/mapper/OrgMapper.xml b/src/main/resources/mapper/OrgMapper.xml index 53813f4..0257afd 100644 --- a/src/main/resources/mapper/OrgMapper.xml +++ b/src/main/resources/mapper/OrgMapper.xml @@ -12,4 +12,7 @@ + diff --git a/src/main/resources/mapper/UserMapper.xml b/src/main/resources/mapper/UserMapper.xml index f059ca6..412108c 100644 --- a/src/main/resources/mapper/UserMapper.xml +++ b/src/main/resources/mapper/UserMapper.xml @@ -26,4 +26,41 @@ email,org_id,status,last_login_time,remark, created_at,updated_at,is_deleted +