diff --git a/annotation/auth.py b/annotation/auth.py index 2b59d39..22467fc 100644 --- a/annotation/auth.py +++ b/annotation/auth.py @@ -9,6 +9,7 @@ from functools import wraps from fastapi import Request +from config.constant import RedisKeyConfig from controller.login import LoginController from exceptions.exception import PermissionException @@ -53,3 +54,16 @@ async def hasAuth(request: Request, permission: str) -> bool: return True else: return False + + +async def hasAdmin(request: Request, department_id: str) -> bool: + """ + 判断是否有管理员权限 + """ + permissions = [] + if ids := await request.app.state.redis.get(f'{RedisKeyConfig.SYSTEM_CONFIG.key}:permission_departments'): + permissions = eval(ids) + if department_id in permissions: + return True + else: + return False diff --git a/api/permission.py b/api/permission.py index 853fc2c..0938f82 100644 --- a/api/permission.py +++ b/api/permission.py @@ -10,7 +10,7 @@ from typing import Optional from fastapi import APIRouter, Depends, Path, Query, Request from fastapi.responses import JSONResponse -from annotation.auth import Auth +from annotation.auth import Auth, hasAdmin from annotation.log import Log from config.constant import BusinessType, RedisKeyConfig from controller.login import LoginController @@ -51,6 +51,7 @@ async def add_permission(request: Request, params: AddPermissionParams): leave_transition=params.leave_transition, fixed_tag=params.fixed_tag, hidden_tag=params.hidden_tag, + is_admin=params.is_admin ) if permission: # 更新用户信息缓存 @@ -114,6 +115,7 @@ async def update_permission(request: Request, params: AddPermissionParams, id: s permission.leave_transition = params.leave_transition permission.fixed_tag = params.fixed_tag permission.hidden_tag = params.hidden_tag + permission.is_admin = params.is_admin await permission.save() # 更新用户信息缓存 userInfos = await request.app.state.redis.keys(f'{RedisKeyConfig.USER_INFO.key}*') @@ -161,6 +163,7 @@ async def get_permission(request: Request, id: str = Path(description="权限ID" fixed_tag="fixed_tag", show_link="show_link", show_parent="show_parent", + is_admin="is_admin" ) return Response.success(msg="查询权限详情成功!", data=permission) else: @@ -195,7 +198,9 @@ async def get_permission_list( enterTransition: Optional[str] = Query(default=None, description="进场动画"), leaveTransition: Optional[str] = Query(default=None, description="离场动画"), fixedTag: Optional[bool] = Query(default=None, description="固定标签页"), - hiddenTag: Optional[bool] = Query(default=None, description="隐藏标签页") + hiddenTag: Optional[bool] = Query(default=None, description="隐藏标签页"), + isAdmin: Optional[bool] = Query(default=None, description="是否为管理专属页面"), + current_user: dict = Depends(LoginController.get_current_user), ): filterArgs = { f'{k}__contains': v for k, v in { @@ -219,9 +224,13 @@ async def get_permission_list( "enter_transition": enterTransition, "leave_transition": leaveTransition, "fixed_tag": fixedTag, - "hidden_tag": hiddenTag + "hidden_tag": hiddenTag, + "is_admin": isAdmin }.items() if v } + department_id = current_user.get("department_id", "") + if not await hasAdmin(request, department_id): + filterArgs["is_admin"] = False total = await Permission.filter(**filterArgs, del_flag=1).count() result = await Permission.filter(**filterArgs, del_flag=1).offset((page - 1) * pageSize).limit(pageSize).order_by( 'rank').values( @@ -250,7 +259,8 @@ async def get_permission_list( hidden_tag="hidden_tag", fixed_tag="fixed_tag", show_link="show_link", - show_parent="show_parent" + show_parent="show_parent", + is_admin="is_admin" ) return Response.success(data={ "total": total, diff --git a/api/role.py b/api/role.py index 8d11a5e..cfeeb43 100644 --- a/api/role.py +++ b/api/role.py @@ -10,7 +10,7 @@ from typing import Optional from fastapi import APIRouter, Depends, Path, Query, Request from fastapi.responses import JSONResponse -from annotation.auth import Auth, hasAuth +from annotation.auth import Auth, hasAuth, hasAdmin from annotation.log import Log from config.constant import BusinessType, RedisKeyConfig from controller.login import LoginController @@ -235,6 +235,11 @@ async def add_role_permission(request: Request, params: AddRolePermissionParams, id: str = Path(..., description="角色ID"), current_user: dict = Depends(LoginController.get_current_user)): sub_departments = current_user.get("sub_departments") + if await hasAdmin(request, current_user.get("department_id")): + department_permissions = await Permission.filter(del_flag=1).values("id") + else: + department_permissions = await Permission.filter(is_admin=False, del_flag=1).values("id") + department_permissions = filterKeyValues(department_permissions, "id") if role := await Role.get_or_none(id=id, del_flag=1, department__id__in=sub_departments): # 已有角色权限 rolePermissions = await RolePermission.filter(role_id=id, del_flag=1).values("permission_id") @@ -243,6 +248,8 @@ async def add_role_permission(request: Request, params: AddRolePermissionParams, add_list = set(params.permission_ids).difference(set(rolePermissions)) # 循环添加角色权限 for item in add_list: + if item not in department_permissions: + continue permission = await Permission.get_or_none(id=item, del_flag=1) if permission: await RolePermission.create( @@ -294,6 +301,11 @@ async def update_role_permission(request: Request, params: AddRolePermissionPara id: str = Path(..., description="角色ID"), current_user: dict = Depends(LoginController.get_current_user)): sub_departments = current_user.get("sub_departments") + if await hasAdmin(request, current_user.get("department_id")): + department_permissions = await Permission.filter(del_flag=1).values("id") + else: + department_permissions = await Permission.filter(is_admin=False, del_flag=1).values("id") + department_permissions = filterKeyValues(department_permissions, "id") if role := await Role.get_or_none(id=id, del_flag=1, department__id__in=sub_departments): # 已有角色权限 rolePermissions = await RolePermission.filter(role_id=role.id, del_flag=1).values("permission_id") @@ -307,6 +319,8 @@ async def update_role_permission(request: Request, params: AddRolePermissionPara await RolePermission.filter(role_id=id, permission_id=item, del_flag=1).update(del_flag=0) # 循环添加角色权限 for item in add_list: + if item not in department_permissions: + continue await RolePermission.create(role_id=id, permission_id=item) # 更新用户信息缓存 userInfos = await request.app.state.redis.keys(f'{RedisKeyConfig.USER_INFO.key}*') diff --git a/api/user.py b/api/user.py index 16e97dd..31d4bf0 100644 --- a/api/user.py +++ b/api/user.py @@ -443,7 +443,7 @@ async def reset_user_password(request: Request, params: ResetPasswordParams, id: @userAPI.post("/updateBaseUserInfo", response_model=BaseResponse, response_class=JSONResponse, summary="更新基础个人信息") @Log(title="更新基础个人信息", business_type=BusinessType.UPDATE) -async def update_base_userinfo(params: UpdateBaseUserInfoParams, request: Request, +async def update_base_userinfo(request: Request, params: UpdateBaseUserInfoParams, current_user: dict = Depends(LoginController.get_current_user)): user = await User.get_or_none(id=current_user.get("id"), del_flag=1) if user: @@ -485,10 +485,10 @@ async def update_user_phone(request: Request, password: str = Form(description=" password = await Password.get_password_hash(password) if user.password != password: return Response.error("更改失败,请正确输入旧密码") - phoneStatus = await User.filter(phone=phone,del_flag=1).count() + phoneStatus = await User.filter(phone=phone, del_flag=1).count() if phoneStatus: - return Response.error( f"更改失败,手机号:{phone}已绑定其他账号!") - user.phone=phone + return Response.error(f"更改失败,手机号:{phone}已绑定其他账号!") + user.phone = phone await user.save() if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:{user.id}'): await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:{user.id}') @@ -500,15 +500,16 @@ async def update_user_phone(request: Request, password: str = Form(description=" @userAPI.post("/updateEmail", response_class=JSONResponse, response_model=BaseResponse, summary="用户更新邮箱") @Log(title="用户更新邮箱", business_type=BusinessType.UPDATE) async def update_user_email(request: Request, password: str = Form(description="用户密码"), - email: str = Form(description="用户邮箱"),current_user: dict = Depends(LoginController.get_current_user)): - if user:=await User.get_or_none(id=current_user.get("id"),del_flag=1): + email: str = Form(description="用户邮箱"), + current_user: dict = Depends(LoginController.get_current_user)): + if user := await User.get_or_none(id=current_user.get("id"), del_flag=1): password = await Password.get_password_hash(password) if user.password != password: return Response.error("更改失败,请正确输入旧密码") - emailStatus = await User.filter(email=email,del_flag=1).count() + emailStatus = await User.filter(email=email, del_flag=1).count() if emailStatus: return Response.error(f"更改失败,邮箱:{email}已绑定其他账号!") - user.email=email + user.email = email await user.save() if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:{user.id}'): await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:{user.id}') diff --git a/models/permission.py b/models/permission.py index 2ea5342..150a567 100644 --- a/models/permission.py +++ b/models/permission.py @@ -280,6 +280,18 @@ class Permission(BaseModel): - 映射到数据库字段 show_parent。 """ + is_admin = fields.BooleanField( + default=False, + description="是否为管理专属页面", + source_field="is_admin" # 映射到数据库字段 is_admin + ) + """ + 是否为管理专属页面。 + - 是否为管理专属页面,仅管理员可见。 + - 默认为 False。 + - 映射到数据库字段 is_admin。 + """ + class Meta: table = "permission" # 数据库表名 table_description = "权限表" # 表描述 diff --git a/schemas/permission.py b/schemas/permission.py index 0275f3a..afe499f 100644 --- a/schemas/permission.py +++ b/schemas/permission.py @@ -43,6 +43,7 @@ class PermissionInfo(BaseModel): fixed_tag: bool = Field(default=False, description="固定标签页") show_link: bool = Field(default=True, description="显示菜单") show_parent: bool = Field(default=True, description="显示父级菜单") + is_admin: bool = Field(default=False, description="是否为管理专属页面") class Config: json_schema_extra = { @@ -72,7 +73,8 @@ class PermissionInfo(BaseModel): "hidden_tag": False, "fixed_tag": False, "show_link": True, - "show_parent": True + "show_parent": True, + "is_admin": False } } @@ -109,6 +111,7 @@ class AddPermissionParams(BaseModel): show_parent: bool = Field(default=True, description="显示父级菜单") parent_id: str = Field(default="", max_length=36, description="父级菜单ID") menu_type: int = Field(default=0, description="菜单类型") + is_admin: bool = Field(default=False, description="是否为管理专属页面") class Config: json_schema_extra = { @@ -133,7 +136,8 @@ class AddPermissionParams(BaseModel): "show_link": True, "show_parent": True, "parent_id": "", - "menu_type": 0 + "menu_type": 0, + "is_admin": False } } diff --git a/schemas/user.py b/schemas/user.py index e0d66f3..3794bc6 100644 --- a/schemas/user.py +++ b/schemas/user.py @@ -6,7 +6,6 @@ # @Software : PyCharm # @Comment : 本程序 from datetime import datetime -from enum import IntEnum from typing import Optional, List from uuid import UUID @@ -16,11 +15,6 @@ from pydantic_validation_decorator import Xss, NotBlank, Size, Network from schemas.common import BaseResponse, ListQueryResult -class Gender(IntEnum): - MAN = 0 - WOMAN = 1 - - class UserBase(BaseModel): """ 用户表基础模型。 @@ -399,7 +393,7 @@ class UpdateBaseUserInfoParams(BaseModel): """修改基础信息参数""" name: str """姓名""" - gender: Gender + gender: int """性别""" class Config: