From f1650b5014256e7969f14c8b0d133911ed65aba6 Mon Sep 17 00:00:00 2001 From: Wu Clan Date: Wed, 23 Apr 2025 11:54:57 +0800 Subject: [PATCH] Optimize the userinfo cache cleaning logic --- backend/app/admin/api/v1/sys/__init__.py | 2 +- backend/app/admin/api/v1/sys/data_rule.py | 22 +++--- backend/app/admin/api/v1/sys/dept.py | 6 +- backend/app/admin/api/v1/sys/menu.py | 4 +- backend/app/admin/api/v1/sys/role.py | 16 ++--- backend/app/admin/crud/crud_data_rule.py | 2 +- backend/app/admin/model/data_rule.py | 2 +- backend/app/admin/model/m2m.py | 2 +- backend/app/admin/model/role.py | 2 +- .../app/admin/service/data_rule_service.py | 26 ++++--- backend/app/admin/service/dept_service.py | 11 ++- backend/app/admin/service/menu_service.py | 12 +++- backend/app/admin/service/role_service.py | 32 +++++---- backend/app/admin/service/user_service.py | 68 ++++++++----------- backend/common/enums.py | 4 +- backend/sql/mysql/create_tables.sql | 4 +- backend/sql/postgresql/create_tables.sql | 4 +- 17 files changed, 109 insertions(+), 110 deletions(-) diff --git a/backend/app/admin/api/v1/sys/__init__.py b/backend/app/admin/api/v1/sys/__init__.py index 7318f87a6..8b2b27022 100644 --- a/backend/app/admin/api/v1/sys/__init__.py +++ b/backend/app/admin/api/v1/sys/__init__.py @@ -17,7 +17,7 @@ router.include_router(menu_router, prefix='/menus', tags=['系统菜单']) router.include_router(role_router, prefix='/roles', tags=['系统角色']) router.include_router(user_router, prefix='/users', tags=['系统用户']) -router.include_router(data_rule_router, prefix='/data-rules', tags=['系统数据权限规则']) +router.include_router(data_rule_router, prefix='/data-rules', tags=['系统数据规则']) router.include_router(token_router, prefix='/tokens', tags=['系统令牌']) router.include_router(upload_router, prefix='/upload', tags=['系统上传']) router.include_router(plugin_router, prefix='/plugin', tags=['系统插件']) diff --git a/backend/app/admin/api/v1/sys/data_rule.py b/backend/app/admin/api/v1/sys/data_rule.py index a4c487c8e..374492024 100644 --- a/backend/app/admin/api/v1/sys/data_rule.py +++ b/backend/app/admin/api/v1/sys/data_rule.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from typing import Annotated -from fastapi import APIRouter, Depends, Path, Query, Request +from fastapi import APIRouter, Depends, Path, Query from backend.app.admin.schema.data_rule import CreateDataRuleParam, GetDataRuleDetail, UpdateDataRuleParam from backend.app.admin.service.data_rule_service import data_rule_service @@ -16,13 +16,13 @@ router = APIRouter() -@router.get('/models', summary='获取支持过滤的数据库模型', dependencies=[DependsJwtAuth]) +@router.get('/models', summary='获取数据规则可用模型', dependencies=[DependsJwtAuth]) async def get_data_rule_models() -> ResponseSchemaModel[list[str]]: models = await data_rule_service.get_models() return response_base.success(data=models) -@router.get('/model/{model}/columns', summary='获取支持过滤的数据库模型列', dependencies=[DependsJwtAuth]) +@router.get('/model/{model}/columns', summary='获取数据规则可用模型列', dependencies=[DependsJwtAuth]) async def get_data_rule_model_columns( model: Annotated[str, Path(description='模型名称')], ) -> ResponseSchemaModel[list[str]]: @@ -36,7 +36,7 @@ async def get_all_data_rules() -> ResponseSchemaModel[list[GetDataRuleDetail]]: return response_base.success(data=data) -@router.get('/{pk}', summary='获取数据权限规则详情', dependencies=[DependsJwtAuth]) +@router.get('/{pk}', summary='获取数据规则详情', dependencies=[DependsJwtAuth]) async def get_data_rule( pk: Annotated[int, Path(description='数据规则 ID')], ) -> ResponseSchemaModel[GetDataRuleDetail]: @@ -46,7 +46,7 @@ async def get_data_rule( @router.get( '', - summary='分页获取所有数据权限规则', + summary='分页获取所有数据规则', dependencies=[ DependsJwtAuth, DependsPagination, @@ -62,7 +62,7 @@ async def get_pagination_data_rules( @router.post( '', - summary='创建数据权限规则', + summary='创建数据规则', dependencies=[ Depends(RequestPermission('data:rule:add')), DependsRBAC, @@ -75,7 +75,7 @@ async def create_data_rule(obj: CreateDataRuleParam) -> ResponseModel: @router.put( '/{pk}', - summary='更新数据权限规则', + summary='更新数据规则', dependencies=[ Depends(RequestPermission('data:rule:edit')), DependsRBAC, @@ -92,16 +92,14 @@ async def update_data_rule( @router.delete( '', - summary='批量删除数据权限规则', + summary='批量删除数据规则', dependencies=[ Depends(RequestPermission('data:rule:del')), DependsRBAC, ], ) -async def delete_data_rule( - request: Request, pk: Annotated[list[int], Query(description='数据规则 ID 列表')] -) -> ResponseModel: - count = await data_rule_service.delete(request=request, pk=pk) +async def delete_data_rule(pk: Annotated[list[int], Query(description='数据规则 ID 列表')]) -> ResponseModel: + count = await data_rule_service.delete(pk=pk) if count > 0: return response_base.success() return response_base.fail() diff --git a/backend/app/admin/api/v1/sys/dept.py b/backend/app/admin/api/v1/sys/dept.py index 03267c20e..0c9a3b969 100644 --- a/backend/app/admin/api/v1/sys/dept.py +++ b/backend/app/admin/api/v1/sys/dept.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from typing import Annotated, Any -from fastapi import APIRouter, Depends, Path, Query, Request +from fastapi import APIRouter, Depends, Path, Query from backend.app.admin.schema.dept import CreateDeptParam, GetDeptDetail, UpdateDeptParam from backend.app.admin.service.dept_service import dept_service @@ -67,8 +67,8 @@ async def update_dept(pk: Annotated[int, Path(description='部门 ID')], obj: Up DependsRBAC, ], ) -async def delete_dept(request: Request, pk: Annotated[int, Path(description='部门 ID')]) -> ResponseModel: - count = await dept_service.delete(request=request, pk=pk) +async def delete_dept(pk: Annotated[int, Path(description='部门 ID')]) -> ResponseModel: + count = await dept_service.delete(pk=pk) if count > 0: return response_base.success() return response_base.fail() diff --git a/backend/app/admin/api/v1/sys/menu.py b/backend/app/admin/api/v1/sys/menu.py index 43780a576..dbd4f23c2 100644 --- a/backend/app/admin/api/v1/sys/menu.py +++ b/backend/app/admin/api/v1/sys/menu.py @@ -71,8 +71,8 @@ async def update_menu(pk: Annotated[int, Path(description='菜单 ID')], obj: Up DependsRBAC, ], ) -async def delete_menu(request: Request, pk: Annotated[int, Path(description='菜单 ID 列表')]) -> ResponseModel: - count = await menu_service.delete(request=request, pk=pk) +async def delete_menu(pk: Annotated[int, Path(description='菜单 ID 列表')]) -> ResponseModel: + count = await menu_service.delete(pk=pk) if count > 0: return response_base.success() return response_base.fail() diff --git a/backend/app/admin/api/v1/sys/role.py b/backend/app/admin/api/v1/sys/role.py index bfd72f3c5..1dbf9e53f 100644 --- a/backend/app/admin/api/v1/sys/role.py +++ b/backend/app/admin/api/v1/sys/role.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from typing import Annotated, Any -from fastapi import APIRouter, Depends, Path, Query, Request +from fastapi import APIRouter, Depends, Path, Query from backend.app.admin.schema.role import ( CreateRoleParam, @@ -116,9 +116,9 @@ async def update_role(pk: Annotated[int, Path(description='角色 ID')], obj: Up ], ) async def update_role_menus( - request: Request, pk: Annotated[int, Path(description='角色 ID')], menu_ids: UpdateRoleMenuParam + pk: Annotated[int, Path(description='角色 ID')], menu_ids: UpdateRoleMenuParam ) -> ResponseModel: - count = await role_service.update_role_menu(request=request, pk=pk, menu_ids=menu_ids) + count = await role_service.update_role_menu(pk=pk, menu_ids=menu_ids) if count > 0: return response_base.success() return response_base.fail() @@ -126,16 +126,16 @@ async def update_role_menus( @router.put( '/{pk}/rule', - summary='更新角色数据权限规则', + summary='更新角色数据规则', dependencies=[ Depends(RequestPermission('sys:role:rule:edit')), DependsRBAC, ], ) async def update_role_rules( - request: Request, pk: Annotated[int, Path(description='角色 ID')], rule_ids: UpdateRoleRuleParam + pk: Annotated[int, Path(description='角色 ID')], rule_ids: UpdateRoleRuleParam ) -> ResponseModel: - count = await role_service.update_role_rule(request=request, pk=pk, rule_ids=rule_ids) + count = await role_service.update_role_rule(pk=pk, rule_ids=rule_ids) if count > 0: return response_base.success() return response_base.fail() @@ -149,8 +149,8 @@ async def update_role_rules( DependsRBAC, ], ) -async def delete_role(request: Request, pk: Annotated[list[int], Query(description='角色 ID 列表')]) -> ResponseModel: - count = await role_service.delete(request=request, pk=pk) +async def delete_role(pk: Annotated[list[int], Query(description='角色 ID 列表')]) -> ResponseModel: + count = await role_service.delete(pk=pk) if count > 0: return response_base.success() return response_base.fail() diff --git a/backend/app/admin/crud/crud_data_rule.py b/backend/app/admin/crud/crud_data_rule.py index 067436ee7..437b25f25 100644 --- a/backend/app/admin/crud/crud_data_rule.py +++ b/backend/app/admin/crud/crud_data_rule.py @@ -12,7 +12,7 @@ class CRUDDataRule(CRUDPlus[DataRule]): - """数据权限规则数据库操作类""" + """数据规则数据库操作类""" async def get(self, db: AsyncSession, pk: int) -> DataRule | None: """ diff --git a/backend/app/admin/model/data_rule.py b/backend/app/admin/model/data_rule.py index 4ec7da564..3c790e765 100644 --- a/backend/app/admin/model/data_rule.py +++ b/backend/app/admin/model/data_rule.py @@ -15,7 +15,7 @@ class DataRule(Base): - """数据权限规则表""" + """数据规则表""" __tablename__ = 'sys_data_rule' diff --git a/backend/app/admin/model/m2m.py b/backend/app/admin/model/m2m.py index acccd6f9d..ab68ebfa9 100644 --- a/backend/app/admin/model/m2m.py +++ b/backend/app/admin/model/m2m.py @@ -30,6 +30,6 @@ Integer, ForeignKey('sys_data_rule.id', ondelete='CASCADE'), primary_key=True, - comment='数据权限规则ID', + comment='数据规则ID', ), ) diff --git a/backend/app/admin/model/role.py b/backend/app/admin/model/role.py index 54227c7e1..2fd0498f2 100644 --- a/backend/app/admin/model/role.py +++ b/backend/app/admin/model/role.py @@ -34,5 +34,5 @@ class Role(Base): # 角色菜单多对多 menus: Mapped[list[Menu]] = relationship(init=False, secondary=sys_role_menu, back_populates='roles') - # 角色数据权限规则多对多 + # 角色数据规则多对多 rules: Mapped[list[DataRule]] = relationship(init=False, secondary=sys_role_data_rule, back_populates='roles') diff --git a/backend/app/admin/service/data_rule_service.py b/backend/app/admin/service/data_rule_service.py index 4bbf4d372..487dd2d79 100644 --- a/backend/app/admin/service/data_rule_service.py +++ b/backend/app/admin/service/data_rule_service.py @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- from typing import Sequence -from fastapi import Request from sqlalchemy import Select from backend.app.admin.crud.crud_data_rule import data_rule_dao @@ -17,7 +16,7 @@ class DataRuleService: - """数据权限规则服务类""" + """数据规则服务类""" @staticmethod async def get(*, pk: int) -> DataRule: @@ -50,19 +49,19 @@ async def get_role_rules(*, pk: int) -> list[int]: @staticmethod async def get_models() -> list[str]: - """获取所有数据模型""" + """获取所有数据规则可用模型""" return list(settings.DATA_PERMISSION_MODELS.keys()) @staticmethod async def get_columns(model: str) -> list[str]: """ - 获取数据模型的字段列表 + 获取数据规则可用模型的字段列表 :param model: 模型名称 :return: """ if model not in settings.DATA_PERMISSION_MODELS: - raise errors.NotFoundError(msg='数据模型不存在') + raise errors.NotFoundError(msg='数据规则可用模型不存在') model_ins = dynamic_import_data_model(settings.DATA_PERMISSION_MODELS[model]) model_columns = [ key for key in model_ins.__table__.columns.keys() if key not in settings.DATA_PERMISSION_COLUMN_EXCLUDE @@ -97,7 +96,7 @@ async def create(*, obj: CreateDataRuleParam) -> None: async with async_db_session.begin() as db: data_rule = await data_rule_dao.get_by_name(db, obj.name) if data_rule: - raise errors.ForbiddenError(msg='数据权限规则已存在') + raise errors.ForbiddenError(msg='数据规则已存在') await data_rule_dao.create(db, obj) @staticmethod @@ -112,22 +111,29 @@ async def update(*, pk: int, obj: UpdateDataRuleParam) -> int: async with async_db_session.begin() as db: data_rule = await data_rule_dao.get(db, pk) if not data_rule: - raise errors.NotFoundError(msg='数据权限规则不存在') + raise errors.NotFoundError(msg='数据规则不存在') count = await data_rule_dao.update(db, pk, obj) + for role in await data_rule.awaitable_attrs.roles: + for user in await role.awaitable_attrs.users: + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod - async def delete(*, request: Request, pk: list[int]) -> int: + async def delete(*, pk: list[int]) -> int: """ 删除数据规则 - :param request: FastAPI 请求对象 :param pk: 规则 ID 列表 :return: """ async with async_db_session.begin() as db: count = await data_rule_dao.delete(db, pk) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + for _pk in pk: + data_rule = await data_rule_dao.get(db, _pk) + if data_rule: + for role in await data_rule.awaitable_attrs.roles: + for user in await role.awaitable_attrs.users: + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count diff --git a/backend/app/admin/service/dept_service.py b/backend/app/admin/service/dept_service.py index c04f14264..1006b575b 100644 --- a/backend/app/admin/service/dept_service.py +++ b/backend/app/admin/service/dept_service.py @@ -2,8 +2,6 @@ # -*- coding: utf-8 -*- from typing import Any -from fastapi import Request - from backend.app.admin.crud.crud_dept import dept_dao from backend.app.admin.model import Dept from backend.app.admin.schema.dept import CreateDeptParam, UpdateDeptParam @@ -93,24 +91,23 @@ async def update(*, pk: int, obj: UpdateDeptParam) -> int: return count @staticmethod - async def delete(*, request: Request, pk: int) -> int: + async def delete(*, pk: int) -> int: """ 删除部门 - :param request: FastAPI 请求对象 :param pk: 部门 ID :return: """ async with async_db_session.begin() as db: dept = await dept_dao.get_with_relation(db, pk) - dept_user = dept.users - if dept_user: + if dept.users: raise errors.ForbiddenError(msg='部门下存在用户,无法删除') children = await dept_dao.get_children(db, pk) if children: raise errors.ForbiddenError(msg='部门下存在子部门,无法删除') count = await dept_dao.delete(db, pk) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + for user in dept.users: + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count diff --git a/backend/app/admin/service/menu_service.py b/backend/app/admin/service/menu_service.py index c7244699c..9123bd0b8 100644 --- a/backend/app/admin/service/menu_service.py +++ b/backend/app/admin/service/menu_service.py @@ -123,14 +123,16 @@ async def update(*, pk: int, obj: UpdateMenuParam) -> int: if obj.parent_id == menu.id: raise errors.ForbiddenError(msg='禁止关联自身为父级') count = await menu_dao.update(db, pk, obj) + for role in await menu.awaitable_attrs.roles: + for user in await role.awaitable_attrs.users: + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod - async def delete(*, request: Request, pk: int) -> int: + async def delete(*, pk: int) -> int: """ 删除菜单 - :param request: FastAPI 请求对象 :param pk: 菜单 ID :return: """ @@ -138,8 +140,12 @@ async def delete(*, request: Request, pk: int) -> int: children = await menu_dao.get_children(db, pk) if children: raise errors.ForbiddenError(msg='菜单下存在子菜单,无法删除') + menu = await menu_dao.get(db, pk) count = await menu_dao.delete(db, pk) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + if menu: + for role in await menu.awaitable_attrs.roles: + for user in await role.awaitable_attrs.users: + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count diff --git a/backend/app/admin/service/role_service.py b/backend/app/admin/service/role_service.py index 2984b652d..4d9ffa93f 100644 --- a/backend/app/admin/service/role_service.py +++ b/backend/app/admin/service/role_service.py @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- from typing import Sequence -from fastapi import Request from sqlalchemy import Select from backend.app.admin.crud.crud_data_rule import data_rule_dao @@ -100,20 +99,21 @@ async def update(*, pk: int, obj: UpdateRoleParam) -> int: if role: raise errors.ForbiddenError(msg='角色已存在') count = await role_dao.update(db, pk, obj) + for user in await role.awaitable_attrs.users: + await redis_client.delete_prefix(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod - async def update_role_menu(*, request: Request, pk: int, menu_ids: UpdateRoleMenuParam) -> int: + async def update_role_menu(*, pk: int, menu_ids: UpdateRoleMenuParam) -> int: """ 更新角色菜单 - :param request: FastAPI 请求对象 :param pk: 角色 ID :param menu_ids: 菜单 ID 列表 :return: """ async with async_db_session.begin() as db: - role = await role_dao.get(db, pk) + role = await role_dao.get_with_relation(db, pk) if not role: raise errors.NotFoundError(msg='角色不存在') for menu_id in menu_ids.menus: @@ -121,16 +121,15 @@ async def update_role_menu(*, request: Request, pk: int, menu_ids: UpdateRoleMen if not menu: raise errors.NotFoundError(msg='菜单不存在') count = await role_dao.update_menus(db, pk, menu_ids) - if pk in [role.id for role in request.user.roles]: - await redis_client.delete_prefix(f'{settings.JWT_USER_REDIS_PREFIX}') + for user in await role.awaitable_attrs.users: + await redis_client.delete_prefix(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod - async def update_role_rule(*, request: Request, pk: int, rule_ids: UpdateRoleRuleParam) -> int: + async def update_role_rule(*, pk: int, rule_ids: UpdateRoleRuleParam) -> int: """ - 更新角色数据权限 + 更新角色数据规则 - :param request: FastAPI 请求对象 :param pk: 角色 ID :param rule_ids: 权限规则 ID 列表 :return: @@ -142,24 +141,27 @@ async def update_role_rule(*, request: Request, pk: int, rule_ids: UpdateRoleRul for rule_id in rule_ids.rules: rule = await data_rule_dao.get(db, rule_id) if not rule: - raise errors.NotFoundError(msg='数据权限不存在') + raise errors.NotFoundError(msg='数据规则不存在') count = await role_dao.update_rules(db, pk, rule_ids) - if pk in [role.id for role in request.user.roles]: - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + for user in await role.awaitable_attrs.users: + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod - async def delete(*, request: Request, pk: list[int]) -> int: + async def delete(*, pk: list[int]) -> int: """ 删除角色 - :param request: FastAPI 请求对象 :param pk: 角色 ID 列表 :return: """ async with async_db_session.begin() as db: count = await role_dao.delete(db, pk) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + for _pk in pk: + role = await role_dao.get(db, _pk) + if role: + for user in await role.awaitable_attrs.users: + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count diff --git a/backend/app/admin/service/user_service.py b/backend/app/admin/service/user_service.py index 1962b3b81..b8b6663fd 100644 --- a/backend/app/admin/service/user_service.py +++ b/backend/app/admin/service/user_service.py @@ -135,25 +135,25 @@ async def update(*, request: Request, username: str, obj: UpdateUserParam) -> in :return: """ async with async_db_session.begin() as db: - if not request.user.is_superuser and request.user.username != username: + if request.user.username != username: raise errors.ForbiddenError(msg='你只能修改自己的信息') - input_user = await user_dao.get_with_relation(db, username=username) - if not input_user: + user = await user_dao.get_with_relation(db, username=username) + if not user: raise errors.NotFoundError(msg='用户不存在') - if input_user.username != obj.username: + if user.username != obj.username: _username = await user_dao.get_by_username(db, obj.username) if _username: raise errors.ForbiddenError(msg='用户名已注册') - if input_user.nickname != obj.nickname: + if user.nickname != obj.nickname: nickname = await user_dao.get_by_nickname(db, obj.nickname) if nickname: raise errors.ForbiddenError(msg='昵称已注册') - if input_user.email != obj.email: + if user.email != obj.email: email = await user_dao.check_email(db, obj.email) if email: raise errors.ForbiddenError(msg='邮箱已注册') - count = await user_dao.update_userinfo(db, input_user.id, obj) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + count = await user_dao.update_userinfo(db, user.id, obj) + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod @@ -168,7 +168,7 @@ async def update_roles(*, request: Request, username: str, obj: UpdateUserRolePa """ async with async_db_session.begin() as db: if not request.user.is_superuser and request.user.username != username: - raise errors.AuthorizationError + raise errors.ForbiddenError(msg='你只能修改自己的信息') input_user = await user_dao.get_with_relation(db, username=username) if not input_user: raise errors.NotFoundError(msg='用户不存在') @@ -190,13 +190,13 @@ async def update_avatar(*, request: Request, username: str, avatar: AvatarParam) :return: """ async with async_db_session.begin() as db: - if not request.user.is_superuser and request.user.username != username: + if request.user.username != username: raise errors.AuthorizationError - input_user = await user_dao.get_by_username(db, username) - if not input_user: + user = await user_dao.get_by_username(db, username) + if not user: raise errors.NotFoundError(msg='用户不存在') - count = await user_dao.update_avatar(db, input_user.id, avatar) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + count = await user_dao.update_avatar(db, user.id, avatar) + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod @@ -230,7 +230,7 @@ async def update_permission(*, request: Request, pk: int) -> int: raise errors.ForbiddenError(msg='非法操作') super_status = await user_dao.get_super(db, pk) count = await user_dao.set_super(db, pk, not super_status) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}') + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod @@ -251,7 +251,7 @@ async def update_staff(*, request: Request, pk: int) -> int: raise errors.ForbiddenError(msg='非法操作') staff_status = await user_dao.get_staff(db, pk) count = await user_dao.set_staff(db, pk, not staff_status) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}') + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod @@ -272,7 +272,7 @@ async def update_status(*, request: Request, pk: int) -> int: raise errors.ForbiddenError(msg='非法操作') status = await user_dao.get_status(db, pk) count = await user_dao.set_status(db, pk, 0 if status == 1 else 1) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}') + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count @staticmethod @@ -289,32 +289,22 @@ async def update_multi_login(*, request: Request, pk: int) -> int: user = await user_dao.get(db, pk) if not user: raise errors.NotFoundError(msg='用户不存在') - user_id = request.user.id - multi_login = await user_dao.get_multi_login(db, pk) if pk != user_id else request.user.is_multi_login - count = await user_dao.set_multi_login(db, pk, not multi_login) - # 删除当前用户缓存 - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}') + multi_login = await user_dao.get_multi_login(db, pk) if pk != user.id else request.user.is_multi_login + new_multi_login = not multi_login + count = await user_dao.set_multi_login(db, pk, new_multi_login) + await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') token = get_token(request) token_payload = jwt_decode(token) - latest_multi_login = await user_dao.get_multi_login(db, pk) - # 超级用户修改自身时,除当前 token 外,其他 token 失效 - if pk == user_id: - if not latest_multi_login: - key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{pk}' + if pk == user.id: + # 系统管理员修改自身时,除当前 token 外,其他 token 失效 + if not new_multi_login: + key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{user.id}' await redis_client.delete_prefix(key_prefix, exclude=f'{key_prefix}:{token_payload.session_uuid}') - refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY) - if refresh_token: - key_prefix = f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}' - await redis_client.delete_prefix(key_prefix, exclude=f'{key_prefix}:{refresh_token}') - # 超级用户修改他人时,其他 token 将全部失效 else: - if not latest_multi_login: - key_prefix = [f'{settings.TOKEN_REDIS_PREFIX}:{pk}'] - refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY) - if refresh_token: - key_prefix.append(f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}') - for prefix in key_prefix: - await redis_client.delete_prefix(prefix) + # 系统管理员修改他人时,他人 token 全部失效 + if not new_multi_login: + key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{user.id}' + await redis_client.delete_prefix(key_prefix) return count @staticmethod diff --git a/backend/common/enums.py b/backend/common/enums.py index d4c3bbb86..5cf2482ae 100644 --- a/backend/common/enums.py +++ b/backend/common/enums.py @@ -47,14 +47,14 @@ class MenuType(IntEnum): class RoleDataRuleOperatorType(IntEnum): - """数据权限规则运算符""" + """数据规则运算符""" AND = 0 OR = 1 class RoleDataRuleExpressionType(IntEnum): - """数据权限规则表达式""" + """数据规则表达式""" eq = 0 # == ne = 1 # != diff --git a/backend/sql/mysql/create_tables.sql b/backend/sql/mysql/create_tables.sql index 06adb974d..57df55169 100644 --- a/backend/sql/mysql/create_tables.sql +++ b/backend/sql/mysql/create_tables.sql @@ -119,7 +119,7 @@ create table sys_data_rule constraint name unique (name) ) - comment '数据权限规则表'; + comment '数据规则表'; create index ix_sys_data_rule_id on sys_data_rule (id); @@ -319,7 +319,7 @@ create table sys_role_data_rule ( id int auto_increment comment '主键ID', role_id int not null comment '角色ID', - data_rule_id int not null comment '数据权限规则ID', + data_rule_id int not null comment '数据规则ID', primary key (id, role_id, data_rule_id), constraint ix_sys_role_data_rule_id unique (id), diff --git a/backend/sql/postgresql/create_tables.sql b/backend/sql/postgresql/create_tables.sql index b73c593e2..0dcdc1d11 100644 --- a/backend/sql/postgresql/create_tables.sql +++ b/backend/sql/postgresql/create_tables.sql @@ -13,7 +13,7 @@ create table sys_data_rule updated_time timestamp with time zone ); -comment on table sys_data_rule is '数据权限规则表'; +comment on table sys_data_rule is '数据规则表'; comment on column sys_data_rule.id is '主键 ID'; @@ -609,7 +609,7 @@ comment on column sys_role_data_rule.id is '主键ID'; comment on column sys_role_data_rule.role_id is '角色ID'; -comment on column sys_role_data_rule.data_rule_id is '数据权限规则ID'; +comment on column sys_role_data_rule.data_rule_id is '数据规则ID'; alter table sys_role_data_rule owner to postgres;