From 44befcc79f21c363ba30f1662a5cf9750ce3962c Mon Sep 17 00:00:00 2001 From: Wu Clan Date: Sun, 9 Jul 2023 16:39:37 +0800 Subject: [PATCH] Add query users by department ID (#175) * Add query users by department ID * fix dept parent id schema field * fix dept get all select * update the test sql --- backend/app/api/v1/user.py | 3 ++- backend/app/core/conf.py | 2 +- backend/app/crud/crud_dept.py | 16 ++++++++++++---- backend/app/crud/crud_user.py | 4 +++- backend/app/schemas/dept.py | 2 +- backend/app/services/user_service.py | 4 ++-- backend/sql/create_tables.sql | 1 + backend/sql/init_test_data.sql | 25 +++++++++++++++++-------- 8 files changed, 39 insertions(+), 18 deletions(-) diff --git a/backend/app/api/v1/user.py b/backend/app/api/v1/user.py index 3f080447..72074f06 100644 --- a/backend/app/api/v1/user.py +++ b/backend/app/api/v1/user.py @@ -62,11 +62,12 @@ async def update_avatar(request: Request, username: str, avatar: Avatar): @router.get('', summary='(模糊条件)分页获取所有用户', dependencies=[DependsJwtAuth, PageDepends]) async def get_all_users( db: CurrentSession, + dept: Annotated[int | None, Query()] = None, username: Annotated[str | None, Query()] = None, phone: Annotated[str | None, Query()] = None, status: Annotated[int | None, Query()] = None, ): - user_select = await UserService.get_select(username=username, phone=phone, status=status) + user_select = await UserService.get_select(dept=dept, username=username, phone=phone, status=status) page_data = await paging_data(db, user_select, GetAllUserInfo) return await response_base.success(data=page_data) diff --git a/backend/app/core/conf.py b/backend/app/core/conf.py index 61a26ccf..427adee0 100644 --- a/backend/app/core/conf.py +++ b/backend/app/core/conf.py @@ -51,7 +51,7 @@ class Settings(BaseSettings): # Demo mode # Only GET, OPTIONS requests are allowed - DEMO_MODE: bool = True + DEMO_MODE: bool = False DEMO_MODE_EXCLUDE: set[tuple[str, str]] = { ('POST', f'{API_V1_STR}/auth/login'), ('POST', f'{API_V1_STR}/auth/logout'), diff --git a/backend/app/crud/crud_dept.py b/backend/app/crud/crud_dept.py index 0661d68b..9f78f994 100644 --- a/backend/app/crud/crud_dept.py +++ b/backend/app/crud/crud_dept.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from typing import Any -from sqlalchemy import select, and_, asc +from sqlalchemy import select, and_, asc, or_ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload @@ -23,14 +23,22 @@ class CRUDDept(CRUDBase[Dept, CreateDept, UpdateDept]): ) -> Any: se = select(self.model).order_by(asc(self.model.sort)) where_list = [self.model.del_flag == 0] + conditions = [] if name: - where_list.append(self.model.name.like(f'%{name}%')) + conditions.append(self.model.name.like(f'%{name}%')) if leader: - where_list.append(self.model.leader.like(f'%{leader}%')) + conditions.append(self.model.leader.like(f'%{leader}%')) if phone: - where_list.append(self.model.phone.startswith(phone)) + se_phone = self.model.phone.startswith(phone) + dept_select = await db.execute(se.where(se_phone)) + dept_likes = dept_select.scalars().all() + where_list.append(or_(se_phone, self.model.id.in_([dept.parent_id for dept in dept_likes]))) if status is not None: where_list.append(self.model.status == status) + if conditions: + dept_select = await db.execute(se.where(and_(*conditions))) + dept_likes = dept_select.scalars().all() + where_list.append(or_(*conditions, self.model.id.in_([dept.parent_id for dept in dept_likes]))) if where_list: se = se.where(and_(*where_list)) dept = await db.execute(se) diff --git a/backend/app/crud/crud_user.py b/backend/app/crud/crud_user.py index 94491ac4..6c0236e2 100644 --- a/backend/app/crud/crud_user.py +++ b/backend/app/crud/crud_user.py @@ -69,7 +69,7 @@ class CRUDUser(CRUDBase[User, CreateUser, UpdateUser]): ) return user.rowcount - async def get_all(self, username: str = None, phone: str = None, status: int = None) -> Select: + async def get_all(self, dept: int = None, username: str = None, phone: str = None, status: int = None) -> Select: se = ( select(self.model) .options(selectinload(self.model.dept)) @@ -77,6 +77,8 @@ class CRUDUser(CRUDBase[User, CreateUser, UpdateUser]): .order_by(desc(self.model.join_time)) ) where_list = [] + if dept: + where_list.append(self.model.dept_id == dept) if username: where_list.append(self.model.username.like(f'%{username}%')) if phone: diff --git a/backend/app/schemas/dept.py b/backend/app/schemas/dept.py index 5cfb3797..6c5f9f3f 100644 --- a/backend/app/schemas/dept.py +++ b/backend/app/schemas/dept.py @@ -11,7 +11,7 @@ from backend.app.utils.re_verify import is_phone class DeptBase(SchemaBase): name: str - parent_id: int | None = Field(default=None, ge=1, description='菜单父级ID') + parent_id: int | None = Field(default=None, description='菜单父级ID') sort: int = Field(default=0, ge=0, description='排序') leader: str | None = None phone: str | None = None diff --git a/backend/app/services/user_service.py b/backend/app/services/user_service.py index 9e59cd31..b4c6b945 100644 --- a/backend/app/services/user_service.py +++ b/backend/app/services/user_service.py @@ -100,8 +100,8 @@ class UserService: return count @staticmethod - async def get_select(*, username: str = None, phone: str = None, status: int = None) -> Select: - return await UserDao.get_all(username=username, phone=phone, status=status) + async def get_select(*, dept: int, username: str = None, phone: str = None, status: int = None) -> Select: + return await UserDao.get_all(dept=dept, username=username, phone=phone, status=status) @staticmethod async def update_permission(*, request: Request, pk: int) -> int: diff --git a/backend/sql/create_tables.sql b/backend/sql/create_tables.sql index 15dda60f..532679e8 100644 --- a/backend/sql/create_tables.sql +++ b/backend/sql/create_tables.sql @@ -99,6 +99,7 @@ CREATE TABLE sys_menu ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL COMMENT '菜单名称', + title varchar(50) not null comment '菜单标题', level INTEGER NOT NULL COMMENT '菜单层级', sort INTEGER NOT NULL COMMENT '排序', icon VARCHAR(100) COMMENT '菜单图标', diff --git a/backend/sql/init_test_data.sql b/backend/sql/init_test_data.sql index 8dcb8247..82b1ab00 100644 --- a/backend/sql/init_test_data.sql +++ b/backend/sql/init_test_data.sql @@ -1,14 +1,23 @@ INSERT INTO fba.sys_dept (id, name, level, sort, leader, phone, email, status, del_flag, parent_id, created_time, updated_time) VALUES (1, 'test', 0, 0, null, null, null, 1, 0, null, '2023-06-26 17:13:45', null); -insert into fba.sys_menu (id, name, level, sort, icon, path, menu_type, component, perms, status, remark, parent_id, created_time, updated_time, `show`, cache) -values (1, 'test', 0, 0, null, null, 0, null, null, 1, null, null, '2023-06-26 17:13:45', null, 0, 1), - (2, 'dashboard', 0, 0, 'icon-dashboard', '/dashboard', 0, '/dashboard/workplace/index.vue', null, 1, null, null, '2023-06-30 10:10:34', null, 1, 1), - (3, 'Workplace', 0, 0, null, '/workplace', 0, null, null, 1, null, 2, '2023-06-30 10:11:40', null, 1, 1), - (4, 'arcoWebsite', 0, 101, 'icon-link', 'https://arco.design', 0, null, null, 1, null, null, '2023-06-30 10:13:04', null, 1, 1), - (5, 'log', 0, 1, 'icon-bug', '/log', 0, null, null, 1, null, null, '2023-06-30 10:13:54', null, 1, 1), - (6, 'Login', 0, 0, null, '/login', 0, '/log/login/index.vue', null, 1, null, 5, '2023-06-30 10:14:23', null, 1, 1), - (7, 'faq', 0, 102, 'icon-question-circle', 'https://arco.design/vue/docs/pro/faq', 0, null, null, 1, null, null, '2023-06-30 10:14:56', null, 1, 1); +insert into fba.sys_menu (id, name, level, sort, icon, path, menu_type, component, perms, status, remark, parent_id, created_time, updated_time, show, cache, title) +values (1, 'test', 0, 0, null, null, 0, null, null, 1, null, null, '2023-06-26 17:13:45', null, 0, 1, '测试'), + (2, 'dashboard', 0, 0, 'icon-dashboard', '/dashboard', 0, '/dashboard/workplace/index.vue', null, 1, null, null, '2023-06-30 10:10:34', null, 1, 1, '仪表盘'), + (3, 'Workplace', 0, 0, null, '/workplace', 1, null, null, 1, null, 2, '2023-06-30 10:11:40', null, 1, 1, '工作台'), + (4, 'arcoWebsite', 0, 888, 'icon-link', 'https://arco.design', 0, null, null, 1, null, null, '2023-06-30 10:13:04', '2023-07-07 20:05:20', 1, 1, 'arco官网'), + (5, 'log', 0, 66, 'icon-bug', '/log', 0, null, null, 1, '这是系统日志记录;这是系统日志记录;这是系统日志记录;这是系统日志记录;这是系统日志记录;这是系统日志记录;这是系统日志记录;这是系统日志记录;这是系统日志记录;这是系统日志记录;', null, '2023-06-30 10:13:54', '2023-07-07 20:04:42', 1, 1, '日志'), + (6, 'Login', 0, 0, null, '/login', 1, '/log/login/index.vue', null, 1, null, 5, '2023-06-30 10:14:23', null, 1, 1, '登录日志'), + (7, 'faq', 0, 999, 'icon-question-circle', 'https://arco.design/vue/docs/pro/faq', 0, null, null, 1, null, null, '2023-06-30 10:14:56', '2023-07-07 20:05:10', 1, 1, '常见问题'), + (8, 'admin', 0, 6, 'icon-settings', '/admin', 0, '', null, 1, null, null, '2023-07-04 10:52:48', '2023-07-07 20:06:02', 1, 1, '系统管理'), + (9, 'SysMenu', 0, 2, '', '/sys-menu', 1, '/admin/menu/index.vue', null, 1, '系统后台菜单管理,玛卡巴卡?', 8, '2023-07-04 10:55:02', '2023-07-08 22:43:53', 1, 1, '菜单管理'), + (10, 'test', 0, 100, null, null, 0, null, null, 1, null, null, '2023-07-07 20:23:57', '2023-07-07 20:04:53', 0, 1, '测试2'), + (11, 'test', 0, 0, null, null, 1, null, null, 1, null, 10, '2023-07-07 20:20:55', null, 1, 1, '测试3'), + (12, '', 0, 0, null, null, 2, null, null, 1, null, 11, '2023-07-07 20:42:31', null 1, 1, '测试4'), + (13, '', 0, 0, null, null, 2, null, null, 1, null, 11, '2023-07-07 20:42:52', null 1, 1, '测试5'), + (14, '', 0, 0, null, null, 2, null, null, 1, null, 11, '2023-07-07 20:16:27', null, 1, 1, '测试6'), + (15, 'Opera', 0, 0, null, '/opera', 1, '/log/opera/index.vue', null, 1, null, 5, '2023-07-07 20:28:21', null, 1, 1, '操作日志'), + (16, 'SysDept', 0, 0, null, 'sys-dept', 1, '/admin/dept/index.vue', null, 1, null, 8, '2023-07-08 22:43:20', null, 1, 1, '部门管理'); INSERT INTO fba.sys_role (id, name, data_scope, status, remark, created_time, updated_time) VALUES (1, 'test', 2, 1, null, '2023-06-26 17:13:45', null);