From 4cdbaa5157c70cd801d46e893da2ccb6c3cbee0c Mon Sep 17 00:00:00 2001 From: insistence <3055204202@qq.com> Date: Fri, 26 Jan 2024 08:56:40 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=92=8C=E8=A7=92=E8=89=B2=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=88=86=E9=A1=B5=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/role_controller.py | 20 +--- .../controller/user_controller.py | 12 +- .../module_admin/dao/role_dao.py | 9 +- .../module_admin/dao/user_dao.py | 47 +++----- .../module_admin/service/role_service.py | 34 ++++-- .../module_admin/service/user_service.py | 20 +++- ruoyi-fastapi-backend/utils/common_util.py | 4 + ruoyi-fastapi-backend/utils/page_util.py | 104 ++++++++++-------- 8 files changed, 130 insertions(+), 120 deletions(-) diff --git a/ruoyi-fastapi-backend/module_admin/controller/role_controller.py b/ruoyi-fastapi-backend/module_admin/controller/role_controller.py index 4007ec5..d99096e 100644 --- a/ruoyi-fastapi-backend/module_admin/controller/role_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/role_controller.py @@ -7,7 +7,7 @@ from module_admin.service.dept_service import DeptService, DeptModel from module_admin.service.user_service import UserService, UserRoleQueryModel, UserRolePageQueryModel, CrudUserRoleModel from utils.response_util import * from utils.log_util import * -from utils.page_util import * +from utils.page_util import PageResponseModel from utils.common_util import bytes2file_response from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.aspect.data_scope import GetDataScope @@ -33,10 +33,7 @@ async def get_system_role_dept_tree(request: Request, role_id: int, query_db: Se @roleController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))]) async def get_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_query), query_db: Session = Depends(get_db)): try: - role_query = RoleQueryModel(**role_page_query.model_dump(by_alias=True)) - role_query_result = RoleService.get_role_list_services(query_db, role_query) - # 分页操作 - role_page_query_result = get_page_obj(role_query_result, role_page_query.page_num, role_page_query.page_size) + role_page_query_result = RoleService.get_role_list_services(query_db, role_page_query, is_page=True) logger.info('获取成功') return ResponseUtil.success(model_content=role_page_query_result) except Exception as e: @@ -134,9 +131,8 @@ async def query_detail_system_role(request: Request, role_id: int, query_db: Ses @log_decorator(title='角色管理', business_type=5) async def export_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_form), query_db: Session = Depends(get_db)): try: - role_query = RoleQueryModel(**role_page_query.model_dump(by_alias=True)) # 获取全量数据 - role_query_result = RoleService.get_role_list_services(query_db, role_query) + role_query_result = RoleService.get_role_list_services(query_db, role_page_query, is_page=False) role_export_result = RoleService.export_role_list_services(role_query_result) logger.info('导出成功') return ResponseUtil.streaming(data=bytes2file_response(role_export_result)) @@ -167,10 +163,7 @@ async def reset_system_role_status(request: Request, edit_role: AddRoleModel, qu @roleController.get("/authUser/allocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) async def get_system_allocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)): try: - role_user_query = UserRoleQueryModel(**user_role.model_dump(by_alias=True)) - role_user_allocated_query_result = RoleService.get_role_user_allocated_list_services(query_db, role_user_query) - # 分页操作 - role_user_allocated_page_query_result = get_page_obj(role_user_allocated_query_result, user_role.page_num, user_role.page_size) + role_user_allocated_page_query_result = RoleService.get_role_user_allocated_list_services(query_db, user_role, is_page=True) logger.info('获取成功') return ResponseUtil.success(model_content=role_user_allocated_page_query_result) except Exception as e: @@ -181,10 +174,7 @@ async def get_system_allocated_user_list(request: Request, user_role: UserRolePa @roleController.get("/authUser/unallocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) async def get_system_unallocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)): try: - role_user_query = UserRoleQueryModel(**user_role.model_dump(by_alias=True)) - role_user_unallocated_query_result = RoleService.get_role_user_unallocated_list_services(query_db, role_user_query) - # 分页操作 - role_user_unallocated_page_query_result = get_page_obj(role_user_unallocated_query_result, user_role.page_num, user_role.page_size) + role_user_unallocated_page_query_result = RoleService.get_role_user_unallocated_list_services(query_db, user_role, is_page=True) logger.info('获取成功') return ResponseUtil.success(model_content=role_user_unallocated_page_query_result) except Exception as e: diff --git a/ruoyi-fastapi-backend/module_admin/controller/user_controller.py b/ruoyi-fastapi-backend/module_admin/controller/user_controller.py index d9b1eba..46ea0b8 100644 --- a/ruoyi-fastapi-backend/module_admin/controller/user_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/user_controller.py @@ -5,7 +5,7 @@ from config.env import UploadConfig from module_admin.service.login_service import LoginService from module_admin.service.user_service import * from module_admin.service.dept_service import DeptService -from utils.page_util import * +from utils.page_util import PageResponseModel from utils.response_util import * from utils.log_util import * from utils.common_util import bytes2file_response @@ -32,11 +32,8 @@ async def get_system_dept_tree(request: Request, query_db: Session = Depends(get @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: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))): try: - user_query = UserQueryModel(**user_page_query.model_dump(by_alias=True)) - # 获取全量数据 - user_query_result = UserService.get_user_list_services(query_db, user_query, data_scope_sql) - # 分页操作 - user_page_query_result = get_page_obj(user_query_result, user_page_query.page_num, user_page_query.page_size) + # 获取分页数据 + user_page_query_result = 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) except Exception as e: @@ -272,9 +269,8 @@ async def export_system_user_template(request: Request, query_db: Session = Depe @log_decorator(title='用户管理', business_type=5) async def export_system_user_list(request: Request, user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_form), query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))): try: - user_query = UserQueryModel(**user_page_query.model_dump(by_alias=True)) # 获取全量数据 - user_query_result = UserService.get_user_list_services(query_db, user_query, data_scope_sql) + user_query_result = UserService.get_user_list_services(query_db, user_page_query, data_scope_sql, is_page=False) user_export_result = UserService.export_user_list_services(user_query_result) logger.info('导出成功') return ResponseUtil.streaming(data=bytes2file_response(user_export_result)) diff --git a/ruoyi-fastapi-backend/module_admin/dao/role_dao.py b/ruoyi-fastapi-backend/module_admin/dao/role_dao.py index 17745b3..32267da 100644 --- a/ruoyi-fastapi-backend/module_admin/dao/role_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/role_dao.py @@ -3,6 +3,7 @@ from sqlalchemy.orm import Session from module_admin.entity.do.role_do import SysRole, SysRoleMenu, SysRoleDept from module_admin.entity.do.dept_do import SysDept from module_admin.entity.vo.role_vo import * +from utils.page_util import PageUtil from datetime import datetime, time @@ -85,14 +86,15 @@ class RoleDao: return role_info @classmethod - def get_role_list(cls, db: Session, query_object: RoleQueryModel): + def get_role_list(cls, db: Session, query_object: RolePageQueryModel, is_page: bool = False): """ 根据查询参数获取角色列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 角色列表信息对象 """ - role_list = db.query(SysRole) \ + query = db.query(SysRole) \ .filter(SysRole.del_flag == 0, SysRole.role_name.like(f'%{query_object.role_name}%') if query_object.role_name else True, SysRole.role_key.like(f'%{query_object.role_key}%') if query_object.role_key else True, @@ -103,7 +105,8 @@ class RoleDao: if query_object.begin_time and query_object.end_time else True ) \ .order_by(SysRole.role_sort) \ - .distinct().all() + .distinct() + role_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) return role_list diff --git a/ruoyi-fastapi-backend/module_admin/dao/user_dao.py b/ruoyi-fastapi-backend/module_admin/dao/user_dao.py index ee96936..f6c2c2f 100644 --- a/ruoyi-fastapi-backend/module_admin/dao/user_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/user_dao.py @@ -6,7 +6,7 @@ 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 utils.time_format_util import list_format_datetime +from utils.page_util import PageUtil from datetime import datetime, time @@ -137,15 +137,16 @@ class UserDao: return results @classmethod - def get_user_list(cls, db: Session, query_object: UserQueryModel, data_scope_sql: str): + def get_user_list(cls, db: Session, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False): """ 根据查询参数获取用户列表信息 :param db: orm对象 :param query_object: 查询参数对象 :param data_scope_sql: 数据权限对应的查询sql语句 + :param is_page: 是否开启分页 :return: 用户列表信息对象 """ - user_list = db.query(SysUser, SysDept) \ + query = db.query(SysUser, SysDept) \ .filter(SysUser.del_flag == 0, or_(SysUser.dept_id == query_object.dept_id, SysUser.dept_id.in_( db.query(SysDept.dept_id).filter(func.find_in_set(query_object.dept_id, SysDept.ancestors)) @@ -163,7 +164,8 @@ class UserDao: eval(data_scope_sql) ) \ .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ - .distinct().all() + .distinct() + user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) return user_list @@ -227,35 +229,15 @@ class UserDao: return allocated_role_list @classmethod - def get_user_role_unallocated_list_by_user_id(cls, db: Session, query_object: UserRoleQueryModel): - """ - 根据用户id获取用户未分配的角色列表信息数据库操作 - :param db: orm对象 - :param query_object: 用户角色查询对象 - :return: 用户未分配的角色列表信息 - """ - unallocated_role_list = db.query(SysRole) \ - .filter( - 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_( - db.query(SysUserRole.role_id).filter(SysUserRole.user_id == query_object.user_id) - ) - ).distinct().all() - - return list_format_datetime(unallocated_role_list) - - @classmethod - def get_user_role_allocated_list_by_role_id(cls, db: Session, query_object: UserRoleQueryModel): + def get_user_role_allocated_list_by_role_id(cls, db: Session, query_object: UserRolePageQueryModel, is_page: bool = False): """ 根据角色id获取已分配的用户列表信息 :param db: orm对象 :param query_object: 用户角色查询对象 + :param is_page: 是否开启分页 :return: 角色已分配的用户列表信息 """ - allocated_user_list = db.query(SysUser) \ + query = db.query(SysUser) \ .filter( SysUser.del_flag == 0, SysUser.user_id != 1, @@ -264,19 +246,21 @@ class UserDao: SysUser.user_id.in_( db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id) ) - ).distinct().all() + ).distinct() + allocated_user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) return allocated_user_list @classmethod - def get_user_role_unallocated_list_by_role_id(cls, db: Session, query_object: UserRoleQueryModel): + def get_user_role_unallocated_list_by_role_id(cls, db: Session, query_object: UserRolePageQueryModel, is_page: bool = False): """ 根据角色id获取未分配的用户列表信息 :param db: orm对象 :param query_object: 用户角色查询对象 + :param is_page: 是否开启分页 :return: 角色未分配的用户列表信息 """ - unallocated_user_list = db.query(SysUser) \ + query = db.query(SysUser) \ .filter( SysUser.del_flag == 0, SysUser.user_id != 1, @@ -285,7 +269,8 @@ class UserDao: ~SysUser.user_id.in_( db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id) ) - ).distinct().all() + ).distinct() + unallocated_user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) return unallocated_user_list diff --git a/ruoyi-fastapi-backend/module_admin/service/role_service.py b/ruoyi-fastapi-backend/module_admin/service/role_service.py index bb82b78..71c3381 100644 --- a/ruoyi-fastapi-backend/module_admin/service/role_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/role_service.py @@ -1,7 +1,8 @@ -from module_admin.entity.vo.user_vo import UserInfoModel, UserRoleQueryModel +from module_admin.entity.vo.user_vo import UserInfoModel, UserRolePageQueryModel from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.dao.user_dao import UserDao from module_admin.dao.role_dao import * +from utils.page_util import PageResponseModel from utils.common_util import export_list2excel, CamelCaseUtil @@ -38,16 +39,17 @@ class RoleService: return result @classmethod - def get_role_list_services(cls, query_db: Session, query_object: RoleQueryModel): + def get_role_list_services(cls, query_db: Session, query_object: RolePageQueryModel, is_page: bool = False): """ 获取角色列表信息service :param query_db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 角色列表信息对象 """ - role_list_result = RoleDao.get_role_list(query_db, query_object) + role_list_result = RoleDao.get_role_list(query_db, query_object, is_page) - return CamelCaseUtil.transform_result(role_list_result) + return role_list_result @classmethod def add_role_services(cls, query_db: Session, page_object: AddRoleModel): @@ -230,27 +232,39 @@ class RoleService: return binary_data @classmethod - def get_role_user_allocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel): + def get_role_user_allocated_list_services(cls, query_db: Session, page_object: UserRolePageQueryModel, is_page: bool = False): """ 根据角色id获取已分配用户列表 :param query_db: orm对象 :param page_object: 用户关联角色对象 + :param is_page: 是否开启分页 :return: 已分配用户列表 """ - query_user_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object) - allocated_list = [UserInfoModel(**CamelCaseUtil.transform_result(row)) for row in query_user_list] + query_user_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object, is_page) + allocated_list = PageResponseModel( + **{ + **query_user_list.model_dump(by_alias=True), + 'rows': [UserInfoModel(**row) for row in query_user_list.rows] + } + ) return allocated_list @classmethod - def get_role_user_unallocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel): + def get_role_user_unallocated_list_services(cls, query_db: Session, page_object: UserRolePageQueryModel, is_page: bool = False): """ 根据角色id获取未分配用户列表 :param query_db: orm对象 :param page_object: 用户关联角色对象 + :param is_page: 是否开启分页 :return: 未分配用户列表 """ - query_user_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object) - unallocated_list = [UserInfoModel(**CamelCaseUtil.transform_result(row)) for row in query_user_list] + query_user_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object, is_page) + unallocated_list = PageResponseModel( + **{ + **query_user_list.model_dump(by_alias=True), + 'rows': [UserInfoModel(**row) for row in query_user_list.rows] + } + ) return unallocated_list diff --git a/ruoyi-fastapi-backend/module_admin/service/user_service.py b/ruoyi-fastapi-backend/module_admin/service/user_service.py index cf56120..b4bb961 100644 --- a/ruoyi-fastapi-backend/module_admin/service/user_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/user_service.py @@ -3,6 +3,7 @@ from module_admin.service.role_service import RoleService from module_admin.service.post_service import PostService from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.dao.user_dao import * +from utils.page_util import PageResponseModel from utils.pwd_util import * from utils.common_util import * @@ -13,18 +14,27 @@ class UserService: """ @classmethod - def get_user_list_services(cls, query_db: Session, query_object: UserQueryModel, data_scope_sql: str): + def get_user_list_services(cls, query_db: Session, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False): """ 获取用户列表信息service :param query_db: orm对象 :param query_object: 查询参数对象 :param data_scope_sql: 数据权限对应的查询sql语句 + :param is_page: 是否开启分页 :return: 用户列表信息对象 """ - query_result = UserDao.get_user_list(query_db, query_object, data_scope_sql) - user_list_result = [] - if query_result: - user_list_result = [{**CamelCaseUtil.transform_result(row[0]), 'dept': CamelCaseUtil.transform_result(row[1])} for row in query_result] + query_result = UserDao.get_user_list(query_db, query_object, data_scope_sql, is_page) + if is_page: + user_list_result = PageResponseModel( + **{ + **query_result.model_dump(by_alias=True), + 'rows': [{**row[0], 'dept': row[1]} for row in query_result.rows] + } + ) + else: + user_list_result = [] + if query_result: + user_list_result = [{**row[0], 'dept': row[1]} for row in query_result] return user_list_result diff --git a/ruoyi-fastapi-backend/utils/common_util.py b/ruoyi-fastapi-backend/utils/common_util.py index a45d266..7efb1dc 100644 --- a/ruoyi-fastapi-backend/utils/common_util.py +++ b/ruoyi-fastapi-backend/utils/common_util.py @@ -5,6 +5,7 @@ from openpyxl import Workbook from openpyxl.styles import Alignment, PatternFill from openpyxl.utils import get_column_letter from openpyxl.worksheet.datavalidation import DataValidation +from sqlalchemy.engine.row import Row from typing import List from config.env import CachePathConfig @@ -66,6 +67,9 @@ class CamelCaseUtil: return {cls.__to_camel_case(k): v for k, v in result.items()} # 如果是一组字典或其他类型的列表,遍历列表进行转换 elif isinstance(result, list): + return [cls.transform_result(row) if isinstance(row, (dict, Row)) else cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) for row in result] + # 如果是sqlalchemy的Row实例,遍历Row进行转换 + elif isinstance(result, Row): return [cls.transform_result(row) if isinstance(row, dict) else cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) for row in result] # 如果是其他类型,如模型实例,先转换为字典 else: diff --git a/ruoyi-fastapi-backend/utils/page_util.py b/ruoyi-fastapi-backend/utils/page_util.py index 341f80f..cf2da9b 100644 --- a/ruoyi-fastapi-backend/utils/page_util.py +++ b/ruoyi-fastapi-backend/utils/page_util.py @@ -1,30 +1,9 @@ import math from typing import Optional, List - +from sqlalchemy.orm.query import Query from pydantic import BaseModel, ConfigDict from pydantic.alias_generators import to_camel - - -class PageModel(BaseModel): - """ - 分页模型 - """ - offset: int - page_num: int - page_size: int - total: int - has_next: bool - - -class PageObjectResponse(BaseModel): - """ - 用户管理列表分页查询返回模型 - """ - rows: List = [] - page_num: int - page_size: int - total: int - has_next: bool +from utils.common_util import CamelCaseUtil class PageResponseModel(BaseModel): @@ -40,33 +19,64 @@ class PageResponseModel(BaseModel): has_next: Optional[bool] = None -def get_page_info(offset: int, page_num: int, page_size: int, count: int): +class PageUtil: """ - 根据分页参数获取分页信息 - :param offset: 起始数据位置 - :param page_num: 当前页码 - :param page_size: 当前页面数据量 - :param count: 数据总数 - :return: 分页信息对象 + 分页工具类 """ - has_next = False - if offset >= count: - res_offset_1 = (page_num - 2) * page_size - if res_offset_1 < 0: - res_offset = 0 - res_page_num = 1 + + @classmethod + def get_page_obj(cls, data_list: List, page_num: int, page_size: int): + """ + 输入数据列表data_list和分页信息,返回分页数据列表结果 + :param data_list: 原始数据列表 + :param page_num: 当前页码 + :param page_size: 当前页面数据量 + :return: 分页数据对象 + """ + # 计算起始索引和结束索引 + start = (page_num - 1) * page_size + end = page_num * page_size + + # 根据计算得到的起始索引和结束索引对数据列表进行切片 + paginated_data = data_list[start:end] + has_next = True if math.ceil(len(data_list) / page_size) > page_num else False + + result = PageResponseModel( + rows=paginated_data, + pageNum=page_num, + pageSize=page_size, + total=len(data_list), + hasNext=has_next + ) + + return result + + @classmethod + def paginate(cls, query: Query, page_num: int, page_size: int, is_page: bool = False): + """ + 输入查询语句和分页信息,返回分页数据列表结果 + :param query: sqlalchemy查询语句 + :param page_num: 当前页码 + :param page_size: 当前页面数据量 + :param is_page: 是否开启分页 + :return: 分页数据对象 + """ + if is_page: + total = query.count() + paginated_data = query.offset((page_num - 1) * page_size).limit(page_size).all() + has_next = True if math.ceil(len(paginated_data) / page_size) > page_num else False + result = PageResponseModel( + rows=CamelCaseUtil.transform_result(paginated_data), + pageNum=page_num, + pageSize=page_size, + total=total, + hasNext=has_next + ) else: - res_offset = res_offset_1 - res_page_num = page_num - 1 - else: - res_offset = offset - if (res_offset + page_size) < count: - has_next = True - res_page_num = page_num + no_paginated_data = query.all() + result = CamelCaseUtil.transform_result(no_paginated_data) - result = dict(offset=res_offset, page_num=res_page_num, page_size=page_size, total=count, has_next=has_next) - - return PageModel(**result) + return result def get_page_obj(data_list: List, page_num: int, page_size: int): @@ -94,5 +104,3 @@ def get_page_obj(data_list: List, page_num: int, page_size: int): ) return result - -