diff --git a/README.md b/README.md index 8e2dc5c8..a3128c49 100644 --- a/README.md +++ b/README.md @@ -128,8 +128,9 @@ Execute tests via pytest cd backend/app/ ``` -3. Initialize the test data using the `backend/sql/init_test_data.sql` file -4. Execute the test command +3. Using `backend/sql/create_tables.sql` file to create database tables +4. Initialize the test data using the `backend/sql/init_test_data.sql` file +5. Execute the test command ```shell pytest -vs --disable-warnings diff --git a/README.zh-CN.md b/README.zh-CN.md index 7d6594c6..0a446640 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -126,8 +126,9 @@ cd backend/app/ ``` -3. 使用 `backend/sql/init_test_data.sql` 文件初始化测试数据 -4. 执行测试命令 +3. 使用 `backend/sql/create_tables.sql` 文件创建数据库表 +4. 使用 `backend/sql/init_test_data.sql` 文件初始化测试数据 +5. 执行测试命令 ```shell pytest -vs --disable-warnings diff --git a/backend/app/init_test_data.py b/backend/app/init_test_data.py deleted file mode 100644 index 7cef7c95..00000000 --- a/backend/app/init_test_data.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -import asyncio - -from email_validator import EmailNotValidError, validate_email -from faker import Faker - -from backend.app.common.jwt import get_hash_password -from backend.app.common.log import log -from backend.app.database.db_mysql import async_db_session -from backend.app.models import User, Role, Menu, Dept - - -class InitTestData: - """初始化测试数据""" - - def __init__(self, session): - self.fake = Faker('zh_CN') - self.session = session - - async def create_dept(self): - """自动创建部门""" - async with self.session.begin() as db: - department_obj = Dept(name='test') - db.add(department_obj) - log.info('部门 test 创建成功') - - async def create_role(self): - """自动创建角色""" - async with self.session.begin() as db: - role_obj = Role(name='test') - role_obj.menus.append(Menu(name='test')) - db.add(role_obj) - log.info('角色 test 创建成功') - - async def create_test_user(self): - """创建测试用户""" - username = 'test' - password = 'test' - email = 'test@gmail.com' - user_obj = User( - username=username, - nickname=username, - password=await get_hash_password(password), - email=email, - is_superuser=True, - dept_id=1, - ) - async with self.session.begin() as db: - user_obj.roles.append(await db.get(Role, 1)) - db.add(user_obj) - log.info(f'测试用户创建成功,账号:{username},密码:{password}') - - async def create_superuser_by_yourself(self): - """手动创建管理员账户""" - log.info('开始创建自定义管理员用户') - print('请输入用户名:') - username = input() - print('请输入密码:') - password = input() - print('请输入邮箱:') - while True: - email = input() - try: - validate_email(email, check_deliverability=False).email - except EmailNotValidError: - print('邮箱不符合规范,请重新输入:') - continue - break - user_obj = User( - username=username, - nickname=username, - password=await get_hash_password(password), - email=email, - is_superuser=True, - dept_id=1, - ) - async with self.session.begin() as db: - user_obj.roles.append(await db.get(Role, 1)) - db.add(user_obj) - log.info(f'自定义管理员用户创建成功,账号:{username},密码:{password}') - - async def fake_user(self): - """自动创建普通用户""" - username = self.fake.user_name() - password = self.fake.password() - email = self.fake.email() - user_obj = User( - username=username, - nickname=username, - password=await get_hash_password(password), - email=email, - is_superuser=False, - dept_id=1, - ) - async with self.session.begin() as db: - user_obj.roles.append(await db.get(Role, 1)) - db.add(user_obj) - log.info(f'普通用户创建成功,账号:{username},密码:{password}') - - async def fake_no_status_user(self): - """自动创建锁定普通用户""" - username = self.fake.user_name() - password = self.fake.password() - email = self.fake.email() - user_obj = User( - username=username, - nickname=username, - password=await get_hash_password(password), - email=email, - status=0, - is_superuser=False, - dept_id=1, - ) - async with self.session.begin() as db: - user_obj.roles.append(await db.get(Role, 1)) - db.add(user_obj) - log.info(f'普通锁定用户创建成功,账号:{username},密码:{password}') - - async def fake_superuser(self): - """自动创建管理员用户""" - username = self.fake.user_name() - password = self.fake.password() - email = self.fake.email() - user_obj = User( - username=username, - nickname=username, - password=await get_hash_password(password), - email=email, - is_superuser=True, - dept_id=1, - ) - async with self.session.begin() as db: - user_obj.roles.append(await db.get(Role, 1)) - db.add(user_obj) - log.info(f'管理员用户创建成功,账号:{username},密码:{password}') - - async def fake_no_status_superuser(self): - """自动创建锁定管理员用户""" - username = self.fake.user_name() - password = self.fake.password() - email = self.fake.email() - user_obj = User( - username=username, - nickname=username, - password=await get_hash_password(password), - email=email, - status=0, - is_superuser=True, - dept_id=1, - ) - async with self.session.begin() as db: - user_obj.roles.append(await db.get(Role, 1)) - db.add(user_obj) - log.info(f'管理员锁定用户创建成功,账号:{username},密码:{password}') - - async def init_data(self): - """自动创建数据""" - log.info('⏳ 开始初始化数据') - await self.create_dept() - await self.create_role() - await self.create_test_user() - await self.create_superuser_by_yourself() - await self.fake_user() - await self.fake_no_status_user() - await self.fake_superuser() - await self.fake_no_status_superuser() - log.info('✅ 数据初始化完成') - - -if __name__ == '__main__': - init = InitTestData(session=async_db_session) - loop = asyncio.get_event_loop() - loop.run_until_complete(init.init_data()) diff --git a/backend/app/schemas/role.py b/backend/app/schemas/role.py index b569590f..1043ecc8 100644 --- a/backend/app/schemas/role.py +++ b/backend/app/schemas/role.py @@ -11,9 +11,7 @@ from backend.app.schemas.menu import GetAllMenu class RoleBase(SchemaBase): name: str - data_scope: RoleDataScopeType = Field( - default=RoleDataScopeType.custom, description='权限范围(1:全部数据权限 2:自定义数据权限)' - ) + data_scope: RoleDataScopeType = Field(default=RoleDataScopeType.custom, description='权限范围(1:全部数据权限 2:自定义数据权限)') status: StatusType = Field(default=StatusType.enable) remark: str | None = None diff --git a/backend/app/tests/init_test_data.py b/backend/app/tests/init_test_data.py deleted file mode 100644 index fb7ae737..00000000 --- a/backend/app/tests/init_test_data.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -import sys - -sys.path.append('../../') - -import asyncio - -from backend.app.init_test_data import InitTestData -from backend.app.tests.utils.db_mysql import async_db_session, create_table - -if __name__ == '__main__': - init = InitTestData(session=async_db_session) - loop = asyncio.get_event_loop() - loop.run_until_complete(create_table()) - loop.run_until_complete(init.init_data()) diff --git a/backend/sql/create_tables.sql b/backend/sql/create_tables.sql index 532679e8..46c6e311 100644 --- a/backend/sql/create_tables.sql +++ b/backend/sql/create_tables.sql @@ -49,8 +49,7 @@ CREATE TABLE sys_dept created_time DATETIME NOT NULL COMMENT '创建时间', updated_time DATETIME COMMENT '更新时间', PRIMARY KEY (id), - FOREIGN KEY (parent_id) REFERENCES sys_dept (id) ON DELETE SET NULL, - UNIQUE (name) + FOREIGN KEY (parent_id) REFERENCES sys_dept (id) ON DELETE SET NULL ); CREATE INDEX ix_sys_dept_id ON sys_dept (id); @@ -98,8 +97,8 @@ CREATE INDEX ix_sys_login_log_id ON sys_login_log (id); CREATE TABLE sys_menu ( id INTEGER NOT NULL AUTO_INCREMENT, + title VARCHAR(50) NOT NULL COMMENT '菜单标题', 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 '菜单图标', @@ -108,15 +107,15 @@ CREATE TABLE sys_menu component VARCHAR(255) COMMENT '组件路径', perms VARCHAR(100) COMMENT '权限标识', status INTEGER NOT NULL COMMENT '菜单状态(0停用 1正常)', - `show` INTEGER NOT NULL comment '是否显示(0否 1是)', - cache INTEGER NOT NULL comment '是否缓存(0否 1是)', + `show` INTEGER NOT NULL COMMENT '是否显示(0否 1是)', + cache INTEGER NOT NULL COMMENT '是否缓存(0否 1是)', remark LONGTEXT COMMENT '备注', parent_id INTEGER COMMENT '父菜单ID', created_time DATETIME NOT NULL COMMENT '创建时间', updated_time DATETIME COMMENT '更新时间', PRIMARY KEY (id), FOREIGN KEY (parent_id) REFERENCES sys_menu (id) ON DELETE SET NULL, - UNIQUE (name) + UNIQUE (title) ); CREATE INDEX ix_sys_menu_id ON sys_menu (id); @@ -154,7 +153,7 @@ CREATE TABLE sys_role ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(20) NOT NULL COMMENT '角色名称', - data_scope INTEGER COMMENT '数据范围(1:全部数据权限 2:自定数据权限)', + data_scope INTEGER COMMENT '权限范围(1:全部数据权限 2:自定义数据权限)', status INTEGER NOT NULL COMMENT '角色状态(0停用 1正常)', remark LONGTEXT COMMENT '备注', created_time DATETIME NOT NULL COMMENT '创建时间', diff --git a/backend/sql/init_test_data.sql b/backend/sql/init_test_data.sql index 65016232..37db1341 100644 --- a/backend/sql/init_test_data.sql +++ b/backend/sql/init_test_data.sql @@ -1,28 +1,24 @@ 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, 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, '部门管理'); - (17, 'SysApi', 0, 1, null, 'sys-api', 1, '/admin/api/index.vue', null, 1, null, 8, '2023-07-10 13:10:16', null, 1, 1, 'API管理'); - (18, 'monitor', 0, 88, 'icon-computer', null, 0, null, null, 1, null, null, '2023-07-11 20:20:20', null, 1, 1, '系统监控'), - (19, 'Redis', 0, 0, null, null, 1, '/monitor/redis/index.vue', null, 1, null, 18, '2023-07-11 20:21:28', null, 1, 1, 'Redis监控'), - (20, 'Server', 0, 0, null, 'server', 1, '/monitor/server/index.vue', null, 1, null, 18, '2023-07-11 20:23:43', null, 1, 1, '服务器监控'); - (21, 'SysUser', 0, 0, null, 'sys-user', 1, '/admin/user/index.vue', null, 1, null, 8, '2023-07-13 03:32:47', null, 1, 1, '用户管理'); +insert into fba.sys_menu (id, title, name, level, sort, icon, path, menu_type, component, perms, status, `show`, cache, remark, parent_id, created_time, updated_time) +values (1, '测试', 'test', 0, 0, '', null, 0, null, null, 0, 0, 1, null, null, '2023-07-27 19:14:10', '2023-07-27 19:14:52'), + (2, '仪表盘', 'dashboard', 0, 0, 'IconDashboard', 'dashboard', 1, '/dashboard/workplace/index.vue', null, 1, 1, 1, null, null, '2023-07-27 19:15:45', null), + (3, '工作台', 'Workplace', 0, 0, null, 'workplace', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:17:59', null), + (4, 'arco官网', 'arcoWebsite', 0, 888, 'IconLink', 'https://arco.design', 1, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:23', null), + (5, '日志', 'log', 0, 66, 'IconBug', 'log', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:59', null), + (6, '登录日志', 'Login', 0, 0, null, 'login', 1, '/log/login/index.vue', null, 1, 1, 1, null, 5, '2023-07-27 19:20:56', null), + (7, '操作日志', 'Opera', 0, 0, null, 'opera', 1, '/log/opera/index.vue', null, 1, 1, 1, null, 5, '2023-07-27 19:21:28', null), + (8, '常见问题', 'faq', 0, 999, 'IconQuestion', 'https://arco.design/vue/docs/pro/faq', 1, null, null, 1, 1, 1, null, null, '2023-07-27 19:22:24', null), + (9, '系统管理', 'admin', 0, 6, 'IconSettings', 'admin', 1, null, null, 1, 1, 1, null, null, '2023-07-27 19:23:00', null), + (10, '部门管理', 'SysDept', 0, 0, null, 'sys-dept', 1, '/admin/dept/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:23:42', null), + (11, 'API管理', 'SysApi', 0, 1, null, 'sys-api', 1, '/admin/api/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:24:12', null), + (12, '用户管理', 'SysUser', 0, 0, null, 'sys-user', 1, '/admin/user/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:25:13', null), + (13, '角色管理', 'SysRole', 0, 2, null, 'sys-role', 1, '/admin/role/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:25:45', null), + (14, '菜单管理', 'SysMenu', 0, 2, null, 'sys-menu', 1, '/admin/menu/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:45:29', null), + (15, '系统监控', 'monitor', 0, 88, 'IconComputer', 'monitor', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:27:08', null), + (16, 'Redis监控', 'Redis', 0, 0, null, 'redis', 1, '/monitor/redis/index.vue', null, 1, 1, 1, null, 14, '2023-07-27 19:28:03', null), + (17, '服务器监控', 'Server', 0, 0, null, 'server', 1, '/monitor/server/index.vue', null, 1, 1, 1, null, 14, '2023-07-27 19:28:29', null); 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);