From 40a8c7346170d3ed8763275973ed6fe546d2bff8 Mon Sep 17 00:00:00 2001 From: insistence <3055204202@qq.com> Date: Thu, 11 Jul 2024 22:24:58 +0800 Subject: [PATCH] =?UTF-8?q?style:=20=E4=BD=BF=E7=94=A8ruff=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E4=BC=98=E5=8C=96=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/user_controller.py | 267 ++++++--- .../module_admin/dao/user_dao.py | 522 +++++++++++------- .../module_admin/entity/vo/user_vo.py | 38 +- .../module_admin/service/user_service.py | 193 ++++--- 4 files changed, 669 insertions(+), 351 deletions(-) diff --git a/ruoyi-fastapi-backend/module_admin/controller/user_controller.py b/ruoyi-fastapi-backend/module_admin/controller/user_controller.py index 28bea7c..2ee6e70 100644 --- a/ruoyi-fastapi-backend/module_admin/controller/user_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/user_controller.py @@ -1,50 +1,86 @@ -from fastapi import APIRouter, Request -from fastapi import Depends, File, Query +import os +from datetime import datetime +from fastapi import APIRouter, Depends, File, Query, Request, UploadFile +from sqlalchemy.ext.asyncio import AsyncSession +from typing import Optional, Union from pydantic_validation_decorator import ValidateFields from config.get_db import get_db from config.env import UploadConfig +from module_admin.annotation.log_annotation import log_decorator +from module_admin.aspect.data_scope import GetDataScope +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.entity.vo.dept_vo import DeptModel +from module_admin.entity.vo.user_vo import ( + AddUserModel, + CrudUserRoleModel, + CurrentUserModel, + DeleteUserModel, + EditUserModel, + ResetPasswordModel, + ResetUserModel, + UserDetailModel, + UserInfoModel, + UserModel, + UserPageQueryModel, + UserProfileModel, + UserRoleQueryModel, + UserRoleResponseModel, +) from module_admin.service.login_service import LoginService -from module_admin.service.user_service import * +from module_admin.service.user_service import UserService from module_admin.service.role_service import RoleService from module_admin.service.dept_service import DeptService -from module_admin.aspect.interface_auth import CheckUserInterfaceAuth -from module_admin.aspect.data_scope import GetDataScope -from module_admin.annotation.log_annotation import log_decorator from config.enums import BusinessType -from utils.page_util import PageResponseModel -from utils.response_util import * -from utils.log_util import * from utils.common_util import bytes2file_response +from utils.log_util import logger +from utils.page_util import PageResponseModel +from utils.pwd_util import PwdUtil +from utils.response_util import ResponseUtil from utils.upload_util import UploadUtil userController = APIRouter(prefix='/system/user', dependencies=[Depends(LoginService.get_current_user)]) -@userController.get("/deptTree", dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))]) -async def get_system_dept_tree(request: Request, query_db: AsyncSession = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))): +@userController.get('/deptTree', dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))]) +async def get_system_dept_tree( + request: Request, query_db: AsyncSession = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept')) +): dept_query_result = await DeptService.get_dept_tree_services(query_db, DeptModel(**{}), data_scope_sql) logger.info('获取成功') return ResponseUtil.success(data=dept_query_result) -@userController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))]) -async def get_system_user_list(request: Request, user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_query), query_db: AsyncSession = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))): +@userController.get( + '/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))] +) +async def get_system_user_list( + request: Request, + user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_query), + query_db: AsyncSession = Depends(get_db), + data_scope_sql: str = Depends(GetDataScope('SysUser')), +): # 获取分页数据 - user_page_query_result = await UserService.get_user_list_services(query_db, user_page_query, data_scope_sql, is_page=True) + user_page_query_result = await UserService.get_user_list_services( + query_db, user_page_query, data_scope_sql, is_page=True + ) logger.info('获取成功') return ResponseUtil.success(model_content=user_page_query_result) -@userController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:user:add'))]) +@userController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:user:add'))]) @ValidateFields(validate_model='add_user') @log_decorator(title='用户管理', business_type=BusinessType.INSERT) -async def add_system_user(request: Request, add_user: AddUserModel, query_db: AsyncSession = Depends(get_db), - current_user: CurrentUserModel = Depends(LoginService.get_current_user), - dept_data_scope_sql: str = Depends(GetDataScope('SysDept')), - role_data_scope_sql: str = Depends(GetDataScope('SysDept'))): +async def add_system_user( + request: Request, + add_user: AddUserModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + dept_data_scope_sql: str = Depends(GetDataScope('SysDept')), + role_data_scope_sql: str = Depends(GetDataScope('SysDept')), +): if not current_user.user.admin: await DeptService.check_dept_data_scope_services(query_db, add_user.dept_id, dept_data_scope_sql) await RoleService.check_role_data_scope_services(query_db, ','.join(add_user.role_ids), role_data_scope_sql) @@ -59,14 +95,18 @@ async def add_system_user(request: Request, add_user: AddUserModel, query_db: As return ResponseUtil.success(msg=add_user_result.message) -@userController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))]) +@userController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))]) @ValidateFields(validate_model='edit_user') @log_decorator(title='用户管理', business_type=BusinessType.UPDATE) -async def edit_system_user(request: Request, edit_user: EditUserModel, query_db: AsyncSession = Depends(get_db), - current_user: CurrentUserModel = Depends(LoginService.get_current_user), - user_data_scope_sql: str = Depends(GetDataScope('SysUser')), - dept_data_scope_sql: str = Depends(GetDataScope('SysDept')), - role_data_scope_sql: str = Depends(GetDataScope('SysDept'))): +async def edit_system_user( + request: Request, + edit_user: EditUserModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + user_data_scope_sql: str = Depends(GetDataScope('SysUser')), + dept_data_scope_sql: str = Depends(GetDataScope('SysDept')), + role_data_scope_sql: str = Depends(GetDataScope('SysDept')), +): await UserService.check_user_allowed_services(edit_user) if not current_user.user.admin: await UserService.check_user_data_scope_services(query_db, edit_user.user_id, user_data_scope_sql) @@ -80,9 +120,15 @@ async def edit_system_user(request: Request, edit_user: EditUserModel, query_db: return ResponseUtil.success(msg=edit_user_result.message) -@userController.delete("/{user_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:user:remove'))]) +@userController.delete('/{user_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:user:remove'))]) @log_decorator(title='用户管理', business_type=BusinessType.DELETE) -async def delete_system_user(request: Request, user_ids: str, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user), data_scope_sql: str = Depends(GetDataScope('SysUser'))): +async def delete_system_user( + request: Request, + user_ids: str, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + data_scope_sql: str = Depends(GetDataScope('SysUser')), +): user_id_list = user_ids.split(',') if current_user.user.user_id in user_id_list: logger.warning('当前登录用户不能删除') @@ -92,20 +138,22 @@ async def delete_system_user(request: Request, user_ids: str, query_db: AsyncSes await UserService.check_user_allowed_services(UserModel(userId=int(user_id))) if not current_user.user.admin: await UserService.check_user_data_scope_services(query_db, int(user_id), data_scope_sql) - delete_user = DeleteUserModel( - userIds=user_ids, - updateBy=current_user.user.user_name, - updateTime=datetime.now() - ) + delete_user = DeleteUserModel(userIds=user_ids, updateBy=current_user.user.user_name, updateTime=datetime.now()) delete_user_result = await UserService.delete_user_services(query_db, delete_user) logger.info(delete_user_result.message) return ResponseUtil.success(msg=delete_user_result.message) -@userController.put("/resetPwd", dependencies=[Depends(CheckUserInterfaceAuth('system:user:resetPwd'))]) +@userController.put('/resetPwd', dependencies=[Depends(CheckUserInterfaceAuth('system:user:resetPwd'))]) @log_decorator(title='用户管理', business_type=BusinessType.UPDATE) -async def reset_system_user_pwd(request: Request, reset_user: EditUserModel, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user), data_scope_sql: str = Depends(GetDataScope('SysUser'))): +async def reset_system_user_pwd( + request: Request, + reset_user: EditUserModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + data_scope_sql: str = Depends(GetDataScope('SysUser')), +): await UserService.check_user_allowed_services(reset_user) if not current_user.user.admin: await UserService.check_user_data_scope_services(query_db, reset_user.user_id, data_scope_sql) @@ -114,7 +162,7 @@ async def reset_system_user_pwd(request: Request, reset_user: EditUserModel, que password=PwdUtil.get_password_hash(reset_user.password), updateBy=current_user.user.user_name, updateTime=datetime.now(), - type='pwd' + type='pwd', ) edit_user_result = await UserService.edit_user_services(query_db, edit_user) logger.info(edit_user_result.message) @@ -122,9 +170,15 @@ async def reset_system_user_pwd(request: Request, reset_user: EditUserModel, que return ResponseUtil.success(msg=edit_user_result.message) -@userController.put("/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))]) +@userController.put('/changeStatus', dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))]) @log_decorator(title='用户管理', business_type=BusinessType.UPDATE) -async def change_system_user_status(request: Request, change_user: EditUserModel, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user), data_scope_sql: str = Depends(GetDataScope('SysUser'))): +async def change_system_user_status( + request: Request, + change_user: EditUserModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + data_scope_sql: str = Depends(GetDataScope('SysUser')), +): await UserService.check_user_allowed_services(change_user) if not current_user.user.admin: await UserService.check_user_data_scope_services(query_db, change_user.user_id, data_scope_sql) @@ -133,7 +187,7 @@ async def change_system_user_status(request: Request, change_user: EditUserModel status=change_user.status, updateBy=current_user.user.user_name, updateTime=datetime.now(), - type='status' + type='status', ) edit_user_result = await UserService.edit_user_services(query_db, edit_user) logger.info(edit_user_result.message) @@ -141,17 +195,31 @@ async def change_system_user_status(request: Request, change_user: EditUserModel return ResponseUtil.success(msg=edit_user_result.message) -@userController.get("/profile", response_model=UserProfileModel) -async def query_detail_system_user(request: Request, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): +@userController.get('/profile', response_model=UserProfileModel) +async def query_detail_system_user_profile( + request: Request, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): profile_user_result = await UserService.user_profile_services(query_db, current_user.user.user_id) logger.info(f'获取user_id为{current_user.user.user_id}的信息成功') return ResponseUtil.success(model_content=profile_user_result) -@userController.get("/{user_id}", response_model=UserDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))]) -@userController.get("/", response_model=UserDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))]) -async def query_detail_system_user(request: Request, user_id: Optional[Union[int, str]] = '', query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user), data_scope_sql: str = Depends(GetDataScope('SysUser'))): +@userController.get( + '/{user_id}', response_model=UserDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))] +) +@userController.get( + '/', response_model=UserDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))] +) +async def query_detail_system_user( + request: Request, + user_id: Optional[Union[int, str]] = '', + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + data_scope_sql: str = Depends(GetDataScope('SysUser')), +): if user_id and not current_user.user.admin: await UserService.check_user_data_scope_services(query_db, user_id, data_scope_sql) detail_user_result = await UserService.user_detail_services(query_db, user_id) @@ -160,11 +228,18 @@ async def query_detail_system_user(request: Request, user_id: Optional[Union[int return ResponseUtil.success(model_content=detail_user_result) -@userController.post("/profile/avatar") +@userController.post('/profile/avatar') @log_decorator(title='个人信息', business_type=BusinessType.UPDATE) -async def change_system_user_profile_avatar(request: Request, avatarfile: bytes = File(), query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): +async def change_system_user_profile_avatar( + request: Request, + avatarfile: bytes = File(), + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): if avatarfile: - relative_path = f'avatar/{datetime.now().strftime("%Y")}/{datetime.now().strftime("%m")}/{datetime.now().strftime("%d")}' + relative_path = ( + f'avatar/{datetime.now().strftime("%Y")}/{datetime.now().strftime("%m")}/{datetime.now().strftime("%d")}' + ) dir_path = os.path.join(UploadConfig.UPLOAD_PATH, relative_path) try: os.makedirs(dir_path) @@ -179,7 +254,7 @@ async def change_system_user_profile_avatar(request: Request, avatarfile: bytes avatar=f'{UploadConfig.UPLOAD_PREFIX}/{relative_path}/{avatar_name}', updateBy=current_user.user.user_name, updateTime=datetime.now(), - type='avatar' + type='avatar', ) edit_user_result = await UserService.edit_user_services(query_db, edit_user) logger.info(edit_user_result.message) @@ -188,22 +263,23 @@ async def change_system_user_profile_avatar(request: Request, avatarfile: bytes return ResponseUtil.failure(msg='上传图片异常,请联系管理员') -@userController.put("/profile") +@userController.put('/profile') @log_decorator(title='个人信息', business_type=BusinessType.UPDATE) -async def change_system_user_profile_info(request: Request, user_info: UserInfoModel, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): +async def change_system_user_profile_info( + request: Request, + user_info: UserInfoModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): edit_user = EditUserModel( - **user_info.model_dump( - exclude_unset=True, - by_alias=True, - exclude={'role_ids', 'post_ids'} - ), + **user_info.model_dump(exclude_unset=True, by_alias=True, exclude={'role_ids', 'post_ids'}), userId=current_user.user.user_id, userName=current_user.user.user_name, updateBy=current_user.user.user_name, updateTime=datetime.now(), roleIds=current_user.user.role_ids.split(',') if current_user.user.role_ids else [], postIds=current_user.user.post_ids.split(',') if current_user.user.post_ids else [], - role=current_user.user.role + role=current_user.user.role, ) edit_user_result = await UserService.edit_user_services(query_db, edit_user) logger.info(edit_user_result.message) @@ -211,15 +287,20 @@ async def change_system_user_profile_info(request: Request, user_info: UserInfoM return ResponseUtil.success(msg=edit_user_result.message) -@userController.put("/profile/updatePwd") +@userController.put('/profile/updatePwd') @log_decorator(title='个人信息', business_type=BusinessType.UPDATE) -async def reset_system_user_password(request: Request, reset_password: ResetPasswordModel = Depends(ResetPasswordModel.as_query), query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): +async def reset_system_user_password( + request: Request, + reset_password: ResetPasswordModel = Depends(ResetPasswordModel.as_query), + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): reset_user = ResetUserModel( userId=current_user.user.user_id, oldPassword=reset_password.old_password, password=PwdUtil.get_password_hash(reset_password.new_password), updateBy=current_user.user.user_name, - updateTime=datetime.now() + updateTime=datetime.now(), ) reset_user_result = await UserService.reset_user_services(query_db, reset_user) logger.info(reset_user_result.message) @@ -227,21 +308,26 @@ async def reset_system_user_password(request: Request, reset_password: ResetPass return ResponseUtil.success(msg=reset_user_result.message) -@userController.post("/importData", dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))]) +@userController.post('/importData', dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))]) @log_decorator(title='用户管理', business_type=BusinessType.IMPORT) -async def batch_import_system_user(request: Request, file: UploadFile = File(...), - update_support: bool = Query(alias='updateSupport'), - query_db: AsyncSession = Depends(get_db), - current_user: CurrentUserModel = Depends(LoginService.get_current_user), - user_data_scope_sql: str = Depends(GetDataScope('SysUser')), - dept_data_scope_sql: str = Depends(GetDataScope('SysDept'))): - batch_import_result = await UserService.batch_import_user_services(request, query_db, file, update_support, current_user, user_data_scope_sql, dept_data_scope_sql) +async def batch_import_system_user( + request: Request, + file: UploadFile = File(...), + update_support: bool = Query(alias='updateSupport'), + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + user_data_scope_sql: str = Depends(GetDataScope('SysUser')), + dept_data_scope_sql: str = Depends(GetDataScope('SysDept')), +): + batch_import_result = await UserService.batch_import_user_services( + request, query_db, file, update_support, current_user, user_data_scope_sql, dept_data_scope_sql + ) logger.info(batch_import_result.message) return ResponseUtil.success(msg=batch_import_result.message) -@userController.post("/importTemplate", dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))]) +@userController.post('/importTemplate', dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))]) async def export_system_user_template(request: Request, query_db: AsyncSession = Depends(get_db)): user_import_template_result = await UserService.get_user_import_template_services() logger.info('获取成功') @@ -249,37 +335,60 @@ async def export_system_user_template(request: Request, query_db: AsyncSession = return ResponseUtil.streaming(data=bytes2file_response(user_import_template_result)) -@userController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:user:export'))]) +@userController.post('/export', dependencies=[Depends(CheckUserInterfaceAuth('system:user:export'))]) @log_decorator(title='用户管理', business_type=BusinessType.EXPORT) -async def export_system_user_list(request: Request, user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_form), query_db: AsyncSession = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))): +async def export_system_user_list( + request: Request, + user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_form), + query_db: AsyncSession = Depends(get_db), + data_scope_sql: str = Depends(GetDataScope('SysUser')), +): # 获取全量数据 - user_query_result = await UserService.get_user_list_services(query_db, user_page_query, data_scope_sql, is_page=False) + user_query_result = await UserService.get_user_list_services( + query_db, user_page_query, data_scope_sql, is_page=False + ) user_export_result = await UserService.export_user_list_services(user_query_result) logger.info('导出成功') return ResponseUtil.streaming(data=bytes2file_response(user_export_result)) -@userController.get("/authRole/{user_id}", response_model=UserRoleResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))]) +@userController.get( + '/authRole/{user_id}', + response_model=UserRoleResponseModel, + dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))], +) async def get_system_allocated_role_list(request: Request, user_id: int, query_db: AsyncSession = Depends(get_db)): user_role_query = UserRoleQueryModel(userId=user_id) - user_role_allocated_query_result = await UserService.get_user_role_allocated_list_services(query_db, user_role_query) + user_role_allocated_query_result = await UserService.get_user_role_allocated_list_services( + query_db, user_role_query + ) logger.info('获取成功') return ResponseUtil.success(model_content=user_role_allocated_query_result) -@userController.put("/authRole", response_model=UserRoleResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))]) +@userController.put( + '/authRole', + response_model=UserRoleResponseModel, + dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))], +) @log_decorator(title='用户管理', business_type=BusinessType.GRANT) -async def update_system_role_user(request: Request, user_id: int = Query(alias='userId'), role_ids: str = Query(alias='roleIds'), - query_db: AsyncSession = Depends(get_db), - current_user: CurrentUserModel = Depends(LoginService.get_current_user), - user_data_scope_sql: str = Depends(GetDataScope('SysUser')), - role_data_scope_sql: str = Depends(GetDataScope('SysDept'))): +async def update_system_role_user( + request: Request, + user_id: int = Query(alias='userId'), + role_ids: str = Query(alias='roleIds'), + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), + user_data_scope_sql: str = Depends(GetDataScope('SysUser')), + role_data_scope_sql: str = Depends(GetDataScope('SysDept')), +): if not current_user.user.admin: await UserService.check_user_data_scope_services(query_db, user_id, user_data_scope_sql) await RoleService.check_role_data_scope_services(query_db, role_ids, role_data_scope_sql) - add_user_role_result = await UserService.add_user_role_services(query_db, CrudUserRoleModel(userId=user_id, roleIds=role_ids)) + add_user_role_result = await UserService.add_user_role_services( + query_db, CrudUserRoleModel(userId=user_id, roleIds=role_ids) + ) logger.info(add_user_role_result.message) return ResponseUtil.success(msg=add_user_role_result.message) diff --git a/ruoyi-fastapi-backend/module_admin/dao/user_dao.py b/ruoyi-fastapi-backend/module_admin/dao/user_dao.py index f75deac..05e47bc 100644 --- a/ruoyi-fastapi-backend/module_admin/dao/user_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/user_dao.py @@ -1,13 +1,20 @@ -from sqlalchemy import select, update, delete, and_, or_, desc, func +from datetime import datetime, time +from sqlalchemy import and_, delete, desc, func, or_, select, update from sqlalchemy.ext.asyncio import AsyncSession -from module_admin.entity.do.user_do import SysUser, SysUserRole, SysUserPost -from module_admin.entity.do.role_do import SysRole, SysRoleDept, SysRoleMenu from module_admin.entity.do.dept_do import SysDept -from module_admin.entity.do.post_do import SysPost from module_admin.entity.do.menu_do import SysMenu -from module_admin.entity.vo.user_vo import * +from module_admin.entity.do.post_do import SysPost +from module_admin.entity.do.role_do import SysRole, SysRoleDept, SysRoleMenu # noqa: F401 +from module_admin.entity.do.user_do import SysUser, SysUserPost, SysUserRole +from module_admin.entity.vo.user_vo import ( + UserModel, + UserPageQueryModel, + UserPostModel, + UserRoleModel, + UserRolePageQueryModel, + UserRoleQueryModel, +) from utils.page_util import PageUtil -from datetime import datetime, time class UserDao: @@ -23,12 +30,18 @@ class UserDao: :param user_name: 用户名 :return: 当前用户名的用户信息对象 """ - query_user_info = (await db.execute( - select(SysUser) - .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_name == user_name) - .order_by(desc(SysUser.create_time)) - .distinct() - )).scalars().first() + query_user_info = ( + ( + await db.execute( + select(SysUser) + .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_name == user_name) + .order_by(desc(SysUser.create_time)) + .distinct() + ) + ) + .scalars() + .first() + ) return query_user_info @@ -40,15 +53,23 @@ class UserDao: :param user: 用户参数 :return: 当前用户参数的用户信息对象 """ - query_user_info = (await db.execute( - select(SysUser) - .where(SysUser.del_flag == '0', - SysUser.user_name == user.user_name if user.user_name else True, - SysUser.phonenumber == user.phonenumber if user.phonenumber else True, - SysUser.email == user.email if user.email else True) - .order_by(desc(SysUser.create_time)) - .distinct() - )).scalars().first() + query_user_info = ( + ( + await db.execute( + select(SysUser) + .where( + SysUser.del_flag == '0', + SysUser.user_name == user.user_name if user.user_name else True, + SysUser.phonenumber == user.phonenumber if user.phonenumber else True, + SysUser.email == user.email if user.email else True, + ) + .order_by(desc(SysUser.create_time)) + .distinct() + ) + ) + .scalars() + .first() + ) return query_user_info @@ -60,62 +81,100 @@ class UserDao: :param user_id: 用户id :return: 当前user_id的用户信息对象 """ - query_user_basic_info = (await db.execute( - select(SysUser) - .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) - .distinct() - )).scalars().first() - query_user_dept_info = (await db.execute( - select(SysDept) - .select_from(SysUser) - .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) - .join(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == '0', SysDept.del_flag == '0')) - .distinct() - )).scalars().first() - query_user_role_info = (await db.execute( - select(SysRole) - .select_from(SysUser) - .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) - .join(SysUserRole, SysUser.user_id == SysUserRole.user_id, isouter=True) - .join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0')) - .distinct() - )).scalars().all() - query_user_post_info = (await db.execute( - select(SysPost) - .select_from(SysUser) - .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) - .join(SysUserPost, SysUser.user_id == SysUserPost.user_id, isouter=True) - .join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == '0')) - .distinct() - )).scalars().all() - role_id_list = [item.role_id for item in query_user_role_info] - if 1 in role_id_list: - query_user_menu_info = (await db.execute( - select(SysMenu) - .where(SysMenu.status == '0') + query_user_basic_info = ( + ( + await db.execute( + select(SysUser) + .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) .distinct() - )).scalars().all() - else: - query_user_menu_info = (await db.execute( - select(SysMenu) + ) + ) + .scalars() + .first() + ) + query_user_dept_info = ( + ( + await db.execute( + select(SysDept) + .select_from(SysUser) + .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) + .join( + SysDept, + and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == '0', SysDept.del_flag == '0'), + ) + .distinct() + ) + ) + .scalars() + .first() + ) + query_user_role_info = ( + ( + await db.execute( + select(SysRole) .select_from(SysUser) .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) .join(SysUserRole, SysUser.user_id == SysUserRole.user_id, isouter=True) - .join(SysRole, - and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0'), - isouter=True) - .join(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id, isouter=True) - .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == '0')) - .order_by(SysMenu.order_num) + .join( + SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0'), + ) + .distinct() + ) + ) + .scalars() + .all() + ) + query_user_post_info = ( + ( + await db.execute( + select(SysPost) + .select_from(SysUser) + .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) + .join(SysUserPost, SysUser.user_id == SysUserPost.user_id, isouter=True) + .join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == '0')) .distinct() - )).scalars().all() + ) + ) + .scalars() + .all() + ) + role_id_list = [item.role_id for item in query_user_role_info] + if 1 in role_id_list: + query_user_menu_info = ( + (await db.execute(select(SysMenu).where(SysMenu.status == '0').distinct())).scalars().all() + ) + else: + query_user_menu_info = ( + ( + await db.execute( + select(SysMenu) + .select_from(SysUser) + .where(SysUser.status == '0', SysUser.del_flag == '0', SysUser.user_id == user_id) + .join(SysUserRole, SysUser.user_id == SysUserRole.user_id, isouter=True) + .join( + SysRole, + and_( + SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0' + ), + isouter=True, + ) + .join(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id, isouter=True) + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == '0')) + .order_by(SysMenu.order_num) + .distinct() + ) + ) + .scalars() + .all() + ) results = dict( user_basic_info=query_user_basic_info, user_dept_info=query_user_dept_info, user_role_info=query_user_role_info, user_post_info=query_user_post_info, - user_menu_info=query_user_menu_info + user_menu_info=query_user_menu_info, ) return results @@ -128,58 +187,92 @@ class UserDao: :param user_id: 用户id :return: 当前user_id的用户信息对象 """ - query_user_basic_info = (await db.execute( - select(SysUser) - .where(SysUser.del_flag == '0', SysUser.user_id == user_id) - .distinct() - )).scalars().first() - query_user_dept_info = (await db.execute( - select(SysDept) - .select_from(SysUser) - .where(SysUser.del_flag == '0', SysUser.user_id == user_id) - .join(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == '0', SysDept.del_flag == '0')) - .distinct() - )).scalars().first() - query_user_role_info = (await db.execute( - select(SysRole) - .select_from(SysUser) - .where(SysUser.del_flag == '0', SysUser.user_id == user_id) - .join(SysUserRole, SysUser.user_id == SysUserRole.user_id, isouter=True) - .join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0')) - .distinct() - )).scalars().all() - query_user_post_info = (await db.execute( - select(SysPost) - .select_from(SysUser) - .where(SysUser.del_flag == '0', SysUser.user_id == user_id) - .join(SysUserPost, SysUser.user_id == SysUserPost.user_id, isouter=True) - .join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == '0')) - .distinct() - )).scalars().all() - query_user_menu_info = (await db.execute( - select(SysMenu) - .select_from(SysUser) - .where(SysUser.del_flag == '0', SysUser.user_id == user_id) - .join(SysUserRole, SysUser.user_id == SysUserRole.user_id, isouter=True) - .join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0'), - isouter=True) - .join(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id, isouter=True) - .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == '0')) - .distinct() - )).scalars().all() + query_user_basic_info = ( + (await db.execute(select(SysUser).where(SysUser.del_flag == '0', SysUser.user_id == user_id).distinct())) + .scalars() + .first() + ) + query_user_dept_info = ( + ( + await db.execute( + select(SysDept) + .select_from(SysUser) + .where(SysUser.del_flag == '0', SysUser.user_id == user_id) + .join( + SysDept, + and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == '0', SysDept.del_flag == '0'), + ) + .distinct() + ) + ) + .scalars() + .first() + ) + query_user_role_info = ( + ( + await db.execute( + select(SysRole) + .select_from(SysUser) + .where(SysUser.del_flag == '0', SysUser.user_id == user_id) + .join(SysUserRole, SysUser.user_id == SysUserRole.user_id, isouter=True) + .join( + SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0'), + ) + .distinct() + ) + ) + .scalars() + .all() + ) + query_user_post_info = ( + ( + await db.execute( + select(SysPost) + .select_from(SysUser) + .where(SysUser.del_flag == '0', SysUser.user_id == user_id) + .join(SysUserPost, SysUser.user_id == SysUserPost.user_id, isouter=True) + .join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == '0')) + .distinct() + ) + ) + .scalars() + .all() + ) + query_user_menu_info = ( + ( + await db.execute( + select(SysMenu) + .select_from(SysUser) + .where(SysUser.del_flag == '0', SysUser.user_id == user_id) + .join(SysUserRole, SysUser.user_id == SysUserRole.user_id, isouter=True) + .join( + SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == '0', SysRole.del_flag == '0'), + isouter=True, + ) + .join(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id, isouter=True) + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == '0')) + .distinct() + ) + ) + .scalars() + .all() + ) results = dict( user_basic_info=query_user_basic_info, user_dept_info=query_user_dept_info, user_role_info=query_user_role_info, user_post_info=query_user_post_info, - user_menu_info=query_user_menu_info + user_menu_info=query_user_menu_info, ) return results @classmethod - async def get_user_list(cls, db: AsyncSession, query_object: UserPageQueryModel, data_scope_sql: str, - is_page: bool = False): + async def get_user_list( + cls, db: AsyncSession, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False + ): """ 根据查询参数获取用户列表信息 :param db: orm对象 @@ -188,27 +281,40 @@ class UserDao: :param is_page: 是否开启分页 :return: 用户列表信息对象 """ - query = select(SysUser, SysDept) \ - .where(SysUser.del_flag == '0', - or_(SysUser.dept_id == query_object.dept_id, SysUser.dept_id.in_( - select(SysDept.dept_id).where(func.find_in_set(query_object.dept_id, SysDept.ancestors)) - )) if query_object.dept_id else True, - SysUser.user_id == query_object.user_id if query_object.user_id is not None else True, - SysUser.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True, - SysUser.nick_name.like(f'%{query_object.nick_name}%') if query_object.nick_name else True, - SysUser.email.like(f'%{query_object.email}%') if query_object.email else True, - SysUser.phonenumber.like(f'%{query_object.phonenumber}%') if query_object.phonenumber else True, - SysUser.status == query_object.status if query_object.status else True, - SysUser.sex == query_object.sex if query_object.sex else True, - SysUser.create_time.between( - datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.begin_time and query_object.end_time else True, - eval(data_scope_sql) - ) \ - .join(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == '0', SysDept.del_flag == '0'), - isouter=True) \ + query = ( + select(SysUser, SysDept) + .where( + SysUser.del_flag == '0', + or_( + SysUser.dept_id == query_object.dept_id, + SysUser.dept_id.in_( + select(SysDept.dept_id).where(func.find_in_set(query_object.dept_id, SysDept.ancestors)) + ), + ) + if query_object.dept_id + else True, + SysUser.user_id == query_object.user_id if query_object.user_id is not None else True, + SysUser.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True, + SysUser.nick_name.like(f'%{query_object.nick_name}%') if query_object.nick_name else True, + SysUser.email.like(f'%{query_object.email}%') if query_object.email else True, + SysUser.phonenumber.like(f'%{query_object.phonenumber}%') if query_object.phonenumber else True, + SysUser.status == query_object.status if query_object.status else True, + SysUser.sex == query_object.sex if query_object.sex else True, + SysUser.create_time.between( + datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)), + ) + if query_object.begin_time and query_object.end_time + else True, + eval(data_scope_sql), + ) + .join( + SysDept, + and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == '0', SysDept.del_flag == '0'), + isouter=True, + ) .distinct() + ) user_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page) return user_list @@ -235,10 +341,7 @@ class UserDao: :param user: 需要更新的用户字典 :return: 编辑校验结果 """ - await db.execute( - update(SysUser), - [user] - ) + await db.execute(update(SysUser), [user]) @classmethod async def delete_user_dao(cls, db: AsyncSession, user: UserModel): @@ -250,8 +353,8 @@ class UserDao: """ await db.execute( update(SysUser) - .where(SysUser.user_id == user.user_id) - .values(del_flag='2', update_by=user.update_by, update_time=user.update_time) + .where(SysUser.user_id == user.user_id) + .values(del_flag='2', update_by=user.update_by, update_time=user.update_time) ) @classmethod @@ -262,22 +365,32 @@ class UserDao: :param query_object: 用户角色查询对象 :return: 用户已分配的角色列表信息 """ - allocated_role_list = (await db.execute( - select(SysRole) - .where(SysRole.del_flag == '0', - SysRole.role_id != 1, - SysRole.role_name == query_object.role_name if query_object.role_name else True, - SysRole.role_key == query_object.role_key if query_object.role_key else True, - SysRole.role_id.in_( - select(SysUserRole.role_id).where(SysUserRole.user_id == query_object.user_id) - )) - .distinct() - )).scalars().all() + allocated_role_list = ( + ( + await db.execute( + select(SysRole) + .where( + SysRole.del_flag == '0', + SysRole.role_id != 1, + SysRole.role_name == query_object.role_name if query_object.role_name else True, + SysRole.role_key == query_object.role_key if query_object.role_key else True, + SysRole.role_id.in_( + select(SysUserRole.role_id).where(SysUserRole.user_id == query_object.user_id) + ), + ) + .distinct() + ) + ) + .scalars() + .all() + ) return allocated_role_list @classmethod - async def get_user_role_allocated_list_by_role_id(cls, db: AsyncSession, query_object: UserRolePageQueryModel, data_scope_sql: str, is_page: bool = False): + async def get_user_role_allocated_list_by_role_id( + cls, db: AsyncSession, query_object: UserRolePageQueryModel, data_scope_sql: str, is_page: bool = False + ): """ 根据角色id获取已分配的用户列表信息 :param db: orm对象 @@ -286,22 +399,28 @@ class UserDao: :param is_page: 是否开启分页 :return: 角色已分配的用户列表信息 """ - query = select(SysUser) \ - .join(SysDept, SysDept.dept_id == SysUser.dept_id, isouter=True) \ - .join(SysUserRole, SysUserRole.user_id == SysUser.user_id, isouter=True) \ - .join(SysRole, SysRole.role_id == SysUserRole.role_id, isouter=True) \ - .where(SysUser.del_flag == '0', - SysUser.user_name == query_object.user_name if query_object.user_name else True, - SysUser.phonenumber == query_object.phonenumber if query_object.phonenumber else True, - SysRole.role_id == query_object.role_id, - eval(data_scope_sql)) \ + query = ( + select(SysUser) + .join(SysDept, SysDept.dept_id == SysUser.dept_id, isouter=True) + .join(SysUserRole, SysUserRole.user_id == SysUser.user_id, isouter=True) + .join(SysRole, SysRole.role_id == SysUserRole.role_id, isouter=True) + .where( + SysUser.del_flag == '0', + SysUser.user_name == query_object.user_name if query_object.user_name else True, + SysUser.phonenumber == query_object.phonenumber if query_object.phonenumber else True, + SysRole.role_id == query_object.role_id, + eval(data_scope_sql), + ) .distinct() + ) allocated_user_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page) return allocated_user_list @classmethod - async def get_user_role_unallocated_list_by_role_id(cls, db: AsyncSession, query_object: UserRolePageQueryModel, data_scope_sql: str, is_page: bool = False): + async def get_user_role_unallocated_list_by_role_id( + cls, db: AsyncSession, query_object: UserRolePageQueryModel, data_scope_sql: str, is_page: bool = False + ): """ 根据角色id获取未分配的用户列表信息 :param db: orm对象 @@ -310,26 +429,31 @@ class UserDao: :param is_page: 是否开启分页 :return: 角色未分配的用户列表信息 """ - query = select(SysUser) \ - .join(SysDept, SysDept.dept_id == SysUser.dept_id, isouter=True) \ - .join(SysUserRole, SysUserRole.user_id == SysUser.user_id, isouter=True) \ - .join(SysRole, SysRole.role_id == SysUserRole.role_id, isouter=True) \ - .where(SysUser.del_flag == '0', - SysUser.user_name == query_object.user_name if query_object.user_name else True, - SysUser.phonenumber == query_object.phonenumber if query_object.phonenumber else True, - or_(SysRole.role_id != query_object.role_id, SysRole.role_id is None), - ~SysUser.user_id.in_( - select(SysUser.user_id) - .select_from(SysUser) - .join(SysUserRole, - and_(SysUserRole.user_id == SysUser.user_id, - SysUserRole.role_id == query_object.role_id) - ) - ), - eval(data_scope_sql)) \ + query = ( + select(SysUser) + .join(SysDept, SysDept.dept_id == SysUser.dept_id, isouter=True) + .join(SysUserRole, SysUserRole.user_id == SysUser.user_id, isouter=True) + .join(SysRole, SysRole.role_id == SysUserRole.role_id, isouter=True) + .where( + SysUser.del_flag == '0', + SysUser.user_name == query_object.user_name if query_object.user_name else True, + SysUser.phonenumber == query_object.phonenumber if query_object.phonenumber else True, + or_(SysRole.role_id != query_object.role_id, SysRole.role_id is None), + ~SysUser.user_id.in_( + select(SysUser.user_id) + .select_from(SysUser) + .join( + SysUserRole, + and_(SysUserRole.user_id == SysUser.user_id, SysUserRole.role_id == query_object.role_id), + ) + ), + eval(data_scope_sql), + ) .distinct() - unallocated_user_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, - is_page) + ) + unallocated_user_list = await PageUtil.paginate( + db, query, query_object.page_num, query_object.page_size, is_page + ) return unallocated_user_list @@ -352,10 +476,7 @@ class UserDao: :param user_role: 用户角色关联对象 :return: """ - await db.execute( - delete(SysUserRole) - .where(SysUserRole.user_id.in_([user_role.user_id])) - ) + await db.execute(delete(SysUserRole).where(SysUserRole.user_id.in_([user_role.user_id]))) @classmethod async def delete_user_role_by_user_and_role_dao(cls, db: AsyncSession, user_role: UserRoleModel): @@ -366,9 +487,10 @@ class UserDao: :return: """ await db.execute( - delete(SysUserRole) - .where(SysUserRole.user_id.in_([user_role.user_id]), - SysUserRole.role_id == user_role.role_id if user_role.role_id else True) + delete(SysUserRole).where( + SysUserRole.user_id.in_([user_role.user_id]), + SysUserRole.role_id == user_role.role_id if user_role.role_id else True, + ) ) @classmethod @@ -379,11 +501,17 @@ class UserDao: :param user_role: 用户角色关联对象 :return: 用户角色关联信息 """ - user_role_info = (await db.execute( - select(SysUserRole) - .where(SysUserRole.user_id == user_role.user_id, SysUserRole.role_id == user_role.role_id) - .distinct() - )).scalars().first() + user_role_info = ( + ( + await db.execute( + select(SysUserRole) + .where(SysUserRole.user_id == user_role.user_id, SysUserRole.role_id == user_role.role_id) + .distinct() + ) + ) + .scalars() + .first() + ) return user_role_info @@ -406,17 +534,17 @@ class UserDao: :param user_post: 用户岗位关联对象 :return: """ - await db.execute( - delete(SysUserPost) - .where(SysUserPost.user_id.in_([user_post.user_id])) - ) + await db.execute(delete(SysUserPost).where(SysUserPost.user_id.in_([user_post.user_id]))) @classmethod async def get_user_dept_info(cls, db: AsyncSession, dept_id: int): - dept_basic_info = (await db.execute( - select(SysDept) - .where(SysDept.dept_id == dept_id, - SysDept.status == '0', - SysDept.del_flag == '0') - )).scalars().first() + dept_basic_info = ( + ( + await db.execute( + select(SysDept).where(SysDept.dept_id == dept_id, SysDept.status == '0', SysDept.del_flag == '0') + ) + ) + .scalars() + .first() + ) return dept_basic_info diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/user_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/user_vo.py index 3613913..67a1d14 100644 --- a/ruoyi-fastapi-backend/module_admin/entity/vo/user_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/user_vo.py @@ -1,20 +1,21 @@ import re -from pydantic import BaseModel, Field, ConfigDict, model_validator +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, model_validator from pydantic.alias_generators import to_camel from pydantic_validation_decorator import Network, NotBlank, Size, Xss -from typing import Union, Optional, List, Literal -from datetime import datetime -from module_admin.entity.vo.role_vo import RoleModel +from typing import List, Literal, Optional, Union +from exceptions.exception import ModelValidatorException +from module_admin.annotation.pydantic_annotation import as_form, as_query from module_admin.entity.vo.dept_vo import DeptModel from module_admin.entity.vo.post_vo import PostModel -from module_admin.annotation.pydantic_annotation import as_query, as_form -from exceptions.exception import ModelValidatorException +from module_admin.entity.vo.role_vo import RoleModel class TokenData(BaseModel): """ token解析结果 """ + user_id: Union[int, None] = Field(default=None, description='用户ID') @@ -22,6 +23,7 @@ class UserModel(BaseModel): """ 用户表对应pydantic模型 """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) user_id: Optional[int] = Field(default=None, description='用户ID') @@ -47,11 +49,11 @@ class UserModel(BaseModel): @model_validator(mode='after') def check_password(self) -> 'UserModel': - pattern = r'''^[^<>"'|\\]+$''' + pattern = r"""^[^<>"'|\\]+$""" if self.password is None or re.match(pattern, self.password): return self else: - raise ModelValidatorException(message="密码不能包含非法字符:< > \" ' \\ |") + raise ModelValidatorException(message='密码不能包含非法字符:< > " \' \\ |') @model_validator(mode='after') def check_admin(self) -> 'UserModel': @@ -92,6 +94,7 @@ class UserRoleModel(BaseModel): """ 用户和角色关联表对应pydantic模型 """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) user_id: Optional[int] = Field(default=None, description='用户ID') @@ -102,6 +105,7 @@ class UserPostModel(BaseModel): """ 用户与岗位关联表对应pydantic模型 """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) user_id: Optional[int] = Field(default=None, description='用户ID') @@ -127,6 +131,7 @@ class UserDetailModel(BaseModel): """ 获取用户详情信息响应模型 """ + model_config = ConfigDict(alias_generator=to_camel) data: Optional[Union[UserInfoModel, None]] = Field(default=None, description='用户信息') @@ -140,6 +145,7 @@ class UserProfileModel(BaseModel): """ 获取个人信息响应模型 """ + model_config = ConfigDict(alias_generator=to_camel) data: Union[UserInfoModel, None] = Field(description='用户信息') @@ -151,6 +157,7 @@ class UserQueryModel(UserModel): """ 用户管理不分页查询模型 """ + begin_time: Optional[str] = Field(default=None, description='开始时间') end_time: Optional[str] = Field(default=None, description='结束时间') @@ -161,6 +168,7 @@ class UserPageQueryModel(UserQueryModel): """ 用户管理分页查询模型 """ + page_num: int = Field(default=1, description='当前页码') page_size: int = Field(default=10, description='每页记录数') @@ -169,6 +177,7 @@ class AddUserModel(UserModel): """ 新增用户模型 """ + role_ids: Optional[List] = Field(default=[], description='角色ID信息') post_ids: Optional[List] = Field(default=[], description='岗位ID信息') type: Optional[str] = Field(default=None, description='操作类型') @@ -178,6 +187,7 @@ class EditUserModel(AddUserModel): """ 编辑用户模型 """ + role: Optional[List] = Field(default=[], description='角色信息') @@ -186,6 +196,7 @@ class ResetPasswordModel(BaseModel): """ 重置密码模型 """ + model_config = ConfigDict(alias_generator=to_camel) old_password: Optional[str] = Field(default=None, description='旧密码') @@ -193,17 +204,18 @@ class ResetPasswordModel(BaseModel): @model_validator(mode='after') def check_new_password(self) -> 'ResetPasswordModel': - pattern = r'''^[^<>"'|\\]+$''' + pattern = r"""^[^<>"'|\\]+$""" if self.new_password is None or re.match(pattern, self.new_password): return self else: - raise ModelValidatorException(message="密码不能包含非法字符:< > \" ' \\ |") + raise ModelValidatorException(message='密码不能包含非法字符:< > " \' \\ |') class ResetUserModel(UserModel): """ 重置用户密码模型 """ + old_password: Optional[str] = Field(default=None, description='旧密码') sms_code: Optional[str] = Field(default=None, description='验证码') session_id: Optional[str] = Field(default=None, description='会话id') @@ -213,6 +225,7 @@ class DeleteUserModel(BaseModel): """ 删除用户模型 """ + model_config = ConfigDict(alias_generator=to_camel) user_ids: str = Field(description='需要删除的用户ID') @@ -224,6 +237,7 @@ class UserRoleQueryModel(UserModel): """ 用户角色关联管理不分页查询模型 """ + role_id: Optional[int] = Field(default=None, description='角色ID') @@ -232,6 +246,7 @@ class UserRolePageQueryModel(UserRoleQueryModel): """ 用户角色关联管理分页查询模型 """ + page_num: int = Field(default=1, description='当前页码') page_size: int = Field(default=10, description='每页记录数') @@ -240,6 +255,7 @@ class SelectedRoleModel(RoleModel): """ 是否选择角色模型 """ + flag: Optional[bool] = Field(default=False, description='选择标识') @@ -247,6 +263,7 @@ class UserRoleResponseModel(BaseModel): """ 用户角色关联管理列表返回模型 """ + model_config = ConfigDict(alias_generator=to_camel) roles: List[Union[SelectedRoleModel, None]] = Field(default=[], description='角色信息') @@ -258,6 +275,7 @@ class CrudUserRoleModel(BaseModel): """ 新增、删除用户关联角色及角色关联用户模型 """ + model_config = ConfigDict(alias_generator=to_camel) user_id: Optional[int] = Field(default=None, description='用户ID') diff --git a/ruoyi-fastapi-backend/module_admin/service/user_service.py b/ruoyi-fastapi-backend/module_admin/service/user_service.py index 720480d..37d9dac 100644 --- a/ruoyi-fastapi-backend/module_admin/service/user_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/user_service.py @@ -1,15 +1,39 @@ +import io +import pandas as pd +from datetime import datetime from fastapi import Request, UploadFile -from module_admin.service.role_service import RoleService -from module_admin.service.dept_service import DeptService -from module_admin.service.post_service import PostService, PostPageQueryModel -from module_admin.service.config_service import ConfigService -from module_admin.entity.vo.common_vo import CrudResponseModel -from module_admin.dao.user_dao import * +from sqlalchemy.ext.asyncio import AsyncSession +from typing import List, Union from config.constant import CommonConstant from exceptions.exception import ServiceException +from module_admin.dao.user_dao import UserDao +from module_admin.entity.vo.common_vo import CrudResponseModel +from module_admin.entity.vo.post_vo import PostPageQueryModel +from module_admin.entity.vo.user_vo import ( + AddUserModel, + CrudUserRoleModel, + CurrentUserModel, + DeleteUserModel, + EditUserModel, + ResetUserModel, + SelectedRoleModel, + UserDetailModel, + UserInfoModel, + UserModel, + UserPageQueryModel, + UserPostModel, + UserProfileModel, + UserRoleModel, + UserRoleQueryModel, + UserRoleResponseModel, +) +from module_admin.service.config_service import ConfigService +from module_admin.service.dept_service import DeptService +from module_admin.service.post_service import PostService +from module_admin.service.role_service import RoleService +from utils.common_util import CamelCaseUtil, export_list2excel, get_excel_template from utils.page_util import PageResponseModel -from utils.pwd_util import * -from utils.common_util import * +from utils.pwd_util import PwdUtil class UserService: @@ -18,7 +42,9 @@ class UserService: """ @classmethod - async def get_user_list_services(cls, query_db: AsyncSession, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False): + async def get_user_list_services( + cls, query_db: AsyncSession, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False + ): """ 获取用户列表信息service :param query_db: orm对象 @@ -32,7 +58,7 @@ class UserService: user_list_result = PageResponseModel( **{ **query_result.model_dump(by_alias=True), - 'rows': [{**row[0], 'dept': row[1]} for row in query_result.rows] + 'rows': [{**row[0], 'dept': row[1]} for row in query_result.rows], } ) else: @@ -173,10 +199,14 @@ class UserService: await UserDao.delete_user_post_dao(query_db, UserPostModel(userId=page_object.user_id)) if page_object.role_ids: for role in page_object.role_ids: - await UserDao.add_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=role)) + await UserDao.add_user_role_dao( + query_db, UserRoleModel(userId=page_object.user_id, roleId=role) + ) if page_object.post_ids: for post in page_object.post_ids: - await UserDao.add_user_post_dao(query_db, UserPostModel(userId=page_object.user_id, postId=post)) + await UserDao.add_user_post_dao( + query_db, UserPostModel(userId=page_object.user_id, postId=post) + ) await query_db.commit() return CrudResponseModel(is_success=True, message='更新成功') except Exception as e: @@ -197,7 +227,9 @@ class UserService: user_id_list = page_object.user_ids.split(',') try: for user_id in user_id_list: - user_id_dict = dict(userId=user_id, updateBy=page_object.update_by, updateTime=page_object.update_time) + user_id_dict = dict( + userId=user_id, updateBy=page_object.update_by, updateTime=page_object.update_time + ) await UserDao.delete_user_role_dao(query_db, UserRoleModel(**user_id_dict)) await UserDao.delete_user_post_dao(query_db, UserPostModel(**user_id_dict)) await UserDao.delete_user_dao(query_db, UserModel(**user_id_dict)) @@ -232,18 +264,15 @@ class UserService: postIds=post_ids, roleIds=role_ids, dept=CamelCaseUtil.transform_result(query_user.get('user_dept_info')), - role=CamelCaseUtil.transform_result(query_user.get('user_role_info')) + role=CamelCaseUtil.transform_result(query_user.get('user_role_info')), ), postIds=post_ids_list, posts=posts, roleIds=role_ids_list, - roles=roles + roles=roles, ) - return UserDetailModel( - posts=posts, - roles=roles - ) + return UserDetailModel(posts=posts, roles=roles) @classmethod async def user_profile_services(cls, query_db: AsyncSession, user_id: int): @@ -265,10 +294,10 @@ class UserService: postIds=post_ids, roleIds=role_ids, dept=CamelCaseUtil.transform_result(query_user.get('user_dept_info')), - role=CamelCaseUtil.transform_result(query_user.get('user_role_info')) + role=CamelCaseUtil.transform_result(query_user.get('user_role_info')), ), postGroup=post_group, - roleGroup=role_group + roleGroup=role_group, ) @classmethod @@ -300,7 +329,16 @@ class UserService: raise e @classmethod - async def batch_import_user_services(cls, request: Request, query_db: AsyncSession, file: UploadFile, update_support: bool, current_user: CurrentUserModel, user_data_scope_sql: str, dept_data_scope_sql: str): + async def batch_import_user_services( + cls, + request: Request, + query_db: AsyncSession, + file: UploadFile, + update_support: bool, + current_user: CurrentUserModel, + user_data_scope_sql: str, + dept_data_scope_sql: str, + ): """ 批量导入用户service :param request: Request对象 @@ -313,13 +351,13 @@ class UserService: :return: 批量导入用户结果 """ header_dict = { - "部门编号": "dept_id", - "登录名称": "user_name", - "用户名称": "nick_name", - "用户邮箱": "email", - "手机号码": "phonenumber", - "用户性别": "sex", - "帐号状态": "status" + '部门编号': 'dept_id', + '登录名称': 'user_name', + '用户名称': 'nick_name', + '用户邮箱': 'email', + '手机号码': 'phonenumber', + '用户性别': 'sex', + '帐号状态': 'status', } contents = await file.read() df = pd.read_excel(io.BytesIO(contents)) @@ -343,7 +381,11 @@ class UserService: add_user = UserModel( deptId=row['dept_id'], userName=row['user_name'], - password=PwdUtil.get_password_hash(await ConfigService.query_config_list_from_cache_services(request.app.state.redis, 'sys.user.initPassword')), + password=PwdUtil.get_password_hash( + await ConfigService.query_config_list_from_cache_services( + request.app.state.redis, 'sys.user.initPassword' + ) + ), nickName=row['nick_name'], email=row['email'], phonenumber=str(row['phonenumber']), @@ -352,7 +394,7 @@ class UserService: createBy=current_user.user.user_name, createTime=datetime.now(), updateBy=current_user.user.user_name, - updateTime=datetime.now() + updateTime=datetime.now(), ) user_info = await UserDao.get_user_by_info(query_db, UserModel(userName=row['user_name'])) if user_info: @@ -367,13 +409,17 @@ class UserService: sex=row['sex'], status=row['status'], updateBy=current_user.user.user_name, - updateTime=datetime.now() + updateTime=datetime.now(), ) edit_user_model.validate_fields() await cls.check_user_allowed_services(edit_user_model) if not current_user.user.admin: - await cls.check_user_data_scope_services(query_db, edit_user_model.user_id, user_data_scope_sql) - await DeptService.check_dept_data_scope_services(query_db, edit_user_model.dept_id, dept_data_scope_sql) + await cls.check_user_data_scope_services( + query_db, edit_user_model.user_id, user_data_scope_sql + ) + await DeptService.check_dept_data_scope_services( + query_db, edit_user_model.dept_id, dept_data_scope_sql + ) edit_user = edit_user_model.model_dump(exclude_unset=True) await UserDao.edit_user_dao(query_db, edit_user) else: @@ -381,7 +427,9 @@ class UserService: else: add_user.validate_fields() if not current_user.user.admin: - await DeptService.check_dept_data_scope_services(query_db, add_user.dept_id, dept_data_scope_sql) + await DeptService.check_dept_data_scope_services( + query_db, add_user.dept_id, dept_data_scope_sql + ) await UserDao.add_user_dao(query_db, add_user) await query_db.commit() return CrudResponseModel(is_success=True, message='\n'.join(add_error_result)) @@ -395,10 +443,12 @@ class UserService: 获取用户导入模板service :return: 用户导入模板excel的二进制数据 """ - header_list = ["部门编号", "登录名称", "用户名称", "用户邮箱", "手机号码", "用户性别", "帐号状态"] - selector_header_list = ["用户性别", "帐号状态"] - option_list = [{"用户性别": ["男", "女", "未知"]}, {"帐号状态": ["正常", "停用"]}] - binary_data = get_excel_template(header_list=header_list, selector_header_list=selector_header_list, option_list=option_list) + header_list = ['部门编号', '登录名称', '用户名称', '用户邮箱', '手机号码', '用户性别', '帐号状态'] + selector_header_list = ['用户性别', '帐号状态'] + option_list = [{'用户性别': ['男', '女', '未知']}, {'帐号状态': ['正常', '停用']}] + binary_data = get_excel_template( + header_list=header_list, selector_header_list=selector_header_list, option_list=option_list + ) return binary_data @@ -411,19 +461,19 @@ class UserService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "userId": "用户编号", - "userName": "用户名称", - "nickName": "用户昵称", - "deptName": "部门", - "email": "邮箱地址", - "phonenumber": "手机号码", - "sex": "性别", - "status": "状态", - "createBy": "创建者", - "createTime": "创建时间", - "updateBy": "更新者", - "updateTime": "更新时间", - "remark": "备注", + 'userId': '用户编号', + 'userName': '用户名称', + 'nickName': '用户昵称', + 'deptName': '部门', + 'email': '邮箱地址', + 'phonenumber': '手机号码', + 'sex': '性别', + 'status': '状态', + 'createBy': '创建者', + 'createTime': '创建时间', + 'updateBy': '更新者', + 'updateTime': '更新时间', + 'remark': '备注', } data = user_list @@ -439,7 +489,9 @@ class UserService: item['sex'] = '女' else: item['sex'] = '未知' - new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + new_data = [ + {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data + ] binary_data = export_list2excel(new_data) return binary_data @@ -460,17 +512,16 @@ class UserService: postIds=post_ids, roleIds=role_ids, dept=CamelCaseUtil.transform_result(query_user.get('user_dept_info')), - role=CamelCaseUtil.transform_result(query_user.get('user_role_info')) + role=CamelCaseUtil.transform_result(query_user.get('user_role_info')), ) - query_role_list = [SelectedRoleModel(**row) for row in await RoleService.get_role_select_option_services(query_db)] + query_role_list = [ + SelectedRoleModel(**row) for row in await RoleService.get_role_select_option_services(query_db) + ] for model_a in query_role_list: for model_b in user.role: if model_a.role_id == model_b.role_id: model_a.flag = True - result = UserRoleResponseModel( - roles=query_role_list, - user=user - ) + result = UserRoleResponseModel(roles=query_role_list, user=user) return result @@ -486,11 +537,15 @@ class UserService: role_id_list = page_object.role_ids.split(',') try: for role_id in role_id_list: - user_role = await cls.detail_user_role_services(query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id)) + user_role = await cls.detail_user_role_services( + query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id) + ) if user_role: continue else: - await UserDao.add_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id)) + await UserDao.add_user_role_dao( + query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id) + ) await query_db.commit() return CrudResponseModel(is_success=True, message='分配成功') except Exception as e: @@ -508,11 +563,15 @@ class UserService: user_id_list = page_object.user_ids.split(',') try: for user_id in user_id_list: - user_role = await cls.detail_user_role_services(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id)) + user_role = await cls.detail_user_role_services( + query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id) + ) if user_role: continue else: - await UserDao.add_user_role_dao(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id)) + await UserDao.add_user_role_dao( + query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id) + ) await query_db.commit() return CrudResponseModel(is_success=True, message='新增成功') except Exception as e: @@ -532,7 +591,9 @@ class UserService: if (page_object.user_id and page_object.role_id) or (page_object.user_ids and page_object.role_id): if page_object.user_id and page_object.role_id: try: - await UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=page_object.role_id)) + await UserDao.delete_user_role_by_user_and_role_dao( + query_db, UserRoleModel(userId=page_object.user_id, roleId=page_object.role_id) + ) await query_db.commit() return CrudResponseModel(is_success=True, message='删除成功') except Exception as e: @@ -542,7 +603,9 @@ class UserService: user_id_list = page_object.user_ids.split(',') try: for user_id in user_id_list: - await UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id)) + await UserDao.delete_user_role_by_user_and_role_dao( + query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id) + ) await query_db.commit() return CrudResponseModel(is_success=True, message='删除成功') except Exception as e: