From ab7229770695bf0b23283448448c59af65fbfdb7 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Wed, 22 Nov 2023 18:51:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ops/framework/common/utils/Requests.java | 2 +- .../controller/SystemUserController.java | 10 +- .../infra/convert/DataPermissionConvert.java | 29 ++ .../module/infra/dao/DataPermissionDAO.java | 33 ++ .../module/infra/dao/SystemUserRoleDAO.java | 16 + .../cache/DataPermissionCacheKeyDefine.java | 26 ++ .../operator/DataGroupOperatorType.java | 34 -- .../operator/DataGroupRelOperatorType.java | 34 -- .../infra/entity/domain/DataPermissionDO.java | 49 +++ .../data/DataPermissionCreateRequest.java | 40 +++ .../data/DataPermissionUpdateRequest.java | 40 +++ .../infra/service/DataPermissionService.java | 104 ++++++ .../service/SystemUserManagementService.java | 32 ++ .../infra/service/SystemUserRoleService.java | 12 +- .../infra/service/SystemUserService.java | 14 +- .../impl/AuthenticationServiceImpl.java | 10 +- .../impl/DataPermissionServiceImpl.java | 310 ++++++++++++++++++ .../infra/service/impl/MineServiceImpl.java | 8 +- .../service/impl/SystemRoleServiceImpl.java | 10 +- .../impl/SystemUserManagementServiceImpl.java | 99 ++++++ .../impl/SystemUserRoleServiceImpl.java | 26 +- .../service/impl/SystemUserServiceImpl.java | 98 ++---- .../resources/mapper/DataPermissionMapper.xml | 24 ++ 23 files changed, 902 insertions(+), 158 deletions(-) create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/DataPermissionConvert.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/DataPermissionDAO.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/cache/DataPermissionCacheKeyDefine.java delete mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupOperatorType.java delete mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupRelOperatorType.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/DataPermissionDO.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionCreateRequest.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionUpdateRequest.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/DataPermissionService.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserManagementService.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataPermissionServiceImpl.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserManagementServiceImpl.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/DataPermissionMapper.xml diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Requests.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Requests.java index f9eb64c2..778f6877 100644 --- a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Requests.java +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Requests.java @@ -20,7 +20,7 @@ public class Requests { } /** - * 填充请求信息 + * 填充请求身份信息 * * @param identity identity */ diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemUserController.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemUserController.java index 0a2e7725..7dbc814f 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemUserController.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemUserController.java @@ -12,6 +12,7 @@ import com.orion.ops.module.infra.define.operator.SystemUserOperatorType; import com.orion.ops.module.infra.entity.request.user.*; import com.orion.ops.module.infra.entity.vo.SystemUserVO; import com.orion.ops.module.infra.entity.vo.UserSessionVO; +import com.orion.ops.module.infra.service.SystemUserManagementService; import com.orion.ops.module.infra.service.SystemUserRoleService; import com.orion.ops.module.infra.service.SystemUserService; import io.swagger.v3.oas.annotations.Operation; @@ -47,6 +48,9 @@ public class SystemUserController { @Resource private SystemUserRoleService systemUserRoleService; + @Resource + private SystemUserManagementService systemUserManagementService; + @OperatorLog(SystemUserOperatorType.CREATE) @PostMapping("/create") @Operation(summary = "创建用户") @@ -118,7 +122,7 @@ public class SystemUserController { @Operation(summary = "查询用户的角色id") @PreAuthorize("@ss.hasPermission('infra:system-user:query')") public List getUserRoleIdList(@RequestParam("userId") Long userId) { - return systemUserRoleService.getUserRoleIdList(userId); + return systemUserRoleService.getRoleIdListByUserId(userId); } @IgnoreLog(IgnoreLogMode.RET) @@ -143,7 +147,7 @@ public class SystemUserController { @Operation(summary = "获取用户会话列表") @PreAuthorize("@ss.hasPermission('infra:system-user:query-session')") public List getUserSessionList(@RequestParam("id") Long id) { - return systemUserService.getUserSessionList(id); + return systemUserManagementService.getUserSessionList(id); } @OperatorLog(SystemUserOperatorType.OFFLINE) @@ -151,7 +155,7 @@ public class SystemUserController { @Operation(summary = "下线用户会话") @PreAuthorize("@ss.hasPermission('infra:system-user:offline-session')") public HttpWrapper offlineUserSession(@Validated @RequestBody UserSessionOfflineRequest request) { - systemUserService.offlineUserSession(request); + systemUserManagementService.offlineUserSession(request); return HttpWrapper.ok(); } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/DataPermissionConvert.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/DataPermissionConvert.java new file mode 100644 index 00000000..b3ba10c9 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/DataPermissionConvert.java @@ -0,0 +1,29 @@ +package com.orion.ops.module.infra.convert; + +import com.orion.ops.module.infra.entity.domain.*; +import com.orion.ops.module.infra.entity.vo.*; +import com.orion.ops.module.infra.entity.request.data.*; +import com.orion.ops.module.infra.convert.*; +import com.orion.ops.module.infra.define.operator.*; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 数据权限 内部对象转换器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-11-21 10:32 + */ +@Mapper +public interface DataPermissionConvert { + + DataPermissionConvert MAPPER = Mappers.getMapper(DataPermissionConvert.class); + + DataPermissionDO to(DataPermissionCreateRequest request); + + DataPermissionDO to(DataPermissionUpdateRequest request); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/DataPermissionDAO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/DataPermissionDAO.java new file mode 100644 index 00000000..82b9ec5d --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/DataPermissionDAO.java @@ -0,0 +1,33 @@ +package com.orion.ops.module.infra.dao; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.orion.ops.framework.mybatis.core.mapper.IMapper; +import com.orion.ops.module.infra.entity.domain.DataPermissionDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 数据权限 Mapper 接口 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-11-21 10:32 + */ +@Mapper +public interface DataPermissionDAO extends IMapper { + + /** + * 获取查询条件 + * + * @param entity entity + * @return 查询条件 + */ + default LambdaQueryWrapper queryCondition(DataPermissionDO entity) { + return this.wrapper() + .eq(DataPermissionDO::getId, entity.getId()) + .eq(DataPermissionDO::getUserId, entity.getUserId()) + .eq(DataPermissionDO::getRoleId, entity.getRoleId()) + .eq(DataPermissionDO::getRelId, entity.getRelId()) + .eq(DataPermissionDO::getType, entity.getType()); + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemUserRoleDAO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemUserRoleDAO.java index f7e5420d..d69dacd6 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemUserRoleDAO.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemUserRoleDAO.java @@ -48,6 +48,22 @@ public interface SystemUserRoleDAO extends IMapper { .collect(Collectors.toList()); } + /** + * 查询角色的全部 userId + * + * @param roleId roleId + * @return userId + */ + default List selectUserIdByRoleId(List roleId) { + LambdaQueryWrapper wrapper = this.wrapper() + .select(SystemUserRoleDO::getUserId) + .in(SystemUserRoleDO::getRoleId, roleId); + return this.selectList(wrapper).stream() + .map(SystemUserRoleDO::getUserId) + .distinct() + .collect(Collectors.toList()); + } + /** * 通过 userId 删除 * diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/cache/DataPermissionCacheKeyDefine.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/cache/DataPermissionCacheKeyDefine.java new file mode 100644 index 00000000..66289825 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/cache/DataPermissionCacheKeyDefine.java @@ -0,0 +1,26 @@ +package com.orion.ops.module.infra.define.cache; + +import com.orion.lang.define.cache.key.CacheKeyBuilder; +import com.orion.lang.define.cache.key.CacheKeyDefine; +import com.orion.lang.define.cache.key.struct.RedisCacheStruct; + +import java.util.concurrent.TimeUnit; + +/** + * 数据权限缓存 key + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/11/21 11:29 + */ +public interface DataPermissionCacheKeyDefine { + + CacheKeyDefine DATA_PERMISSION_USER = new CacheKeyBuilder() + .key("data:perm-user:{}:{}") + .desc("用户所有数据权限 ${type} ${userId}") + .type(Long.class) + .struct(RedisCacheStruct.LIST) + .timeout(1, TimeUnit.DAYS) + .build(); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupOperatorType.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupOperatorType.java deleted file mode 100644 index da1eff16..00000000 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupOperatorType.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.orion.ops.module.infra.define.operator; - -import com.orion.ops.framework.biz.operator.log.core.annotation.Module; -import com.orion.ops.framework.biz.operator.log.core.factory.InitializingOperatorTypes; -import com.orion.ops.framework.biz.operator.log.core.model.OperatorType; - -import static com.orion.ops.framework.biz.operator.log.core.enums.OperatorRiskLevel.*; - -/** - * 数据分组 操作日志类型 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-11-7 18:44 - */ -@Module("infra:data-group") -public class DataGroupOperatorType extends InitializingOperatorTypes { - - public static final String CREATE = "data-group:create"; - - public static final String UPDATE = "data-group:update"; - - public static final String DELETE = "data-group:delete"; - - @Override - public OperatorType[] types() { - return new OperatorType[]{ - new OperatorType(L, CREATE, "创建数据分组"), - new OperatorType(M, UPDATE, "更新数据分组"), - new OperatorType(H, DELETE, "删除数据分组"), - }; - } - -} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupRelOperatorType.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupRelOperatorType.java deleted file mode 100644 index 9e44ee8c..00000000 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/DataGroupRelOperatorType.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.orion.ops.module.infra.define.operator; - -import com.orion.ops.framework.biz.operator.log.core.annotation.Module; -import com.orion.ops.framework.biz.operator.log.core.factory.InitializingOperatorTypes; -import com.orion.ops.framework.biz.operator.log.core.model.OperatorType; - -import static com.orion.ops.framework.biz.operator.log.core.enums.OperatorRiskLevel.*; - -/** - * 数据分组关联 操作日志类型 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-11-7 18:44 - */ -@Module("infra:data-group-rel") -public class DataGroupRelOperatorType extends InitializingOperatorTypes { - - public static final String CREATE = "data-group-rel:create"; - - public static final String UPDATE = "data-group-rel:update"; - - public static final String DELETE = "data-group-rel:delete"; - - @Override - public OperatorType[] types() { - return new OperatorType[]{ - new OperatorType(L, CREATE, "创建数据分组关联"), - new OperatorType(M, UPDATE, "更新数据分组关联"), - new OperatorType(H, DELETE, "删除数据分组关联"), - }; - } - -} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/DataPermissionDO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/DataPermissionDO.java new file mode 100644 index 00000000..b8b4e6b4 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/DataPermissionDO.java @@ -0,0 +1,49 @@ +package com.orion.ops.module.infra.entity.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.orion.ops.framework.mybatis.core.domain.BaseDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.util.*; +import java.math.*; + +/** + * 数据权限 实体对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-11-21 10:32 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName(value = "data_permission", autoResultMap = true) +@Schema(name = "DataPermissionDO", description = "数据权限 实体对象") +public class DataPermissionDO extends BaseDO { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "用户id") + @TableField("user_id") + private Long userId; + + @Schema(description = "角色id") + @TableField("role_id") + private Long roleId; + + @Schema(description = "引用id") + @TableField("rel_id") + private Long relId; + + @Schema(description = "数据类型") + @TableField("type") + private String type; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionCreateRequest.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionCreateRequest.java new file mode 100644 index 00000000..3c06c3b5 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionCreateRequest.java @@ -0,0 +1,40 @@ +package com.orion.ops.module.infra.entity.request.data; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 数据权限 创建请求对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-11-21 10:32 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "DataPermissionCreateRequest", description = "数据权限 创建请求对象") +public class DataPermissionCreateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "用户id") + private Long userId; + + @Schema(description = "角色id") + private Long roleId; + + @Schema(description = "引用id") + private List relIdList; + + @Schema(description = "数据类型") + private String type; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionUpdateRequest.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionUpdateRequest.java new file mode 100644 index 00000000..9452b0b6 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/data/DataPermissionUpdateRequest.java @@ -0,0 +1,40 @@ +package com.orion.ops.module.infra.entity.request.data; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 数据权限 更新请求对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-11-21 10:32 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "DataPermissionUpdateRequest", description = "数据权限 更新请求对象") +public class DataPermissionUpdateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "用户id") + private Long userId; + + @Schema(description = "角色id") + private Long roleId; + + @Schema(description = "引用id") + private List relIdList; + + @Schema(description = "数据类型") + private String type; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/DataPermissionService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/DataPermissionService.java new file mode 100644 index 00000000..ed1e9bd8 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/DataPermissionService.java @@ -0,0 +1,104 @@ +package com.orion.ops.module.infra.service; + +import com.orion.ops.module.infra.entity.request.data.DataPermissionCreateRequest; +import com.orion.ops.module.infra.entity.request.data.DataPermissionUpdateRequest; + +import java.util.List; + +/** + * 数据权限 服务类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-11-21 10:32 + */ +public interface DataPermissionService { + + /** + * 添加数据权限 + * + * @param request request + */ + void addDataPermission(DataPermissionCreateRequest request); + + /** + * 更新数据权限 + * + * @param request request + */ + void updateDataPermission(DataPermissionUpdateRequest request); + + /** + * 通过 userId 查询 (不包含角色 不走缓存) + * + * @param type type + * @param userId userId + * @return relId + */ + List getRelIdListByUserId(String type, Long userId); + + /** + * 通过 roleId 查询 不走缓存 + * + * @param type type + * @param roleId roleId + * @return relId + */ + List getRelIdListByRoleId(String type, Long roleId); + + /** + * 通过 userId 查询 (包含角色 走缓存) + * + * @param type type + * @param userId userId + * @return relId + */ + List getAllowRelIdList(String type, Long userId); + + /** + * 通过 relId 删除 + * + * @param type type + * @param relId relId + * @return effect + */ + int deleteByRelId(String type, Long relId); + + /** + * 通过 userId 删除 + * + * @param userId userId + * @return effect + */ + int deleteByUserId(Long userId); + + /** + * 通过 roleId 删除 + * + * @param roleId roleId + * @return effect + */ + int deleteByRoleId(Long roleId); + + /** + * 清空角色缓存 + * + * @param roleId roleId + */ + void clearRoleCache(Long roleId); + + /** + * 清空用户缓存 + * + * @param userId userId + */ + void clearUserCache(Long userId); + + /** + * 清空用户缓存 + * + * @param userIdList userIdList + */ + void clearUserCache(List userIdList); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserManagementService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserManagementService.java new file mode 100644 index 00000000..d4e0fddb --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserManagementService.java @@ -0,0 +1,32 @@ +package com.orion.ops.module.infra.service; + +import com.orion.ops.module.infra.entity.request.user.UserSessionOfflineRequest; +import com.orion.ops.module.infra.entity.vo.UserSessionVO; + +import java.util.List; + +/** + * 用户管理服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/11/22 18:17 + */ +public interface SystemUserManagementService { + + /** + * 获取用户会话列表 + * + * @param userId userId + * @return 回话列表 + */ + List getUserSessionList(Long userId); + + /** + * 下线用户会话 + * + * @param request request + */ + void offlineUserSession(UserSessionOfflineRequest request); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java index 8aadf978..e8fc06f7 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java @@ -14,12 +14,20 @@ import java.util.List; public interface SystemUserRoleService { /** - * 查询用户 roleId + * 通过 userId 查询 roleId * * @param userId userId * @return roleId */ - List getUserRoleIdList(Long userId); + List getRoleIdListByUserId(Long userId); + + /** + * 通过 roleCode 查询 userId + * + * @param roleCode roleCode + * @return userId + */ + List getUserIdListByRoleCode(String roleCode); /** * 删除用户角色 diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserService.java index 373aa5be..34bdf5d7 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserService.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserService.java @@ -3,7 +3,6 @@ package com.orion.ops.module.infra.service; import com.orion.lang.define.wrapper.DataGrid; import com.orion.ops.module.infra.entity.request.user.*; import com.orion.ops.module.infra.entity.vo.SystemUserVO; -import com.orion.ops.module.infra.entity.vo.UserSessionVO; import java.util.List; @@ -87,18 +86,11 @@ public interface SystemUserService { void resetPassword(UserResetPasswordRequest request); /** - * 获取用户会话列表 + * 检测用户是否是为管理员 * * @param userId userId - * @return 回话列表 + * @return 是否为管理员 */ - List getUserSessionList(Long userId); - - /** - * 下线用户会话 - * - * @param request request - */ - void offlineUserSession(UserSessionOfflineRequest request); + boolean isAdminUser(Long userId); } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java index 6c908201..166db6b6 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java @@ -8,6 +8,7 @@ import com.orion.lang.utils.collect.Lists; import com.orion.lang.utils.crypto.Signatures; import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs; import com.orion.ops.framework.common.constant.Const; +import com.orion.ops.framework.common.constant.ErrorCode; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.security.LoginUser; import com.orion.ops.framework.common.security.UserRole; @@ -130,8 +131,13 @@ public class AuthenticationServiceImpl implements AuthenticationService { if (userInfoCache != null) { return JSON.parseObject(userInfoCache, LoginUser.class); } - // 设置缓存并返回 - return this.setUserCache(systemUserDAO.selectById(id)); + // 查询用户信息 + SystemUserDO user = systemUserDAO.selectById(id); + if (user == null) { + throw Exceptions.httpWrapper(ErrorCode.UNAUTHORIZED); + } + // 设置用户缓存 + return this.setUserCache(user); } @Override diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataPermissionServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataPermissionServiceImpl.java new file mode 100644 index 00000000..c5cd7011 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataPermissionServiceImpl.java @@ -0,0 +1,310 @@ +package com.orion.ops.module.infra.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.orion.lang.utils.collect.Lists; +import com.orion.ops.framework.mybatis.core.query.Conditions; +import com.orion.ops.framework.redis.core.utils.RedisLists; +import com.orion.ops.framework.redis.core.utils.RedisUtils; +import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers; +import com.orion.ops.module.infra.dao.DataPermissionDAO; +import com.orion.ops.module.infra.dao.SystemUserRoleDAO; +import com.orion.ops.module.infra.define.cache.DataPermissionCacheKeyDefine; +import com.orion.ops.module.infra.entity.domain.DataPermissionDO; +import com.orion.ops.module.infra.entity.request.data.DataPermissionCreateRequest; +import com.orion.ops.module.infra.entity.request.data.DataPermissionUpdateRequest; +import com.orion.ops.module.infra.service.DataPermissionService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 数据权限 服务实现类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-11-21 10:32 + */ +@Slf4j +@Service +public class DataPermissionServiceImpl implements DataPermissionService { + + @Resource + private DataPermissionDAO dataPermissionDAO; + + @Resource + private SystemUserRoleDAO systemUserRoleDAO; + + @Override + @Transactional(rollbackFor = Exception.class) + public void addDataPermission(DataPermissionCreateRequest request) { + Long userId = request.getUserId(); + Long roleId = request.getRoleId(); + String type = request.getType(); + // 查询 + LambdaQueryWrapper wrapper = dataPermissionDAO.wrapper() + .eq(DataPermissionDO::getUserId, userId) + .eq(DataPermissionDO::getRoleId, roleId) + .eq(DataPermissionDO::getType, type); + List beforeRelIdList = dataPermissionDAO.selectList(wrapper) + .stream() + .map(DataPermissionDO::getRelId) + .distinct() + .collect(Collectors.toList()); + // 新增 + List records = request.getRelIdList() + .stream() + .distinct() + .filter(s -> !beforeRelIdList.contains(s)) + .map(s -> DataPermissionDO.builder() + .type(type) + .userId(userId) + .roleId(roleId) + .relId(s) + .build()) + .collect(Collectors.toList()); + dataPermissionDAO.insertBatch(records); + // 删除缓存 + this.deleteCache(type, userId, roleId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateDataPermission(DataPermissionUpdateRequest request) { + Long userId = request.getUserId(); + Long roleId = request.getRoleId(); + String type = request.getType(); + // 删除 + if (Lists.isEmpty(request.getRelIdList())) { + LambdaQueryWrapper wrapper = dataPermissionDAO.wrapper() + .eq(DataPermissionDO::getUserId, userId) + .eq(DataPermissionDO::getRoleId, roleId) + .eq(DataPermissionDO::getType, type); + dataPermissionDAO.delete(wrapper); + return; + } + // 新增 + List records = request.getRelIdList() + .stream() + .distinct() + .map(s -> DataPermissionDO.builder() + .type(type) + .userId(userId) + .roleId(roleId) + .relId(s) + .build()) + .collect(Collectors.toList()); + dataPermissionDAO.insertBatch(records); + // 删除缓存 + this.deleteCache(type, userId, roleId); + } + + @Override + public List getRelIdListByUserId(String type, Long userId) { + return dataPermissionDAO.of() + .createWrapper() + .eq(DataPermissionDO::getType, type) + .eq(DataPermissionDO::getUserId, userId) + .then() + .stream() + .map(DataPermissionDO::getRelId) + .distinct() + .collect(Collectors.toList()); + } + + @Override + public List getRelIdListByRoleId(String type, Long roleId) { + // 查询数据库 + return dataPermissionDAO.of() + .createWrapper() + .eq(DataPermissionDO::getType, type) + .eq(DataPermissionDO::getRoleId, roleId) + .then() + .stream() + .map(DataPermissionDO::getRelId) + .distinct() + .collect(Collectors.toList()); + } + + @Override + public List getAllowRelIdList(String type, Long userId) { + String cacheKey = DataPermissionCacheKeyDefine.DATA_PERMISSION_USER.format(type, userId); + // 获取缓存 + List list = RedisLists.range(cacheKey, Long::valueOf); + if (list.isEmpty()) { + LambdaQueryWrapper wrapper = dataPermissionDAO.lambda() + .eq(DataPermissionDO::getType, type) + .eq(DataPermissionDO::getUserId, userId); + // 查询用户角色 + List roleIdList = systemUserRoleDAO.selectRoleIdByUserId(userId); + if (!roleIdList.isEmpty()) { + wrapper.or().in(DataPermissionDO::getRoleId, roleIdList); + } + // 查询数据库 + list = dataPermissionDAO.of() + .wrapper(wrapper) + .stream() + .map(DataPermissionDO::getRelId) + .distinct() + .collect(Collectors.toList()); + // 设置屏障 防止穿透 + CacheBarriers.LONG.check(list); + // 设置缓存 + RedisLists.pushAll(cacheKey, DataPermissionCacheKeyDefine.DATA_PERMISSION_USER, list, String::valueOf); + } + // 删除屏障 + CacheBarriers.LONG.remove(list); + return list.stream() + .distinct() + .collect(Collectors.toList()); + } + + @Override + public int deleteByRelId(String type, Long relId) { + LambdaQueryWrapper wrapper = dataPermissionDAO.wrapper() + .eq(DataPermissionDO::getType, type) + .eq(DataPermissionDO::getRelId, relId); + // 查询 + List rows = dataPermissionDAO.selectList(wrapper); + // 删除 + int effect = dataPermissionDAO.delete(wrapper); + // 删除缓存 + Function, List> mapper = + f -> rows.stream() + .map(f) + .distinct() + .filter(Objects::nonNull) + .collect(Collectors.toList()); + List userIdList = mapper.apply(DataPermissionDO::getUserId); + List roleIdList = mapper.apply(DataPermissionDO::getRoleId); + this.deleteCache(Lists.singleton(type), userIdList, roleIdList); + return effect; + } + + @Override + public int deleteByUserId(Long userId) { + LambdaQueryWrapper wrapper = Conditions.eq(DataPermissionDO::getUserId, userId); + // 查询 + List typeList = dataPermissionDAO.of() + .wrapper(wrapper) + .stream() + .map(DataPermissionDO::getType) + .distinct() + .collect(Collectors.toList()); + // 删除 + int effect = dataPermissionDAO.delete(wrapper); + // 删除缓存 + this.deleteCache(typeList, Lists.singleton(userId), null); + return effect; + } + + @Override + public int deleteByRoleId(Long roleId) { + LambdaQueryWrapper wrapper = Conditions.eq(DataPermissionDO::getRoleId, roleId); + // 查询 + List typeList = dataPermissionDAO.of() + .wrapper(wrapper) + .stream() + .map(DataPermissionDO::getType) + .distinct() + .collect(Collectors.toList()); + // 删除 + int effect = dataPermissionDAO.delete(wrapper); + // 删除缓存 + this.deleteCache(typeList, null, Lists.singleton(roleId)); + return effect; + } + + @Override + public void clearRoleCache(Long roleId) { + // 查询角色下的用户 + List userIdList = systemUserRoleDAO.selectUserIdByRoleId(roleId); + if (userIdList.isEmpty()) { + return; + } + this.clearUserCache(userIdList); + } + + @Override + public void clearUserCache(Long userId) { + this.clearUserCache(Lists.singleton(userId)); + } + + @Override + public void clearUserCache(List userIdList) { + // 构建 key 匹配 + List keyPatterns = userIdList.stream() + .distinct() + .map(s -> DataPermissionCacheKeyDefine.DATA_PERMISSION_USER.format("*", s)) + .collect(Collectors.toList()); + // 扫描所有 key + List deleteKeys = keyPatterns.stream() + .map(RedisUtils::scanKeys) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + // 删除 key + if (!deleteKeys.isEmpty()) { + RedisUtils.delete(deleteKeys); + } + } + + /** + * 删除缓存 + * + * @param type type + * @param userId userId + * @param roleId roleId + */ + private void deleteCache(String type, Long userId, Long roleId) { + List userIdList = new ArrayList<>(); + if (userId != null) { + userIdList.add(userId); + } + // 查询角色的权限 + List roleUserIdList = systemUserRoleDAO.selectUserIdByRoleId(roleId); + userIdList.addAll(roleUserIdList); + // 删除缓存 + if (!userIdList.isEmpty()) { + List keys = userIdList.stream() + .map(s -> DataPermissionCacheKeyDefine.DATA_PERMISSION_USER.format(type, s)) + .collect(Collectors.toList()); + RedisUtils.delete(keys); + } + } + + /** + * 删除缓存 + * + * @param typeList typeList + * @param userIdList userIdList + * @param roleIdList roleIdList + */ + private void deleteCache(List typeList, List userIdList, List roleIdList) { + Set deleteUserIdList = new HashSet<>(4); + if (!Lists.isEmpty(userIdList)) { + deleteUserIdList.addAll(userIdList); + } + // 查询角色的用户列表 + if (!Lists.isEmpty(roleIdList)) { + List roleUserIdList = systemUserRoleDAO.selectUserIdByRoleId(roleIdList); + deleteUserIdList.addAll(roleUserIdList); + } + if (deleteUserIdList.isEmpty()) { + return; + } + // 删除缓存 + List keys = new ArrayList<>(); + for (String type : typeList) { + userIdList.stream() + .filter(Objects::nonNull) + .map(s -> DataPermissionCacheKeyDefine.DATA_PERMISSION_USER.format(type, s)) + .forEach(keys::add); + } + RedisLists.delete(keys); + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/MineServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/MineServiceImpl.java index e7a608ae..fcaafe1a 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/MineServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/MineServiceImpl.java @@ -18,6 +18,7 @@ import com.orion.ops.module.infra.entity.vo.SystemUserVO; import com.orion.ops.module.infra.entity.vo.UserSessionVO; import com.orion.ops.module.infra.service.MineService; import com.orion.ops.module.infra.service.OperatorLogService; +import com.orion.ops.module.infra.service.SystemUserManagementService; import com.orion.ops.module.infra.service.SystemUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -39,6 +40,9 @@ public class MineServiceImpl implements MineService { @Resource private SystemUserService systemUserService; + @Resource + private SystemUserManagementService systemUserManagementService; + @Resource private OperatorLogService operatorLogService; @@ -80,13 +84,13 @@ public class MineServiceImpl implements MineService { @Override public List getCurrentUserSessionList() { - return systemUserService.getUserSessionList(SecurityUtils.getLoginUserId()); + return systemUserManagementService.getUserSessionList(SecurityUtils.getLoginUserId()); } @Override public void offlineCurrentUserSession(UserSessionOfflineRequest request) { request.setUserId(SecurityUtils.getLoginUserId()); - systemUserService.offlineUserSession(request); + systemUserManagementService.offlineUserSession(request); } @Override diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java index 2d077a79..9166ff73 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java @@ -19,6 +19,7 @@ import com.orion.ops.module.infra.entity.request.role.SystemRoleStatusRequest; import com.orion.ops.module.infra.entity.request.role.SystemRoleUpdateRequest; import com.orion.ops.module.infra.entity.vo.SystemRoleVO; import com.orion.ops.module.infra.enums.RoleStatusEnum; +import com.orion.ops.module.infra.service.DataPermissionService; import com.orion.ops.module.infra.service.PermissionService; import com.orion.ops.module.infra.service.SystemRoleService; import com.orion.ops.module.infra.service.SystemUserRoleService; @@ -55,6 +56,9 @@ public class SystemRoleServiceImpl implements SystemRoleService { @Resource private SystemUserRoleService systemUserRoleService; + @Resource + private DataPermissionService dataPermissionService; + @Override public Long createSystemRole(SystemRoleCreateRequest request) { // 转换 @@ -111,9 +115,11 @@ public class SystemRoleServiceImpl implements SystemRoleService { // 更新 int effect = systemRoleDAO.updateById(updateRecord); log.info("SystemRoleService-updateRoleStatus effect: {}, updateRecord: {}", effect, JSON.toJSONString(updateRecord)); - // 修改缓存状态 + // 修改本地缓存状态 SystemRoleDO roleCache = permissionService.getRoleCache().get(id); roleCache.setStatus(status); + // 删除数据权限缓存 + dataPermissionService.clearRoleCache(id); return effect; } @@ -178,6 +184,8 @@ public class SystemRoleServiceImpl implements SystemRoleService { permissionService.getRoleMenuCache().remove(id); // 删除用户缓存中的角色 systemUserRoleService.deleteUserCacheRoleAsync(id, userIdList); + // 删除数据权限缓存 + dataPermissionService.clearUserCache(userIdList); return effect; } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserManagementServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserManagementServiceImpl.java new file mode 100644 index 00000000..2a045e24 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserManagementServiceImpl.java @@ -0,0 +1,99 @@ +package com.orion.ops.module.infra.service.impl; + +import com.orion.lang.utils.collect.Lists; +import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs; +import com.orion.ops.framework.common.constant.ErrorMessage; +import com.orion.ops.framework.common.utils.Requests; +import com.orion.ops.framework.common.utils.Valid; +import com.orion.ops.framework.redis.core.utils.RedisStrings; +import com.orion.ops.framework.security.core.utils.SecurityUtils; +import com.orion.ops.module.infra.dao.SystemUserDAO; +import com.orion.ops.module.infra.define.cache.UserCacheKeyDefine; +import com.orion.ops.module.infra.entity.domain.SystemUserDO; +import com.orion.ops.module.infra.entity.dto.LoginTokenDTO; +import com.orion.ops.module.infra.entity.dto.LoginTokenIdentityDTO; +import com.orion.ops.module.infra.entity.request.user.UserSessionOfflineRequest; +import com.orion.ops.module.infra.entity.vo.UserSessionVO; +import com.orion.ops.module.infra.enums.LoginTokenStatusEnum; +import com.orion.ops.module.infra.service.SystemUserManagementService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 用户管理 服务实现类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/11/22 18:17 + */ +@Slf4j +@Service +public class SystemUserManagementServiceImpl implements SystemUserManagementService { + + @Resource + private SystemUserDAO systemUserDAO; + + @Override + public List getUserSessionList(Long userId) { + // 扫描缓存 + Set keys = RedisStrings.scanKeys(UserCacheKeyDefine.LOGIN_TOKEN.format(userId, "*")); + if (Lists.isEmpty(keys)) { + return Lists.empty(); + } + // 查询缓存 + List tokens = RedisStrings.getJsonList(keys, UserCacheKeyDefine.LOGIN_TOKEN); + if (Lists.isEmpty(tokens)) { + return Lists.empty(); + } + final boolean isCurrentUser = userId.equals(SecurityUtils.getLoginUserId()); + // 返回 + return tokens.stream() + .filter(s -> LoginTokenStatusEnum.OK.getStatus().equals(s.getStatus())) + .map(LoginTokenDTO::getOrigin) + .map(s -> UserSessionVO.builder() + .current(isCurrentUser && s.getLoginTime().equals(SecurityUtils.getLoginTimestamp())) + .address(s.getAddress()) + .location(s.getLocation()) + .userAgent(s.getUserAgent()) + .loginTime(new Date(s.getLoginTime())) + .build()) + .sorted(Comparator.comparing(UserSessionVO::getCurrent).reversed() + .thenComparing(Comparator.comparing(UserSessionVO::getLoginTime).reversed())) + .collect(Collectors.toList()); + } + + @Override + public void offlineUserSession(UserSessionOfflineRequest request) { + Long userId = Valid.notNull(request.getUserId()); + Long timestamp = request.getTimestamp(); + log.info("SystemUserManagementService offlineUserSession userId: {}, timestamp: {}", userId, timestamp); + // 查询用户 + SystemUserDO user = systemUserDAO.selectById(userId); + Valid.notNull(user, ErrorMessage.USER_ABSENT); + // 添加日志参数 + OperatorLogs.add(OperatorLogs.USERNAME, user.getUsername()); + // 删除刷新缓存 + RedisStrings.delete(UserCacheKeyDefine.LOGIN_REFRESH.format(userId, request.getTimestamp())); + // 查询并且覆盖 token + String tokenKey = UserCacheKeyDefine.LOGIN_TOKEN.format(userId, timestamp); + LoginTokenDTO tokenInfo = RedisStrings.getJson(tokenKey, UserCacheKeyDefine.LOGIN_TOKEN); + if (tokenInfo != null) { + tokenInfo.setStatus(LoginTokenStatusEnum.SESSION_OFFLINE.getStatus()); + LoginTokenIdentityDTO override = new LoginTokenIdentityDTO(); + override.setLoginTime(System.currentTimeMillis()); + // 设置请求信息 + Requests.fillIdentity(override); + tokenInfo.setOverride(override); + // 更新 token + RedisStrings.setJson(tokenKey, UserCacheKeyDefine.LOGIN_TOKEN, tokenInfo); + } + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java index bcf79a4d..b1a04f33 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java @@ -15,6 +15,7 @@ import com.orion.ops.module.infra.entity.domain.SystemRoleDO; import com.orion.ops.module.infra.entity.domain.SystemUserDO; import com.orion.ops.module.infra.entity.domain.SystemUserRoleDO; import com.orion.ops.module.infra.entity.request.user.SystemUserUpdateRoleRequest; +import com.orion.ops.module.infra.service.DataPermissionService; import com.orion.ops.module.infra.service.SystemUserRoleService; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; @@ -45,11 +46,28 @@ public class SystemUserRoleServiceImpl implements SystemUserRoleService { @Resource private SystemUserRoleDAO systemUserRoleDAO; + @Resource + private DataPermissionService dataPermissionService; + @Override - public List getUserRoleIdList(Long userId) { + public List getRoleIdListByUserId(Long userId) { return systemUserRoleDAO.selectRoleIdByUserId(userId); } + @Override + public List getUserIdListByRoleCode(String roleCode) { + Long roleId = systemRoleDAO.of() + .createWrapper() + .eq(SystemRoleDO::getCode, roleCode) + .then() + .getOne(SystemRoleDO::getId); + if (roleId == null) { + return Lists.empty(); + } + // 查询用户列表 + return systemUserRoleDAO.selectUserIdByRoleId(roleId); + } + @Override public Integer deleteUserRoles(SystemUserUpdateRoleRequest request) { Long userId = request.getId(); @@ -60,10 +78,12 @@ public class SystemUserRoleServiceImpl implements SystemUserRoleService { OperatorLogs.add(OperatorLogs.USERNAME, user.getUsername()); // 删除用户关联 int effect = systemUserRoleDAO.deleteByUserId(userId); - // 更新缓存中的角色 + // 更新用户缓存中的角色 RedisStrings.processSetJson(UserCacheKeyDefine.USER_INFO, s -> { s.setRoles(Lists.empty()); }, userId); + // 清除数据权限缓存 + dataPermissionService.clearUserCache(userId); return effect; } @@ -107,6 +127,8 @@ public class SystemUserRoleServiceImpl implements SystemUserRoleService { .collect(Collectors.toList()); s.setRoles(roles); }, userId); + // 清除数据权限缓存 + dataPermissionService.clearUserCache(userId); return effect; } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java index bd95f4c8..19338f3e 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java @@ -3,13 +3,11 @@ package com.orion.ops.module.infra.service.impl; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.orion.lang.define.wrapper.DataGrid; -import com.orion.lang.utils.collect.Lists; import com.orion.lang.utils.crypto.Signatures; import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs; import com.orion.ops.framework.common.constant.ErrorCode; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.security.LoginUser; -import com.orion.ops.framework.common.utils.Requests; import com.orion.ops.framework.common.utils.Valid; import com.orion.ops.framework.redis.core.utils.RedisMaps; import com.orion.ops.framework.redis.core.utils.RedisStrings; @@ -18,31 +16,25 @@ import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers; import com.orion.ops.framework.security.core.utils.SecurityUtils; import com.orion.ops.module.infra.convert.SystemUserConvert; import com.orion.ops.module.infra.dao.OperatorLogDAO; +import com.orion.ops.module.infra.dao.SystemRoleDAO; import com.orion.ops.module.infra.dao.SystemUserDAO; import com.orion.ops.module.infra.dao.SystemUserRoleDAO; +import com.orion.ops.module.infra.define.RoleDefine; import com.orion.ops.module.infra.define.cache.TipsCacheKeyDefine; import com.orion.ops.module.infra.define.cache.UserCacheKeyDefine; +import com.orion.ops.module.infra.entity.domain.SystemRoleDO; import com.orion.ops.module.infra.entity.domain.SystemUserDO; -import com.orion.ops.module.infra.entity.dto.LoginTokenDTO; -import com.orion.ops.module.infra.entity.dto.LoginTokenIdentityDTO; import com.orion.ops.module.infra.entity.dto.UserInfoDTO; import com.orion.ops.module.infra.entity.request.user.*; import com.orion.ops.module.infra.entity.vo.SystemUserVO; -import com.orion.ops.module.infra.entity.vo.UserSessionVO; -import com.orion.ops.module.infra.enums.LoginTokenStatusEnum; import com.orion.ops.module.infra.enums.UserStatusEnum; -import com.orion.ops.module.infra.service.AuthenticationService; -import com.orion.ops.module.infra.service.FavoriteService; -import com.orion.ops.module.infra.service.PreferenceService; -import com.orion.ops.module.infra.service.SystemUserService; +import com.orion.ops.module.infra.service.*; import com.orion.spring.SpringHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.Comparator; -import java.util.Date; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -64,6 +56,9 @@ public class SystemUserServiceImpl implements SystemUserService { @Resource private SystemUserRoleDAO systemUserRoleDAO; + @Resource + private SystemRoleDAO systemRoleDAO; + @Resource private OperatorLogDAO operatorLogDAO; @@ -73,6 +68,9 @@ public class SystemUserServiceImpl implements SystemUserService { @Resource private PreferenceService preferenceService; + @Resource + private DataPermissionService dataPermissionService; + @Override public Long createSystemUser(SystemUserCreateRequest request) { // 转换 @@ -206,6 +204,15 @@ public class SystemUserServiceImpl implements SystemUserService { // 删除用户 int effect = systemUserDAO.deleteById(id); log.info("SystemUserService-deleteSystemUserById id: {}, effect: {}", id, effect); + // 删除用户信息缓存 + RedisUtils.delete(UserCacheKeyDefine.USER_INFO.format(id)); + // 删除 token 缓存 + RedisUtils.scanKeysDelete( + // 登录 token + UserCacheKeyDefine.LOGIN_TOKEN.format(id, "*"), + // 刷新 token + UserCacheKeyDefine.LOGIN_REFRESH.format(id, "*") + ); // 异步删除额外信息 SpringHolder.getBean(SystemUserService.class).deleteSystemUserRelAsync(id, record.getUsername()); return effect; @@ -217,10 +224,8 @@ public class SystemUserServiceImpl implements SystemUserService { log.info("SystemUserService-deleteSystemUserRel id: {}", id); // 删除用户列表缓存 RedisMaps.delete(UserCacheKeyDefine.USER_LIST, id); - // 删除用户缓存 需要扫描的 key 让其自动过期 + // 删除用户缓存 其他的 key 让其自动过期 RedisUtils.delete( - // 用户缓存 - UserCacheKeyDefine.USER_INFO.format(id), // 登录失败次数 UserCacheKeyDefine.LOGIN_FAILED_COUNT.format(username), // 用户提示 @@ -234,6 +239,8 @@ public class SystemUserServiceImpl implements SystemUserService { favoriteService.deleteFavoriteByUserId(id); // 删除用户偏好 preferenceService.deletePreferenceByUserId(id); + // 删除用户数据权限 + dataPermissionService.deleteByUserId(id); } @Override @@ -269,58 +276,17 @@ public class SystemUserServiceImpl implements SystemUserService { } @Override - public List getUserSessionList(Long userId) { - // 扫描缓存 - Set keys = RedisStrings.scanKeys(UserCacheKeyDefine.LOGIN_TOKEN.format(userId, "*")); - if (Lists.isEmpty(keys)) { - return Lists.empty(); - } - // 查询缓存 - List tokens = RedisStrings.getJsonList(keys, UserCacheKeyDefine.LOGIN_TOKEN); - if (Lists.isEmpty(tokens)) { - return Lists.empty(); - } - final boolean isCurrentUser = userId.equals(SecurityUtils.getLoginUserId()); - // 返回 - return tokens.stream() - .filter(s -> LoginTokenStatusEnum.OK.getStatus().equals(s.getStatus())) - .map(LoginTokenDTO::getOrigin) - .map(s -> UserSessionVO.builder() - .current(isCurrentUser && s.getLoginTime().equals(SecurityUtils.getLoginTimestamp())) - .address(s.getAddress()) - .location(s.getLocation()) - .userAgent(s.getUserAgent()) - .loginTime(new Date(s.getLoginTime())) - .build()) - .sorted(Comparator.comparing(UserSessionVO::getCurrent).reversed() - .thenComparing(Comparator.comparing(UserSessionVO::getLoginTime).reversed())) - .collect(Collectors.toList()); - } - - @Override - public void offlineUserSession(UserSessionOfflineRequest request) { - Long userId = Valid.notNull(request.getUserId()); - Long timestamp = request.getTimestamp(); - // 查询用户 - SystemUserDO user = systemUserDAO.selectById(userId); - Valid.notNull(user, ErrorMessage.USER_ABSENT); - // 添加日志参数 - OperatorLogs.add(OperatorLogs.USERNAME, user.getUsername()); - // 删除刷新缓存 - RedisStrings.delete(UserCacheKeyDefine.LOGIN_REFRESH.format(userId, request.getTimestamp())); - // 查询并且覆盖 token - String tokenKey = UserCacheKeyDefine.LOGIN_TOKEN.format(userId, timestamp); - LoginTokenDTO tokenInfo = RedisStrings.getJson(tokenKey, UserCacheKeyDefine.LOGIN_TOKEN); - if (tokenInfo != null) { - tokenInfo.setStatus(LoginTokenStatusEnum.SESSION_OFFLINE.getStatus()); - LoginTokenIdentityDTO override = new LoginTokenIdentityDTO(); - override.setLoginTime(System.currentTimeMillis()); - // 设置请求信息 - Requests.fillIdentity(override); - tokenInfo.setOverride(override); - // 更新 token - RedisStrings.setJson(tokenKey, UserCacheKeyDefine.LOGIN_TOKEN, tokenInfo); + public boolean isAdminUser(Long userId) { + // 查询用户角色 + List roleIdList = systemUserRoleDAO.selectRoleIdByUserId(userId); + if (!roleIdList.isEmpty()) { + // 查询角色信息 + return systemRoleDAO.selectBatchIds(roleIdList) + .stream() + .map(SystemRoleDO::getCode) + .anyMatch(RoleDefine::isAdmin); } + return false; } /** diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/DataPermissionMapper.xml b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/DataPermissionMapper.xml new file mode 100644 index 00000000..003f8ebf --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/DataPermissionMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + id, user_id, role_id, rel_id, type, create_time, update_time, creator, updater, deleted + + +