ShiErFeng/shierfeng-fastapi-backend/common/aspect/data_scope.py
2026-07-24 09:43:10 +08:00

113 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import Depends, Request, params
from sqlalchemy import ColumnElement, func, or_, select
from common.context import RequestContext
from config.database import Base
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.do.role_do import SysRoleDept
from utils.dependency_util import DependencyUtil
class GetDataScope:
"""
获取当前用户数据权限对应的查询sql语句
"""
DATA_SCOPE_ALL = '1'
DATA_SCOPE_CUSTOM = '2'
DATA_SCOPE_DEPT = '3'
DATA_SCOPE_DEPT_AND_CHILD = '4'
DATA_SCOPE_SELF = '5'
def __init__(
self,
query_alias: Base,
user_alias: str | None = 'user_id',
dept_alias: str | None = 'dept_id',
) -> None:
"""
获取当前用户数据权限对应的查询sql语句
:param query_alias: 所要查询表对应的sqlalchemy模型类不可为空
:param user_alias: 用户id字段别名默认为'user_id'
:param dept_alias: 部门id字段别名默认为'dept_id'
"""
self.query_alias = query_alias
self.user_alias = user_alias
self.dept_alias = dept_alias
def __call__(self, request: Request) -> ColumnElement:
DependencyUtil.check_exclude_routes(request, err_msg='当前路由不在认证规则内不可使用GetDataScope依赖项')
current_user = RequestContext.get_current_user()
user_id = current_user.user.user_id
dept_id = current_user.user.dept_id
custom_data_scope_role_id_list = [
item.role_id for item in current_user.user.role if item.data_scope == self.DATA_SCOPE_CUSTOM
]
param_sql_list = []
for role in current_user.user.role:
if current_user.user.admin or role.data_scope == self.DATA_SCOPE_ALL:
param_sql_list = [True]
break
if role.data_scope == self.DATA_SCOPE_CUSTOM:
if len(custom_data_scope_role_id_list) > 1:
param_sql_list.append(
getattr(self.query_alias, self.dept_alias).in_(
select(SysRoleDept.dept_id).where(SysRoleDept.role_id.in_(custom_data_scope_role_id_list))
)
if hasattr(self.query_alias, self.dept_alias)
else False
)
else:
param_sql_list.append(
getattr(self.query_alias, self.dept_alias).in_(
select(SysRoleDept.dept_id).where(SysRoleDept.role_id == role.role_id)
)
if hasattr(self.query_alias, self.dept_alias)
else False
)
elif role.data_scope == self.DATA_SCOPE_DEPT:
param_sql_list.append(
getattr(self.query_alias, self.dept_alias) == dept_id
if hasattr(self.query_alias, self.dept_alias)
else False
)
elif role.data_scope == self.DATA_SCOPE_DEPT_AND_CHILD:
param_sql_list.append(
getattr(self.query_alias, self.dept_alias).in_(
select(SysDept.dept_id).where(
or_(SysDept.dept_id == dept_id, func.find_in_set(dept_id, SysDept.ancestors))
)
)
if hasattr(self.query_alias, self.dept_alias)
else False
)
elif role.data_scope == self.DATA_SCOPE_SELF:
param_sql_list.append(
getattr(self.query_alias, self.user_alias) == user_id
if hasattr(self.query_alias, self.user_alias)
else False
)
else:
param_sql_list.append(False)
param_sql_list = list(dict.fromkeys(param_sql_list))
param_sql = or_(*param_sql_list)
return param_sql
def DataScopeDependency( # noqa: N802
query_alias: Base,
user_alias: str | None = 'user_id',
dept_alias: str | None = 'dept_id',
) -> params.Depends:
"""
当前用户数据权限依赖
:param query_alias: 所要查询表对应的sqlalchemy模型类不可为空
:param user_alias: 用户id字段别名默认为'user_id'
:param dept_alias: 部门id字段别名默认为'dept_id'
:return: 当前用户数据权限依赖
"""
return Depends(GetDataScope(query_alias, user_alias, dept_alias))