diff --git a/backend/app/admin/api/v1/sys/user.py b/backend/app/admin/api/v1/sys/user.py index e136fbd0..972e2544 100644 --- a/backend/app/admin/api/v1/sys/user.py +++ b/backend/app/admin/api/v1/sys/user.py @@ -6,13 +6,11 @@ from fastapi import APIRouter, Depends, Path, Query, Request from backend.app.admin.schema.user import ( AddUserParam, - AvatarParam, GetCurrentUserInfoWithRelationDetail, GetUserInfoWithRelationDetail, RegisterUserParam, ResetPasswordParam, UpdateUserParam, - UpdateUserRoleParam, ) from backend.app.admin.service.user_service import user_service from backend.common.pagination import DependsPagination, PageData, paging_data @@ -70,31 +68,6 @@ async def update_user( return response_base.fail() -@router.put( - '/{username}/role', - summary='更新用户角色', - dependencies=[ - Depends(RequestPermission('sys:user:role:edit')), - DependsRBAC, - ], -) -async def update_user_role( - request: Request, username: Annotated[str, Path(description='用户名')], obj: UpdateUserRoleParam -) -> ResponseModel: - await user_service.update_roles(request=request, username=username, obj=obj) - return response_base.success() - - -@router.put('/{username}/avatar', summary='更新头像', dependencies=[DependsJwtAuth]) -async def update_avatar( - request: Request, username: Annotated[str, Path(description='用户名')], avatar: AvatarParam -) -> ResponseModel: - count = await user_service.update_avatar(request=request, username=username, avatar=avatar) - if count > 0: - return response_base.success() - return response_base.fail() - - @router.get( '', summary='分页获取所有用户', diff --git a/backend/app/admin/crud/crud_user.py b/backend/app/admin/crud/crud_user.py index 951d4103..fe0c709a 100644 --- a/backend/app/admin/crud/crud_user.py +++ b/backend/app/admin/crud/crud_user.py @@ -11,10 +11,8 @@ from sqlalchemy_crud_plus import CRUDPlus from backend.app.admin.model import Dept, Role, User from backend.app.admin.schema.user import ( AddUserParam, - AvatarParam, RegisterUserParam, UpdateUserParam, - UpdateUserRoleParam, ) from backend.common.security.jwt import get_hash_password from backend.utils.timezone import timezone @@ -97,14 +95,13 @@ class CRUDUser(CRUDPlus[User]): dict_obj.update({'salt': salt}) new_user = self.model(**dict_obj) - role_list = [] - for role_id in obj.roles: - role_list.append(await db.get(Role, role_id)) - new_user.roles.extend(role_list) + stmt = select(Role).where(Role.id.in_(obj.roles)) + roles = await db.execute(stmt) + new_user.roles = roles.scalars().all() db.add(new_user) - async def update_userinfo(self, db: AsyncSession, input_user: int, obj: UpdateUserParam) -> int: + async def update(self, db: AsyncSession, input_user: User, obj: UpdateUserParam) -> int: """ 更新用户信息 @@ -113,36 +110,14 @@ class CRUDUser(CRUDPlus[User]): :param obj: 更新用户参数 :return: """ - return await self.update_model(db, input_user, obj) + role_ids = obj.roles + del obj.roles + count = await self.update_model(db, input_user.id, obj) - @staticmethod - async def update_role(db: AsyncSession, input_user: User, obj: UpdateUserRoleParam) -> None: - """ - 更新用户角色 - - :param db: 数据库会话 - :param input_user: 用户对象 - :param obj: 更新角色参数 - :return: - """ - for i in list(input_user.roles): - input_user.roles.remove(i) - - role_list = [] - for role_id in obj.roles: - role_list.append(await db.get(Role, role_id)) - input_user.roles.extend(role_list) - - async def update_avatar(self, db: AsyncSession, input_user: int, avatar: AvatarParam) -> int: - """ - 更新用户头像 - - :param db: 数据库会话 - :param input_user: 用户 ID - :param avatar: 头像地址 - :return: - """ - return await self.update_model(db, input_user, {'avatar': str(avatar.url)}) + stmt = select(Role).where(Role.id.in_(role_ids)) + roles = await db.execute(stmt) + input_user.roles = roles.scalars().all() + return count async def delete(self, db: AsyncSession, user_id: int) -> int: """ diff --git a/backend/app/admin/schema/user.py b/backend/app/admin/schema/user.py index 762d0d67..3dfb4a6b 100644 --- a/backend/app/admin/schema/user.py +++ b/backend/app/admin/schema/user.py @@ -55,6 +55,7 @@ class UserInfoSchemaBase(SchemaBase): dept_id: int | None = Field(None, description='部门 ID') username: str = Field(description='用户名') nickname: str = Field(description='昵称') + avatar: HttpUrl | None = Field(None, description='头像') email: EmailStr = Field(examples=['user@example.com'], description='邮箱') phone: CustomPhoneNumber | None = Field(None, description='手机号') @@ -62,19 +63,9 @@ class UserInfoSchemaBase(SchemaBase): class UpdateUserParam(UserInfoSchemaBase): """更新用户参数""" - -class UpdateUserRoleParam(SchemaBase): - """更新用户角色参数""" - roles: list[int] = Field(description='角色 ID 列表') -class AvatarParam(SchemaBase): - """更新头像参数""" - - url: HttpUrl = Field(description='头像 http 地址') - - class GetUserInfoDetail(UserInfoSchemaBase): """用户信息详情""" diff --git a/backend/app/admin/service/user_service.py b/backend/app/admin/service/user_service.py index 97c8bcbd..32e36282 100644 --- a/backend/app/admin/service/user_service.py +++ b/backend/app/admin/service/user_service.py @@ -11,11 +11,9 @@ from backend.app.admin.crud.crud_user import user_dao from backend.app.admin.model import User from backend.app.admin.schema.user import ( AddUserParam, - AvatarParam, RegisterUserParam, ResetPasswordParam, UpdateUserParam, - UpdateUserRoleParam, ) from backend.common.exception import errors from backend.common.security.jwt import get_hash_password, get_token, jwt_decode, password_verify, superuser_verify @@ -152,50 +150,11 @@ class UserService: email = await user_dao.check_email(db, obj.email) if email: raise errors.ForbiddenError(msg='邮箱已注册') - 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 - async def update_roles(*, request: Request, username: str, obj: UpdateUserRoleParam) -> None: - """ - 更新用户角色 - - :param request: FastAPI 请求对象 - :param username: 用户名 - :param obj: 角色更新参数 - :return: - """ - async with async_db_session.begin() as db: - if not request.user.is_superuser and request.user.username != username: - raise errors.ForbiddenError(msg='你只能修改自己的信息') - input_user = await user_dao.get_with_relation(db, username=username) - if not input_user: - raise errors.NotFoundError(msg='用户不存在') for role_id in obj.roles: role = await role_dao.get(db, role_id) if not role: raise errors.NotFoundError(msg='角色不存在') - await user_dao.update_role(db, input_user, obj) - await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{input_user.id}') - - @staticmethod - async def update_avatar(*, request: Request, username: str, avatar: AvatarParam) -> int: - """ - 更新用户头像 - - :param request: FastAPI 请求对象 - :param username: 用户名 - :param avatar: 头像参数 - :return: - """ - async with async_db_session.begin() as db: - if request.user.username != username: - raise errors.AuthorizationError(msg='你只能修改自己的信息') - user = await user_dao.get_by_username(db, username) - if not user: - raise errors.NotFoundError(msg='用户不存在') - count = await user_dao.update_avatar(db, user.id, avatar) + count = await user_dao.update(db, user, obj) await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}') return count