219 Commits

Author SHA1 Message Date
insistence
591dbe06a2 !22 RuoYi-Vue3-FastAPI v1.5.1
Merge pull request !22 from insistence/develop
2024-11-12 07:35:06 +00:00
insistence
43b7931591 docs: 更新README文档 2024-11-12 15:31:01 +08:00
insistence
51257df07c chore: 升级版本至1.5.1 2024-11-12 15:30:54 +08:00
insistence
c282f362f4 perf: 移除已弃用的log_decorator装饰器 2024-11-12 15:10:17 +08:00
insistence
425d6e00eb perf: 校检文件名是否包含特殊字符 2024-11-08 17:10:54 +08:00
insistence
564d470240 perf: 优化字典数组条件判断 2024-11-08 17:06:21 +08:00
insistence
a1937448d6 refactor: 定时任务改用AsyncIOScheduler和AsyncIOExecutor 2024-11-07 10:01:49 +08:00
insistence
1ddb1bd5b5 feat: 定时任务新增支持调用异步函数 2024-11-06 22:28:09 +08:00
insistence
4f4ee34e8d style: 修复书写错误 2024-10-31 15:38:58 +08:00
insistence
8202e8c9db !21 RuoYi-Vue3-FastAPI v1.5.0
Merge pull request !21 from insistence/develop
2024-10-22 12:05:05 +00:00
insistence
b797ffb5af docs: 更新README文档 2024-10-22 20:02:09 +08:00
insistence
c2795c49e4 chore: 升级版本至1.5.0 2024-10-22 20:01:59 +08:00
insistence
545cb6606c revert: 因fastapi查询参数模型底层存在bug,回滚查询参数模型声明方式为as_query 2024-10-22 19:41:28 +08:00
insistence
d0211cfd11 perf: 优化上传图片带域名时不增加前缀 2024-10-22 19:36:27 +08:00
insistence
a3c9ffdad5 fix: 修复登录日志导出文件名称错误的问题 2024-10-22 19:34:13 +08:00
insistence
5ce1ffd557 perf: 优化参数设置页面 2024-10-22 17:04:34 +08:00
insistence
850d8d7890 fix: 修复DictTag组件控制台抛异常的问题 #IAYSVZ 2024-10-22 17:04:08 +08:00
insistence
53cc6eb8ce perf: 优化列表查询排序 2024-10-22 16:28:08 +08:00
insistence
c7af974d3f feat: 新增对PostgreSQL数据库的支持 2024-10-22 16:27:47 +08:00
insistence
bb143ac15a perf: 优化CamelCaseUtil和SnakeCaseUtil以兼容更多转换场景 2024-10-21 11:11:05 +08:00
insistence
c6c9020d89 !18 RuoYi-Vue3-FastAPI v1.4.0
Merge pull request !18 from insistence/develop
2024-09-29 02:24:08 +00:00
insistence
df1929ab24 docs: 更新README文档 2024-09-29 09:50:32 +08:00
insistence
3d15c37182 chore: 升级版本至1.4.0 2024-09-29 09:50:23 +08:00
insistence
d9810bfb67 perf: 优化前端登录请求方法 2024-09-29 09:47:25 +08:00
insistence
5a04889f84 refactor: 基于fastapi0.115.0版本新特性,直接使用pydantic模型接收查询参数和表单数据,移除as_query和as_form使用方式 2024-09-29 09:43:38 +08:00
insistence
8a964bf3f5 chore: 更新fastapi版本至0.115.0 2024-09-29 09:39:56 +08:00
insistence
f573e3e93b style: 修复书写错误 2024-09-24 20:20:04 +08:00
insistence
84a02a42aa !17 RuoYi-Vue3-FastAPI v1.3.3
Merge pull request !17 from insistence/develop
2024-09-04 01:16:02 +00:00
insistence
c750908c04 docs: 更新README文档 2024-09-04 09:07:42 +08:00
insistence
af89388294 chore: 升级版本至1.3.3 2024-09-04 09:07:34 +08:00
insistence
09380dc94f chore: 更新pydantic-validation-decorator版本为0.1.4,修复了一些底层bug 2024-09-04 09:02:13 +08:00
insistence
82c84b2afe perf: 日志装饰器异常处理增加logger打印日志 2024-09-04 09:01:41 +08:00
insistence
f404aba689 fix: 修复在线用户模块条件查询无效的问题 2024-08-17 16:52:46 +08:00
insistence
9013b1917e perf: 优化在线用户模块前后端字段描述一致 2024-08-17 16:51:38 +08:00
insistence
c415dfa8e1 !16 RuoYi-Vue3-FastAPI v1.3.2
Merge pull request !16 from insistence/develop
2024-08-08 01:38:22 +00:00
insistence
5765e967ae docs: 更新README文档 2024-08-08 09:28:33 +08:00
insistence
1ba4d959ce chore: 升级版本至1.3.2 2024-08-08 09:27:51 +08:00
insistence
df8ab6bc55 chore: 调整.gitignore策略 2024-08-08 09:24:09 +08:00
insistence
ca6668331f style: 优化添加中间件函数注释 2024-08-08 09:20:57 +08:00
insistence
d49d05b776 feat: 新增gzip压缩中间件 2024-08-08 09:18:07 +08:00
insistence
d8e3f7dca1 fix: 修复定时任务监听函数中事件没有job_id报错的问题 2024-08-07 14:41:57 +08:00
insistence
5ee1a64587 fix: 修复分页函数计算has_next错误的问题 #10 2024-08-02 10:27:06 +08:00
insistence
9a31c21943 !15 RuoYi-Vue3-FastAPI v1.3.1
Merge pull request !15 from insistence/develop
2024-07-31 03:24:06 +00:00
insistence
e52f0f42cb docs: 更新README文档 2024-07-31 11:14:38 +08:00
insistence
1f51525dfa chore: 升级版本至1.3.1 2024-07-31 11:13:57 +08:00
insistence
a1c77829cd perf: 补充定时任务违规字符串 2024-07-31 10:59:01 +08:00
insistence
07771c180d fix: 修复1.3.0版本采用新的异常处理机制后日志装饰器无法记录异常日志的问题 2024-07-27 16:31:01 +08:00
insistence
d55ddbebaf !14 RuoYi-Vue3-FastAPI v1.3.0
Merge pull request !14 from insistence/develop
2024-07-16 10:11:31 +00:00
insistence
bea5d9428e docs: 更新README文档 2024-07-16 15:24:51 +08:00
insistence
e275cbdaee chore: 升级版本至1.3.0 2024-07-16 15:23:25 +08:00
insistence
5742582073 chore: 调整vue版本以适应部分模块 2024-07-16 15:21:52 +08:00
insistence
eab51c0355 perf: 优化API文档字段描述显示 2024-07-16 15:19:36 +08:00
insistence
6734df119a perf: 优化用户管理模块部分接口逻辑 2024-07-16 15:15:43 +08:00
insistence
42269f78c3 chore: 使用PyJWT替换python-jose以解决一些安全性问题 2024-07-16 09:40:56 +08:00
insistence
93d7ecb1ee chore: 更新依赖至最新版本 2024-07-16 09:39:24 +08:00
insistence
70e1b7a078 refactor: 重构RedisInitKeyConfig为枚举类型 2024-07-16 08:52:49 +08:00
insistence
e359471361 perf: 对数据权限sql去重 2024-07-16 08:13:11 +08:00
insistence
7df6616e54 refactor: 重构数据权限逻辑 2024-07-15 21:31:01 +08:00
insistence
2263897111 perf: 优化部分ids字符串分割写法 2024-07-15 21:24:17 +08:00
insistence
d1b6db4769 feat: 菜单管理新增路由名称 2024-07-15 15:46:20 +08:00
insistence
a001ff8099 fix: 修复重复的getList 2024-07-15 14:59:33 +08:00
insistence
ee625ea3ed style: 优化代码 2024-07-15 14:57:58 +08:00
insistence
3cf31828e0 perf: cron生成的表达式hour优化 2024-07-15 14:37:40 +08:00
insistence
bcf7467308 perf: 优化部分ids进行字符串分割后的校验 2024-07-15 14:21:05 +08:00
insistence
997a3068ac fix: 修复升级element-plus后el-radio使用label过期的问题 2024-07-15 11:38:29 +08:00
insistence
753403b0f8 fix: 修复check_role_data_scope_services参数类型不匹配的问题 2024-07-15 11:37:28 +08:00
insistence
1d4fb2cdb2 fix: 修复validate_second_or_minute参数丢失的问题 2024-07-15 11:36:34 +08:00
insistence
82ce4f00f5 refactor: 重构日志装饰器为Log 2024-07-15 10:39:52 +08:00
insistence
068503d275 feat: 新增CronUtil工具类 2024-07-15 08:49:15 +08:00
insistence
c39375b776 perf: 优化定时任务模块service层及异常处理 2024-07-14 22:37:35 +08:00
insistence
4669d6b29b chore: 调整ServiceException的日志级别 2024-07-13 18:16:55 +08:00
insistence
e3b422cc6e style: 优化部分文件中的函数及类注释 2024-07-13 18:15:35 +08:00
insistence
c23a3ccfaf style: 使用ruff格式化app.py,优化导入 2024-07-12 11:36:06 +08:00
insistence
5d8b177a12 style: 使用ruff格式化server.py,优化导入 2024-07-12 11:35:58 +08:00
insistence
5dd6513706 style: 使用ruff格式化aspect模块,优化导入 2024-07-12 11:31:10 +08:00
insistence
bdb1a67d44 style: 使用ruff格式化annotation模块,优化导入 2024-07-12 11:29:15 +08:00
insistence
7af22e97ad style: 使用ruff格式化sub_applications模块,优化导入 2024-07-12 11:23:46 +08:00
insistence
fea346413c style: 使用ruff格式化module_task模块,优化导入 2024-07-12 11:23:01 +08:00
insistence
44af38612c style: 使用ruff格式化middlewares模块,优化导入 2024-07-12 11:22:23 +08:00
insistence
13cfc60782 style: 使用ruff格式化exceptions模块,优化导入 2024-07-12 11:21:37 +08:00
insistence
9b40c05e64 style: 使用ruff格式化config模块,优化导入 2024-07-12 11:19:07 +08:00
insistence
ed9ad54b46 style: 使用ruff格式化utils模块,优化导入 2024-07-12 11:13:01 +08:00
insistence
380693c66d style: 使用ruff格式化验证码模块,优化导入 2024-07-12 11:06:57 +08:00
insistence
91e31cfbf7 style: 使用ruff格式化服务监控模块,优化导入 2024-07-12 11:04:40 +08:00
insistence
371fed69df style: 使用ruff格式化缓存监控及列表模块,优化导入 2024-07-12 10:59:41 +08:00
insistence
f41ee26067 style: 使用ruff格式化通用模块,优化导入 2024-07-12 10:56:26 +08:00
insistence
749fe85cad style: 使用ruff格式化参数配置模块,优化导入 2024-07-12 10:51:34 +08:00
insistence
eb29d616d1 style: 使用ruff格式化部门管理模块,优化导入 2024-07-12 10:45:10 +08:00
insistence
eac920fcae style: 使用ruff格式化字典管理模块,优化导入 2024-07-12 10:38:36 +08:00
insistence
659163d662 style: 使用ruff格式化定时任务模块,优化导入 2024-07-12 10:28:28 +08:00
insistence
ccb9e2a314 style: 使用ruff格式化日志管理模块,优化导入 2024-07-12 10:13:34 +08:00
insistence
5891ec1930 style: 使用ruff格式化菜单管理模块,优化导入 2024-07-12 09:59:12 +08:00
insistence
2c86992cac style: 使用ruff格式化通知公告管理模块,优化导入 2024-07-12 09:50:10 +08:00
insistence
6d0d772749 style: 使用ruff格式化在线用户模块,优化导入 2024-07-12 09:43:36 +08:00
insistence
ca86c5ffb7 style: 使用ruff格式化岗位管理模块,优化导入 2024-07-12 09:38:56 +08:00
insistence
e80a44c43a style: 使用ruff格式化用户管理模块do层,优化导入 2024-07-12 09:36:08 +08:00
insistence
4a7c9367d4 style: 使用ruff格式化角色管理模块,优化导入 2024-07-12 09:35:55 +08:00
insistence
bd242c95f7 style: 使用ruff格式化登录模块,优化导入 2024-07-12 09:35:26 +08:00
insistence
40a8c73461 style: 使用ruff格式化用户管理模块,优化导入 2024-07-11 22:24:58 +08:00
insistence
5ae234714f feat: 新增ruff配置文件 2024-07-11 22:24:17 +08:00
insistence
449b7581d8 perf: 优化用户管理模块部分接口数据权限校验 2024-07-11 21:38:44 +08:00
insistence
d0eafb1e09 feat: 部门管理和菜单管理service层引入ServiceWarning 2024-07-11 17:17:56 +08:00
insistence
47d5697653 feat: 新增全局处理自定义服务警告 2024-07-11 16:47:23 +08:00
insistence
0dfc201990 perf: 优化角色管理模块数据权限 2024-07-11 16:36:28 +08:00
insistence
cd260fbcda perf: 优化部门管理模块service层及异常处理 2024-07-11 16:36:04 +08:00
insistence
f87ae9a25b perf: 优化数据权限设置 2024-07-10 21:30:11 +08:00
insistence
0ee473fd07 perf: 优化部分接口dao层查询 2024-07-10 21:29:50 +08:00
insistence
36f45b2c26 fix: 修复升级axios到最新版本后表单数据需手动指定Content-Type的问题 2024-07-10 21:24:00 +08:00
insistence
51bed591d4 perf: 优化缓存监控及缓存列表模块service层及异常处理 2024-07-10 21:21:22 +08:00
insistence
f255595b30 perf: 优化通用模块service层及异常处理 2024-07-10 21:14:41 +08:00
insistence
bbd4a4cd95 perf: 优化日志管理模块service层及异常处理 2024-07-10 21:08:55 +08:00
insistence
95b0cdebfb perf: 优化验证码模块异常处理 2024-07-10 21:02:40 +08:00
insistence
0737adb389 perf: 优化登录模块service层及异常处理 2024-07-10 21:00:43 +08:00
insistence
9878482654 feat: 新增全局处理自定义登录异常 2024-07-10 21:00:25 +08:00
insistence
4d31fe7a92 perf: 优化在线用户模块service层及异常处理 2024-07-10 20:50:39 +08:00
insistence
55babcee4c perf: 优化服务监控模块异常处理 2024-07-10 20:47:51 +08:00
insistence
1bd4bba2f5 perf: 优化角色管理模块service层及异常处理 2024-07-10 17:11:03 +08:00
insistence
013ea25731 perf: 优化菜单管理模块service层及异常处理 2024-07-10 11:08:07 +08:00
insistence
4a17ffbebe perf: 优化字典管理模块service层及异常处理 2024-07-10 10:33:44 +08:00
insistence
e3efca9648 perf: 优化岗位管理模块service层及异常处理 2024-07-09 21:17:50 +08:00
insistence
da54a7e5f5 perf: 优化通知公告管理模块service层及异常处理 2024-07-09 21:03:05 +08:00
insistence
1eff840afa perf: 优化用户管理模块service层及异常处理 2024-07-09 17:07:33 +08:00
insistence
2b19022e29 perf: 优化参数管理模块service层及异常处理 2024-07-09 16:25:27 +08:00
insistence
2fef16e58b feat: 新增全局处理自定义服务异常及其他异常 2024-07-09 16:25:13 +08:00
insistence
09f9dd2784 perf: 参数管理模块service层优化 2024-07-08 16:47:17 +08:00
insistence
e9c4f295ce perf: 编辑用户时接口请求体中删除password 2024-07-07 13:07:48 +08:00
insistence
3684d5a703 fix: 修复编辑字典时修改字典类型异常的问题 2024-07-07 13:06:16 +08:00
insistence
82c61753e3 style: 删除无用的自定义异常 2024-07-07 09:46:29 +08:00
insistence
19f34d6a81 chore: 将validate_annotation封装为pydantic-validation-decorator库 2024-07-07 09:09:19 +08:00
insistence
d500e22b2f feat: 用户管理模块新增和编辑接口新增字段校验 2024-07-05 12:52:41 +08:00
insistence
568ed2b9d7 feat: 角色管理模块新增和编辑接口新增字段校验 2024-07-05 12:52:26 +08:00
insistence
bfac3ff26e feat: 通知公告管理模块新增和编辑接口新增字段校验 2024-07-05 12:52:18 +08:00
insistence
ddfe7c8851 feat: 菜单管理模块新增和编辑接口新增字段校验 2024-07-05 12:52:09 +08:00
insistence
d12c1c31f3 feat: 定时任务管理模块新增和编辑接口新增字段校验 2024-07-05 12:52:00 +08:00
insistence
d5cd7d1ae4 feat: 字典管理模块新增和编辑接口新增字段校验 2024-07-05 12:51:50 +08:00
insistence
841fbd1ae1 feat: 部门管理模块新增和编辑接口新增字段校验 2024-07-05 12:51:41 +08:00
insistence
1f0f35b402 feat: 参数管理模块新增和编辑接口新增字段校验 2024-07-05 12:51:34 +08:00
insistence
ffc932951b perf: 优化validate_annotation中各装饰器逻辑 2024-07-05 12:50:36 +08:00
insistence
9f09d37936 perf: 日志管理模块vo层优化 2024-07-05 11:43:52 +08:00
insistence
f8c246796d perf: 服务监控模块vo层优化 2024-07-05 11:19:31 +08:00
insistence
68906b7e81 perf: 在线用户监控模块vo层优化 2024-07-05 11:07:55 +08:00
insistence
fffff50a00 perf: 登录模块vo层优化 2024-07-05 11:07:33 +08:00
insistence
b7260a40ad perf: 通用模块vo层优化 2024-07-05 11:07:22 +08:00
insistence
a12713f89a perf: 缓存监控模块vo层优化 2024-07-05 11:07:06 +08:00
insistence
0fa264a7bc feat&perf: 用户管理模块vo层优化,新增字段校验 2024-07-05 09:56:49 +08:00
insistence
5dcef7b408 feat&perf: 角色管理模块vo层优化,新增字段校验 2024-07-05 09:31:04 +08:00
insistence
b6f1827fe0 feat&perf: 通知公告管理模块vo层优化,新增字段校验 2024-07-05 09:13:54 +08:00
insistence
57dd4178f4 feat&perf: 菜单管理模块vo层优化,新增字段校验 2024-07-05 09:07:17 +08:00
insistence
cd131ba7a2 feat&perf: 定时任务管理模块vo层优化,新增字段校验 2024-07-05 08:50:42 +08:00
insistence
fad9f484e8 feat&perf: 字典管理模块vo层优化,新增字段校验 2024-07-05 08:31:38 +08:00
insistence
45063936eb perf: 优化参数管理vo层config_type的类型提示 2024-07-05 08:31:19 +08:00
insistence
d1cc297169 refactor: check_annotation.py重命名为validate_annotation.py 2024-07-05 08:11:52 +08:00
insistence
cebbe90eac feat&perf: 部门管理模块vo层优化,新增字段校验 2024-07-04 17:30:14 +08:00
insistence
0ca5aab05a feat: 新增@NetWork字段校验装饰器 2024-07-04 17:29:54 +08:00
insistence
a66061aa89 chore: 更新fastapi版本至0.111.0 2024-07-04 17:29:44 +08:00
insistence
d98d5e8c41 feat&perf: 参数管理模块vo层优化,新增字段校验 2024-07-04 14:32:46 +08:00
insistence
212f981b6a feat: 新增@Pattern字段校验装饰器 2024-07-04 11:52:05 +08:00
insistence
2b3849a573 feat: 新增@Xss字段校验装饰器 2024-07-04 10:57:37 +08:00
insistence
b5d0b5a170 feat: 新增字符串工具类 2024-07-04 10:56:44 +08:00
insistence
66595d10a3 feat: 岗位管理模块新增和编辑接口新增字段校验 2024-07-04 10:56:23 +08:00
insistence
2a20042680 feat: 新增@ValidateFields字段校验装饰器 2024-07-04 10:56:05 +08:00
insistence
549948ba37 feat: 新增FieldValidatorException全局异常处理 2024-07-04 09:54:49 +08:00
insistence
2f3e5171b0 feat&perf: 岗位管理模块vo层优化,新增字段校验 2024-07-03 21:09:43 +08:00
insistence
cfa68999a9 feat: 新增@NotBlank和@Size装饰器用于字段校验 2024-07-03 21:08:00 +08:00
insistence
6109c45dbe feat: 新增常量配置 2024-07-03 16:41:20 +08:00
insistence
e8a4922541 style: 删除多余print 2024-07-03 09:38:50 +08:00
insistence
71b4a10991 perf: 优化用户管理dao层status和del_flag类型与数据库保持一致 2024-07-01 21:56:17 +08:00
insistence
0d2aa3e8b8 perf: 优化角色管理dao层status和del_flag类型与数据库保持一致 2024-07-01 21:50:15 +08:00
insistence
d7d8dcda1c perf: 优化岗位管理dao层status类型与数据库保持一致 2024-07-01 21:48:14 +08:00
insistence
1fa14118ff perf: 优化菜单管理dao层status和del_flag类型与数据库保持一致 2024-07-01 21:46:43 +08:00
insistence
7bb947c14a perf: 优化登录模块dao层status和del_flag类型与数据库保持一致 2024-07-01 21:44:04 +08:00
insistence
d8011c8738 perf: 优化定时任务管理dao层status类型与数据库保持一致 2024-07-01 21:41:10 +08:00
insistence
adb6d63eb4 perf: 优化字典管理dao层status类型与数据库保持一致 2024-07-01 21:39:22 +08:00
insistence
f1baf96f95 perf: 优化部门管理dao层status和del_flag类型与数据库保持一致 2024-07-01 21:35:29 +08:00
insistence
d0e82b56ab fix: 修复移动端左侧菜单无法显示的问题 2024-06-30 21:55:37 +08:00
insistence
c64519d8f9 chore: 升级前端组件依赖到最新版本 2024-06-30 21:40:35 +08:00
insistence
77b4eb10b1 perf: 优化@log_decorator参数的类型提示 2024-06-30 21:04:50 +08:00
insistence
e705a1c32b !13 RuoYi-Vue3-FastAPI v1.2.2
Merge pull request !13 from insistence/develop
2024-06-29 12:16:55 +00:00
insistence
114cda0b76 docs: 更新README文档 2024-06-29 20:13:42 +08:00
insistence
847445df82 chore: 升级版本至1.2.2 2024-06-29 20:13:03 +08:00
insistence
2360c7a12d fix: 修复菜单生成路由时组件条件判断错误的问题 2024-06-29 19:49:52 +08:00
insistence
581ef15917 fix: 修复删除定时任务时未移除调度中任务的问题 2024-06-29 17:03:28 +08:00
insistence
3180da36da !12 RuoYi-Vue3-FastAPI v1.2.1
Merge pull request !12 from insistence/develop
2024-06-28 06:40:53 +00:00
insistence
ad20a5da70 docs: 更新README文档 2024-06-28 14:35:18 +08:00
insistence
b04debcf75 chore: 升级版本至1.2.1 2024-06-28 14:31:48 +08:00
insistence
2cf5268f7d perf: 修改代理localhost为127.0.0.1以适配部分设备解析localhost异常的问题 2024-06-28 14:31:22 +08:00
insistence
43f903c6e0 fix: 修复菜单挂载到根目录时路由加载异常等一系列相关问题 2024-06-27 21:51:01 +08:00
insistence
d08fe67ab8 fix: 修复各模块新增数据时创建时间记录异常的问题 2024-06-26 21:05:25 +08:00
insistence
88f9574aaa chore: 回退通用上传接口返回url修复 2024-06-16 15:23:28 +08:00
insistence
2387c2e7df fix: 修复通用上传接口返回url异常的问题 2024-06-15 15:44:50 +08:00
insistence
1dd4d8296b !11 RuoYi-Vue3-FastAPI v1.2.0
Merge pull request !11 from insistence/async-database
2024-05-17 08:17:47 +00:00
insistence
b1e3fcdc30 docs: 更新README文档 2024-05-17 16:04:06 +08:00
insistence
6064535c22 chore: 升级版本至1.2.0 2024-05-17 16:03:40 +08:00
insistence
8b3d04ca06 feat: 新增SnakeCaseUtil工具类,将原CamelCaseUtil工具类的camel_to_snake函数迁移至SnakeCaseUtil工具类 2024-05-17 15:59:12 +08:00
insistence
4b13e492fc style: 修复.env.prod文件书写错误 2024-05-17 15:16:59 +08:00
insistence
5319327c37 chore: 增加asyncmy依赖用于支持orm异步操作mysql 2024-05-17 15:11:14 +08:00
insistence
3b13237ad6 fix: 修复清空定时任务日志异常的问题 2024-05-17 15:07:17 +08:00
insistence
ef39f5aa1e fix: 修复用户管理模块重置用户密码时会异常重置用户岗位和角色的问题 2024-05-17 15:05:34 +08:00
insistence
1972f1cb6d refactor: 重构数据库orm为异步 #I9MRQS 2024-05-17 15:04:30 +08:00
insistence
18103e3d38 !10 RuoYi-Vue3-FastAPI v1.1.3
Merge pull request !10 from insistence/develop
2024-05-13 01:20:40 +00:00
insistence
cb96c878bf docs: 更新README文档 2024-05-13 09:16:04 +08:00
insistence
266b3e3b5c chore: 升级版本至1.1.3 2024-05-13 09:15:01 +08:00
insistence
6ea8ada989 fix: 修复个人中心修改基本资料后端异常的问题 2024-05-11 21:15:14 +08:00
insistence
901a66bafa feat: 用户密码新增非法字符验证 2024-05-11 14:58:02 +08:00
insistence
c9cb8c6542 fix: 修复通知公告列表查询前后端字段不一致的问题 2024-05-11 09:05:07 +08:00
insistence
34f9e891b6 !9 RuoYi-Vue3-FastAPI v1.1.2
Merge pull request !9 from insistence/develop
2024-04-29 01:07:48 +00:00
insistence
fb9dfa4674 docs: 更新README文档 2024-04-29 08:52:12 +08:00
insistence
bbb7214cee chore: 升级版本至1.1.2 2024-04-29 08:43:57 +08:00
insistence
52e92d50d1 perf: 使用@lru_cache缓存ip归属区域查询结果,避免重复调用ip归属区域查询接口以优化性能 2024-04-24 10:03:52 +08:00
insistence
816793b888 feat: 配置文件新增数据库连接池相关配置 2024-04-23 09:04:49 +08:00
insistence
e774e1b26b fix: 修复个人中心修改密码后端异常的问题 2024-04-20 12:55:43 +08:00
insistence
42009cf3f4 !8 RuoYi-Vue3-FastAPI v1.1.1
Merge pull request !8 from insistence/develop
2024-04-19 03:40:20 +00:00
insistence
f4afa20ac2 docs: 更新README文档 2024-04-19 11:39:04 +08:00
insistence
7fd3109b52 chore: 升级版本至1.1.1 2024-04-19 11:38:12 +08:00
insistence
dfb8af23b3 fix: 修复添加菜单时是否外链和是否缓存回显异常的问题 2024-04-19 11:31:24 +08:00
insistence
b423647ad5 fix: 修复获取路由信息时菜单排序不生效的问题 2024-04-17 16:03:49 +08:00
insistence
423491302d fix: 修复菜单配置路由参数不生效的问题 2024-04-17 10:51:16 +08:00
insistence
fa27fd3b68 fix: 修复编辑角色数据权限时后端异常的问题 #I9ENQN 2024-04-08 11:04:32 +08:00
insistence
88b27685c1 fix: 修复编辑定时任务时更新的信息未同步至scheduler的问题 #I9EK56 2024-04-08 11:02:41 +08:00
142 changed files with 8731 additions and 4644 deletions

1
.gitignore vendored
View File

@@ -18,6 +18,7 @@ lib64/
parts/
sdist/
var/
vf_admin/
wheels/
share/python-wheels/
*.egg-info/

View File

@@ -1,27 +1,23 @@
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi-Vue3-FastAPI v1.1.0</h1>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi-Vue3-FastAPI v1.5.1</h1>
<h4 align="center">基于RuoYi-Vue3+FastAPI前后端分离的快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI/stargazers"><img src="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI/badge/star.svg?theme=dark"></a>
<a href="https://github.com/insistence/RuoYi-Vue3-FastAPI"><img src="https://img.shields.io/github/stars/insistence/RuoYi-Vue3-FastAPI?style=social"></a>
<a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI"><img src="https://img.shields.io/badge/RuoYiVue3FastAPI-v1.1.0-brightgreen.svg"></a>
<a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI"><img src="https://img.shields.io/badge/RuoYiVue3FastAPI-v1.5.1-brightgreen.svg"></a>
<a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
<img src="https://img.shields.io/badge/python-≥3.8-blue">
<img src="https://img.shields.io/badge/python-≥3.9-blue">
<img src="https://img.shields.io/badge/MySQL-≥5.7-blue">
</p>
## 平台简介
RuoYi-Vue3-FastAPI是一套全部开源的快速开发平台毫无保留给个人及企业免费使用。
* 前端采用Vue、Element Plus基于<u>[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3)</u>前端项目修改。
* 后端采用FastAPI、sqlalchemy、MySQL、Redis、OAuth2 & Jwt。
* 前端采用Vue3、Element Plus基于<u>[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3)</u>前端项目修改。
* 后端采用FastAPI、sqlalchemy、MySQLPostgreSQL、Redis、OAuth2 & Jwt。
* 权限认证使用OAuth2 & Jwt支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* Vue2版本
@@ -131,15 +127,17 @@ npm run dev 或 yarn dev
# 进入后端目录
cd ruoyi-fastapi-backend
# 安装项目依赖环境
# 如果使用的是MySQL数据库请执行以下命令安装项目依赖环境
pip3 install -r requirements.txt
# 如果使用的是PostgreSQL数据库请执行以下命令安装项目依赖环境
pip3 install -r requirements-pg.txt
# 配置环境
在.env.dev文件中配置开发环境的数据库和redis
# 运行sql文件
1.新建数据库ruoyi-fastapi(默认,可修改)
2.使用命令或数据库连接工具运行sql文件夹下的ruoyi-fastapi.sql
2.如果使用的是MySQL数据库使用命令或数据库连接工具运行sql文件夹下的ruoyi-fastapi.sql如果使用的是PostgreSQL数据库使用命令或数据库连接工具运行sql文件夹下的ruoyi-fastapi-pg.sql
# 运行后端
python3 app.py --env=dev

View File

@@ -10,7 +10,7 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 9099
# 应用版本
APP_VERSION= '1.1.0'
APP_VERSION= '1.5.1'
# 应用是否开启热重载
APP_RELOAD = true
# 应用是否开启IP归属区域查询
@@ -30,6 +30,8 @@ JWT_REDIS_EXPIRE_MINUTES = 30
# -------- 数据库配置 --------
# 数据库类型,可选的有'mysql'、'postgresql',默认为'mysql'
DB_TYPE = 'mysql'
# 数据库主机
DB_HOST = '127.0.0.1'
# 数据库端口
@@ -42,6 +44,14 @@ DB_PASSWORD = 'mysqlroot'
DB_DATABASE = 'ruoyi-fastapi'
# 是否开启sqlalchemy日志
DB_ECHO = true
# 允许溢出连接池大小的最大连接数
DB_MAX_OVERFLOW = 10
# 连接池大小0表示连接数无限制
DB_POOL_SIZE = 50
# 连接回收时间(单位:秒)
DB_POOL_RECYCLE = 3600
# 连接池中没有线程可用时,最多等待的时间(单位:秒)
DB_POOL_TIMEOUT = 30
# -------- Redis配置 --------
# Redis主机

View File

@@ -10,13 +10,13 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 9099
# 应用版本
APP_VERSION= '1.1.0'
APP_VERSION= '1.5.1'
# 应用是否开启热重载
APP_RELOAD = false
# 应用是否开启IP归属区域查询
APP_IP_LOCATION_QUERY = true
# 应用是否允许账号同时登录
APP_SAMETIME_LOGIN = true
APP_SAME_TIME_LOGIN = true
# -------- Jwt配置 --------
# Jwt秘钥
@@ -30,6 +30,8 @@ JWT_REDIS_EXPIRE_MINUTES = 30
# -------- 数据库配置 --------
# 数据库类型,可选的有'mysql'、'postgresql',默认为'mysql'
DB_TYPE = 'mysql'
# 数据库主机
DB_HOST = '127.0.0.1'
# 数据库端口
@@ -42,6 +44,14 @@ DB_PASSWORD = 'root'
DB_DATABASE = 'ruoyi-fastapi'
# 是否开启sqlalchemy日志
DB_ECHO = true
# 允许溢出连接池大小的最大连接数
DB_MAX_OVERFLOW = 10
# 连接池大小0表示连接数无限制
DB_POOL_SIZE = 50
# 连接回收时间(单位:秒)
DB_POOL_RECYCLE = 3600
# 连接池中没有线程可用时,最多等待的时间(单位:秒)
DB_POOL_TIMEOUT = 30
# -------- Redis配置 --------
# Redis主机

View File

@@ -1,5 +1,5 @@
import uvicorn
from server import app, AppConfig
from server import app, AppConfig # noqa: F401
if __name__ == '__main__':
@@ -8,5 +8,5 @@ if __name__ == '__main__':
host=AppConfig.app_host,
port=AppConfig.app_port,
root_path=AppConfig.app_root_path,
reload=AppConfig.app_reload
reload=AppConfig.app_reload,
)

View File

@@ -0,0 +1,152 @@
class CommonConstant:
"""
常用常量
WWW: www主域
HTTP: http请求
HTTPS: https请求
LOOKUP_RMI: RMI远程方法调用
LOOKUP_LDAP: LDAP远程方法调用
LOOKUP_LDAPS: LDAPS远程方法调用
YES: 是否为系统默认(是)
NO: 是否为系统默认(否)
DEPT_NORMAL: 部门正常状态
DEPT_DISABLE: 部门停用状态
UNIQUE: 校验是否唯一的返回标识(是)
NOT_UNIQUE: 校验是否唯一的返回标识(否)
"""
WWW = 'www.'
HTTP = 'http://'
HTTPS = 'https://'
LOOKUP_RMI = 'rmi:'
LOOKUP_LDAP = 'ldap:'
LOOKUP_LDAPS = 'ldaps:'
YES = 'Y'
NO = 'N'
DEPT_NORMAL = '0'
DEPT_DISABLE = '1'
UNIQUE = True
NOT_UNIQUE = False
class HttpStatusConstant:
"""
返回状态码
SUCCESS: 操作成功
CREATED: 对象创建成功
ACCEPTED: 请求已经被接受
NO_CONTENT: 操作已经执行成功,但是没有返回数据
MOVED_PERM: 资源已被移除
SEE_OTHER: 重定向
NOT_MODIFIED: 资源没有被修改
BAD_REQUEST: 参数列表错误(缺少,格式不匹配)
UNAUTHORIZED: 未授权
FORBIDDEN: 访问受限,授权过期
NOT_FOUND: 资源,服务未找到
BAD_METHOD: 不允许的http方法
CONFLICT: 资源冲突,或者资源被锁
UNSUPPORTED_TYPE: 不支持的数据,媒体类型
ERROR: 系统内部错误
NOT_IMPLEMENTED: 接口未实现
WARN: 系统警告消息
"""
SUCCESS = 200
CREATED = 201
ACCEPTED = 202
NO_CONTENT = 204
MOVED_PERM = 301
SEE_OTHER = 303
NOT_MODIFIED = 304
BAD_REQUEST = 400
UNAUTHORIZED = 401
FORBIDDEN = 403
NOT_FOUND = 404
BAD_METHOD = 405
CONFLICT = 409
UNSUPPORTED_TYPE = 415
ERROR = 500
NOT_IMPLEMENTED = 501
WARN = 601
class JobConstant:
"""
定时任务常量
JOB_ERROR_LIST: 定时任务禁止调用模块及违规字符串列表
JOB_WHITE_LIST: 定时任务允许调用模块列表
"""
JOB_ERROR_LIST = [
'app',
'config',
'exceptions',
'import ',
'middlewares',
'module_admin',
'open(',
'os.',
'server',
'sub_applications',
'subprocess.',
'sys.',
'utils',
'while ',
'__import__',
'"',
"'",
',',
'?',
':',
';',
'/',
'|',
'+',
'-',
'=',
'~',
'!',
'#',
'$',
'%',
'^',
'&',
'*',
'<',
'>',
'(',
')',
'[',
']',
'{',
'}',
' ',
]
JOB_WHITE_LIST = ['module_task']
class MenuConstant:
"""
菜单常量
TYPE_DIR: 菜单类型(目录)
TYPE_MENU: 菜单类型(菜单)
TYPE_BUTTON: 菜单类型(按钮)
YES_FRAME: 是否菜单外链(是)
NO_FRAME: 是否菜单外链(否)
LAYOUT: Layout组件标识
PARENT_VIEW: ParentView组件标识
INNER_LINK: InnerLink组件标识
"""
TYPE_DIR = 'M'
TYPE_MENU = 'C'
TYPE_BUTTON = 'F'
YES_FRAME = 0
NO_FRAME = 1
LAYOUT = 'Layout'
PARENT_VIEW = 'ParentView'
INNER_LINK = 'InnerLink'

View File

@@ -1,14 +1,30 @@
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.ext.asyncio import async_sessionmaker
from sqlalchemy.ext.asyncio import AsyncAttrs
from sqlalchemy.orm import DeclarativeBase
from urllib.parse import quote_plus
from config.env import DataBaseConfig
SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@" \
f"{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, echo=DataBaseConfig.db_echo
ASYNC_SQLALCHEMY_DATABASE_URL = (
f'mysql+asyncmy://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@'
f'{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}'
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
if DataBaseConfig.db_type == 'postgresql':
ASYNC_SQLALCHEMY_DATABASE_URL = (
f'postgresql+asyncpg://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@'
f'{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}'
)
async_engine = create_async_engine(
ASYNC_SQLALCHEMY_DATABASE_URL,
echo=DataBaseConfig.db_echo,
max_overflow=DataBaseConfig.db_max_overflow,
pool_size=DataBaseConfig.db_pool_size,
pool_recycle=DataBaseConfig.db_pool_recycle,
pool_timeout=DataBaseConfig.db_pool_timeout,
)
AsyncSessionLocal = async_sessionmaker(autocommit=False, autoflush=False, bind=async_engine)
class Base(AsyncAttrs, DeclarativeBase):
pass

View File

@@ -0,0 +1,51 @@
from enum import Enum
class BusinessType(Enum):
"""
业务操作类型
OTHER: 其它
INSERT: 新增
UPDATE: 修改
DELETE: 删除
GRANT: 授权
EXPORT: 导出
IMPORT: 导入
FORCE: 强退
GENCODE: 生成代码
CLEAN: 清空数据
"""
OTHER = 0
INSERT = 1
UPDATE = 2
DELETE = 3
GRANT = 4
EXPORT = 5
IMPORT = 6
FORCE = 7
GENCODE = 8
CLEAN = 9
class RedisInitKeyConfig(Enum):
"""
系统内置Redis键名
"""
@property
def key(self):
return self.value.get('key')
@property
def remark(self):
return self.value.get('remark')
ACCESS_TOKEN = {'key': 'access_token', 'remark': '登录令牌信息'}
SYS_DICT = {'key': 'sys_dict', 'remark': '数据字典'}
SYS_CONFIG = {'key': 'sys_config', 'remark': '配置信息'}
CAPTCHA_CODES = {'key': 'captcha_codes', 'remark': '图片验证码'}
ACCOUNT_LOCK = {'key': 'account_lock', 'remark': '用户锁定'}
PASSWORD_ERROR_COUNT = {'key': 'password_error_count', 'remark': '密码错误次数'}
SMS_CODE = {'key': 'sms_code', 'remark': '短信验证码'}

View File

@@ -1,15 +1,17 @@
import argparse
import os
import sys
import argparse
from pydantic_settings import BaseSettings
from functools import lru_cache
from dotenv import load_dotenv
from functools import lru_cache
from pydantic_settings import BaseSettings
from typing import Literal
class AppSettings(BaseSettings):
"""
应用配置
"""
app_env: str = 'dev'
app_name: str = 'RuoYi-FasAPI'
app_root_path: str = '/dev-api'
@@ -25,6 +27,7 @@ class JwtSettings(BaseSettings):
"""
Jwt配置
"""
jwt_secret_key: str = 'b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55'
jwt_algorithm: str = 'HS256'
jwt_expire_minutes: int = 1440
@@ -35,18 +38,25 @@ class DataBaseSettings(BaseSettings):
"""
数据库配置
"""
db_type: Literal['mysql', 'postgresql'] = 'mysql'
db_host: str = '127.0.0.1'
db_port: int = 3306
db_username: str = 'root'
db_password: str = 'mysqlroot'
db_database: str = 'ruoyi-fastapi'
db_echo: bool = True
db_max_overflow: int = 10
db_pool_size: int = 50
db_pool_recycle: int = 3600
db_pool_timeout: int = 30
class RedisSettings(BaseSettings):
"""
Redis配置
"""
redis_host: str = '127.0.0.1'
redis_port: int = 6379
redis_username: str = ''
@@ -58,20 +68,38 @@ class UploadSettings:
"""
上传配置
"""
UPLOAD_PREFIX = '/profile'
UPLOAD_PATH = 'vf_admin/upload_path'
UPLOAD_MACHINE = 'A'
DEFAULT_ALLOWED_EXTENSION = [
# 图片
"bmp", "gif", "jpg", "jpeg", "png",
'bmp',
'gif',
'jpg',
'jpeg',
'png',
# word excel powerpoint
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
'doc',
'docx',
'xls',
'xlsx',
'ppt',
'pptx',
'html',
'htm',
'txt',
# 压缩文件
"rar", "zip", "gz", "bz2",
'rar',
'zip',
'gz',
'bz2',
# 视频格式
"mp4", "avi", "rmvb",
'mp4',
'avi',
'rmvb',
# pdf
"pdf"
'pdf',
]
DOWNLOAD_PATH = 'vf_admin/download_path'
@@ -86,23 +114,11 @@ class CachePathConfig:
"""
缓存目录配置
"""
PATH = os.path.join(os.path.abspath(os.getcwd()), 'caches')
PATHSTR = 'caches'
class RedisInitKeyConfig:
"""
系统内置Redis键名
"""
ACCESS_TOKEN = {'key': 'access_token', 'remark': '登录令牌信息'}
SYS_DICT = {'key': 'sys_dict', 'remark': '数据字典'}
SYS_CONFIG = {'key': 'sys_config', 'remark': '配置信息'}
CAPTCHA_CODES = {'key': 'captcha_codes', 'remark': '图片验证码'}
ACCOUNT_LOCK = {'key': 'account_lock', 'remark': '用户锁定'}
PASSWORD_ERROR_COUNT = {'key': 'password_error_count', 'remark': '密码错误次数'}
SMS_CODE = {'key': 'sms_code', 'remark': '短信验证码'}
class GetConfig:
"""
获取配置

View File

@@ -1,27 +1,24 @@
from config.database import *
from config.database import async_engine, AsyncSessionLocal, Base
from utils.log_util import logger
def get_db_pro():
async def get_db():
"""
每一个请求处理完毕后会关闭当前连接,不同的请求使用不同的连接
:return:
"""
current_db = SessionLocal()
try:
async with AsyncSessionLocal() as current_db:
yield current_db
finally:
current_db.close()
async def init_create_table():
"""
应用启动时初始化数据库连接
:return:
"""
logger.info("初始化数据库连接...")
Base.metadata.create_all(bind=engine)
logger.info("数据库连接成功")
get_db = get_db_pro
logger.info('初始化数据库连接...')
async with async_engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
logger.info('数据库连接成功')

View File

@@ -1,9 +1,9 @@
from redis import asyncio as aioredis
from redis.exceptions import AuthenticationError, TimeoutError, RedisError
from module_admin.service.dict_service import DictDataService
from module_admin.service.config_service import ConfigService
from config.database import AsyncSessionLocal
from config.env import RedisConfig
from config.database import SessionLocal
from module_admin.service.config_service import ConfigService
from module_admin.service.dict_service import DictDataService
from utils.log_util import logger
@@ -16,62 +16,62 @@ class RedisUtil:
async def create_redis_pool(cls) -> aioredis.Redis:
"""
应用启动时初始化redis连接
:return: Redis连接对象
"""
logger.info("开始连接redis...")
logger.info('开始连接redis...')
redis = await aioredis.from_url(
url=f"redis://{RedisConfig.redis_host}",
url=f'redis://{RedisConfig.redis_host}',
port=RedisConfig.redis_port,
username=RedisConfig.redis_username,
password=RedisConfig.redis_password,
db=RedisConfig.redis_database,
encoding="utf-8",
decode_responses=True
encoding='utf-8',
decode_responses=True,
)
try:
connection = await redis.ping()
if connection:
logger.info("redis连接成功")
logger.info('redis连接成功')
else:
logger.error("redis连接失败")
logger.error('redis连接失败')
except AuthenticationError as e:
logger.error(f"redis用户名或密码错误详细错误信息{e}")
logger.error(f'redis用户名或密码错误详细错误信息{e}')
except TimeoutError as e:
logger.error(f"redis连接超时详细错误信息{e}")
logger.error(f'redis连接超时详细错误信息{e}')
except RedisError as e:
logger.error(f"redis连接错误详细错误信息{e}")
logger.error(f'redis连接错误详细错误信息{e}')
return redis
@classmethod
async def close_redis_pool(cls, app):
"""
应用关闭时关闭redis连接
:param app: fastapi对象
:return:
"""
await app.state.redis.close()
logger.info("关闭redis连接成功")
logger.info('关闭redis连接成功')
@classmethod
async def init_sys_dict(cls, redis):
"""
应用启动时缓存字典表
:param redis: redis对象
:return:
"""
session = SessionLocal()
await DictDataService.init_cache_sys_dict_services(session, redis)
session.close()
async with AsyncSessionLocal() as session:
await DictDataService.init_cache_sys_dict_services(session, redis)
@classmethod
async def init_sys_config(cls, redis):
"""
应用启动时缓存参数配置表
:param redis: redis对象
:return:
"""
session = SessionLocal()
await ConfigService.init_cache_sys_config_services(session, redis)
session.close()
async with AsyncSessionLocal() as session:
await ConfigService.init_cache_sys_config_services(session, redis)

View File

@@ -1,24 +1,30 @@
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
import json
from apscheduler.events import EVENT_ALL
from apscheduler.executors.asyncio import AsyncIOExecutor
from apscheduler.executors.pool import ProcessPoolExecutor
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.jobstores.redis import RedisJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
from apscheduler.events import EVENT_ALL
import json
from asyncio import iscoroutinefunction
from datetime import datetime, timedelta
from config.database import engine, SQLALCHEMY_DATABASE_URL, SessionLocal
from config.env import RedisConfig
from module_admin.service.job_log_service import JobLogService, JobLogModel
from module_admin.dao.job_dao import Session, JobDao
from sqlalchemy.engine import create_engine
from sqlalchemy.orm import sessionmaker
from typing import Union
from config.database import AsyncSessionLocal, quote_plus
from config.env import DataBaseConfig, RedisConfig
from module_admin.dao.job_dao import JobDao
from module_admin.entity.vo.job_vo import JobLogModel, JobModel
from module_admin.service.job_log_service import JobLogService
from utils.log_util import logger
import module_task
import module_task # noqa: F401
# 重写Cron定时
class MyCronTrigger(CronTrigger):
@classmethod
def from_crontab(cls, expr, timezone=None):
def from_crontab(cls, expr: str, timezone=None):
values = expr.split()
if len(values) != 6 and len(values) != 7:
raise ValueError('Wrong number of fields; got {}, expected 6 or 7'.format(len(values)))
@@ -46,11 +52,20 @@ class MyCronTrigger(CronTrigger):
else:
day_of_week = None
year = values[6] if len(values) == 7 else None
return cls(second=second, minute=minute, hour=hour, day=day, month=month, week=week,
day_of_week=day_of_week, year=year, timezone=timezone)
return cls(
second=second,
minute=minute,
hour=hour,
day=day,
month=month,
week=week,
day_of_week=day_of_week,
year=year,
timezone=timezone,
)
@classmethod
def __find_recent_workday(cls, day):
def __find_recent_workday(cls, day: int):
now = datetime.now()
date = datetime(now.year, now.month, day)
if date.weekday() < 5:
@@ -65,6 +80,24 @@ class MyCronTrigger(CronTrigger):
diff += 1
SQLALCHEMY_DATABASE_URL = (
f'mysql+pymysql://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@'
f'{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}'
)
if DataBaseConfig.db_type == 'postgresql':
SQLALCHEMY_DATABASE_URL = (
f'postgresql+psycopg2://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@'
f'{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}'
)
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
echo=DataBaseConfig.db_echo,
max_overflow=DataBaseConfig.db_max_overflow,
pool_size=DataBaseConfig.db_pool_size,
pool_recycle=DataBaseConfig.db_pool_recycle,
pool_timeout=DataBaseConfig.db_pool_timeout,
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
job_stores = {
'default': MemoryJobStore(),
'sqlalchemy': SQLAlchemyJobStore(url=SQLALCHEMY_DATABASE_URL, engine=engine),
@@ -74,19 +107,13 @@ job_stores = {
port=RedisConfig.redis_port,
username=RedisConfig.redis_username,
password=RedisConfig.redis_password,
db=RedisConfig.redis_database
db=RedisConfig.redis_database,
)
)
),
}
executors = {
'default': ThreadPoolExecutor(20),
'processpool': ProcessPoolExecutor(5)
}
job_defaults = {
'coalesce': False,
'max_instance': 1
}
scheduler = BackgroundScheduler()
executors = {'default': AsyncIOExecutor(), 'processpool': ProcessPoolExecutor(5)}
job_defaults = {'coalesce': False, 'max_instance': 1}
scheduler = AsyncIOScheduler()
scheduler.configure(jobstores=job_stores, executors=executors, job_defaults=job_defaults)
@@ -96,36 +123,37 @@ class SchedulerUtil:
"""
@classmethod
async def init_system_scheduler(cls, query_db: Session = SessionLocal()):
async def init_system_scheduler(cls):
"""
应用启动时初始化定时任务
:return:
"""
logger.info("开始启动定时任务...")
logger.info('开始启动定时任务...')
scheduler.start()
job_list = JobDao.get_job_list_for_scheduler(query_db)
for item in job_list:
query_job = cls.get_scheduler_job(job_id=str(item.job_id))
if query_job:
async with AsyncSessionLocal() as session:
job_list = await JobDao.get_job_list_for_scheduler(session)
for item in job_list:
cls.remove_scheduler_job(job_id=str(item.job_id))
cls.add_scheduler_job(item)
query_db.close()
cls.add_scheduler_job(item)
scheduler.add_listener(cls.scheduler_event_listener, EVENT_ALL)
logger.info("系统初始定时任务加载成功")
logger.info('系统初始定时任务加载成功')
@classmethod
async def close_system_scheduler(cls):
"""
应用关闭时关闭定时任务
:return:
"""
scheduler.shutdown()
logger.info("关闭定时任务成功")
logger.info('关闭定时任务成功')
@classmethod
def get_scheduler_job(cls, job_id):
def get_scheduler_job(cls, job_id: Union[str, int]):
"""
根据任务id获取任务对象
:param job_id: 任务id
:return: 任务对象
"""
@@ -134,12 +162,17 @@ class SchedulerUtil:
return query_job
@classmethod
def add_scheduler_job(cls, job_info):
def add_scheduler_job(cls, job_info: JobModel):
"""
根据输入的任务对象信息添加任务
:param job_info: 任务对象信息
:return:
"""
job_func = eval(job_info.invoke_target)
job_executor = job_info.job_executor
if iscoroutinefunction(job_func):
job_executor = 'default'
scheduler.add_job(
func=eval(job_info.invoke_target),
trigger=MyCronTrigger.from_crontab(job_info.cron_expression),
@@ -151,16 +184,21 @@ class SchedulerUtil:
coalesce=True if job_info.misfire_policy == '2' else False,
max_instances=3 if job_info.concurrent == '0' else 1,
jobstore=job_info.job_group,
executor=job_info.job_executor
executor=job_executor,
)
@classmethod
def execute_scheduler_job_once(cls, job_info):
def execute_scheduler_job_once(cls, job_info: JobModel):
"""
根据输入的任务对象执行一次任务
:param job_info: 任务对象信息
:return:
"""
job_func = eval(job_info.invoke_target)
job_executor = job_info.job_executor
if iscoroutinefunction(job_func):
job_executor = 'default'
scheduler.add_job(
func=eval(job_info.invoke_target),
trigger='date',
@@ -173,17 +211,20 @@ class SchedulerUtil:
coalesce=True if job_info.misfire_policy == '2' else False,
max_instances=3 if job_info.concurrent == '0' else 1,
jobstore=job_info.job_group,
executor=job_info.job_executor
executor=job_executor,
)
@classmethod
def remove_scheduler_job(cls, job_id):
def remove_scheduler_job(cls, job_id: Union[str, int]):
"""
根据任务id移除任务
:param job_id: 任务id
:return:
"""
scheduler.remove_job(job_id=str(job_id))
query_job = cls.get_scheduler_job(job_id=job_id)
if query_job:
scheduler.remove_job(job_id=str(job_id))
@classmethod
def scheduler_event_listener(cls, event):
@@ -195,38 +236,40 @@ class SchedulerUtil:
if event_type == 'JobExecutionEvent' and event.exception:
exception_info = str(event.exception)
status = '1'
job_id = event.job_id
query_job = cls.get_scheduler_job(job_id=job_id)
if query_job:
query_job_info = query_job.__getstate__()
# 获取任务名称
job_name = query_job_info.get('name')
# 获取任务组名
job_group = query_job._jobstore_alias
# 获取任务执行器
job_executor = query_job_info.get('executor')
# 获取调用目标字符串
invoke_target = query_job_info.get('func')
# 获取调用函数位置参数
job_args = ','.join(query_job_info.get('args'))
# 获取调用函数关键字参数
job_kwargs = json.dumps(query_job_info.get('kwargs'))
# 获取任务触发器
job_trigger = str(query_job_info.get('trigger'))
# 构造日志消息
job_message = f"事件类型: {event_type}, 任务ID: {job_id}, 任务名称: {job_name}, 执行于{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
job_log = JobLogModel(
jobName=job_name,
jobGroup=job_group,
jobExecutor=job_executor,
invokeTarget=invoke_target,
jobArgs=job_args,
jobKwargs=job_kwargs,
jobTrigger=job_trigger,
jobMessage=job_message,
status=status,
exceptionInfo=exception_info
)
session = SessionLocal()
JobLogService.add_job_log_services(session, job_log)
session.close()
if hasattr(event, 'job_id'):
job_id = event.job_id
query_job = cls.get_scheduler_job(job_id=job_id)
if query_job:
query_job_info = query_job.__getstate__()
# 获取任务名称
job_name = query_job_info.get('name')
# 获取任务组名
job_group = query_job._jobstore_alias
# 获取任务执行器
job_executor = query_job_info.get('executor')
# 获取调用目标字符串
invoke_target = query_job_info.get('func')
# 获取调用函数位置参数
job_args = ','.join(query_job_info.get('args'))
# 获取调用函数关键字参数
job_kwargs = json.dumps(query_job_info.get('kwargs'))
# 获取任务触发器
job_trigger = str(query_job_info.get('trigger'))
# 构造日志消息
job_message = f"事件类型: {event_type}, 任务ID: {job_id}, 任务名称: {job_name}, 执行于{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
job_log = JobLogModel(
jobName=job_name,
jobGroup=job_group,
jobExecutor=job_executor,
invokeTarget=invoke_target,
jobArgs=job_args,
jobKwargs=job_kwargs,
jobTrigger=job_trigger,
jobMessage=job_message,
status=status,
exceptionInfo=exception_info,
createTime=datetime.now(),
)
session = SessionLocal()
JobLogService.add_job_log_services(session, job_log)
session.close()

View File

@@ -26,3 +26,33 @@ class PermissionException(Exception):
def __init__(self, data: str = None, message: str = None):
self.data = data
self.message = message
class ServiceException(Exception):
"""
自定义服务异常ServiceException
"""
def __init__(self, data: str = None, message: str = None):
self.data = data
self.message = message
class ServiceWarning(Exception):
"""
自定义服务警告ServiceWarning
"""
def __init__(self, data: str = None, message: str = None):
self.data = data
self.message = message
class ModelValidatorException(Exception):
"""
自定义模型校验异常ModelValidatorException
"""
def __init__(self, data: str = None, message: str = None):
self.data = data
self.message = message

View File

@@ -1,27 +1,71 @@
from fastapi import FastAPI, Request
from fastapi.exceptions import HTTPException
from exceptions.exception import AuthException, PermissionException
from utils.response_util import ResponseUtil, JSONResponse, jsonable_encoder
from pydantic_validation_decorator import FieldValidationError
from exceptions.exception import (
AuthException,
LoginException,
ModelValidatorException,
PermissionException,
ServiceException,
ServiceWarning,
)
from utils.log_util import logger
from utils.response_util import jsonable_encoder, JSONResponse, ResponseUtil
def handle_exception(app: FastAPI):
"""
全局异常处理
"""
# 自定义token检验异常
@app.exception_handler(AuthException)
async def auth_exception_handler(request: Request, exc: AuthException):
return ResponseUtil.unauthorized(data=exc.data, msg=exc.message)
# 自定义登录检验异常
@app.exception_handler(LoginException)
async def login_exception_handler(request: Request, exc: LoginException):
return ResponseUtil.failure(data=exc.data, msg=exc.message)
# 自定义模型检验异常
@app.exception_handler(ModelValidatorException)
async def model_validator_exception_handler(request: Request, exc: ModelValidatorException):
logger.warning(exc.message)
return ResponseUtil.failure(data=exc.data, msg=exc.message)
# 自定义字段检验异常
@app.exception_handler(FieldValidationError)
async def field_validation_error_handler(request: Request, exc: FieldValidationError):
logger.warning(exc.message)
return ResponseUtil.failure(msg=exc.message)
# 自定义权限检验异常
@app.exception_handler(PermissionException)
async def permission_exception_handler(request: Request, exc: PermissionException):
return ResponseUtil.forbidden(data=exc.data, msg=exc.message)
# 自定义服务异常
@app.exception_handler(ServiceException)
async def service_exception_handler(request: Request, exc: ServiceException):
logger.error(exc.message)
return ResponseUtil.error(data=exc.data, msg=exc.message)
# 自定义服务警告
@app.exception_handler(ServiceWarning)
async def service_warning_handler(request: Request, exc: ServiceWarning):
logger.warning(exc.message)
return ResponseUtil.failure(data=exc.data, msg=exc.message)
# 处理其他http请求异常
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
return JSONResponse(
content=jsonable_encoder({"code": exc.status_code, "msg": exc.detail}),
status_code=exc.status_code
content=jsonable_encoder({'code': exc.status_code, 'msg': exc.detail}), status_code=exc.status_code
)
# 处理其他异常
@app.exception_handler(Exception)
async def exception_handler(request: Request, exc: Exception):
logger.exception(exc)
return ResponseUtil.error(msg=str(exc))

View File

@@ -3,10 +3,16 @@ from fastapi.middleware.cors import CORSMiddleware
def add_cors_middleware(app: FastAPI):
"""
添加跨域中间件
:param app: FastAPI对象
:return:
"""
# 前端页面url
origins = [
"http://localhost:80",
"http://127.0.0.1:80",
'http://localhost:80',
'http://127.0.0.1:80',
]
# 后台api允许跨域
@@ -14,6 +20,6 @@ def add_cors_middleware(app: FastAPI):
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
allow_methods=['*'],
allow_headers=['*'],
)

View File

@@ -0,0 +1,12 @@
from fastapi import FastAPI
from starlette.middleware.gzip import GZipMiddleware
def add_gzip_middleware(app: FastAPI):
"""
添加gzip压缩中间件
:param app: FastAPI对象
:return:
"""
app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=9)

View File

@@ -1,5 +1,6 @@
from fastapi import FastAPI
from middlewares.cors_middleware import add_cors_middleware
from middlewares.gzip_middleware import add_gzip_middleware
def handle_middleware(app: FastAPI):
@@ -8,3 +9,5 @@ def handle_middleware(app: FastAPI):
"""
# 加载跨域中间件
add_cors_middleware(app)
# 加载gzip压缩中间件
add_gzip_middleware(app)

View File

@@ -1,29 +1,48 @@
from functools import wraps
from fastapi import Request
from fastapi.responses import JSONResponse, ORJSONResponse, UJSONResponse
import inspect
import os
import json
import os
import requests
import time
from datetime import datetime
import requests
from fastapi import Request
from fastapi.responses import JSONResponse, ORJSONResponse, UJSONResponse
from functools import lru_cache, wraps
from typing import Literal, Optional
from user_agents import parse
from typing import Optional
from module_admin.service.login_service import LoginService
from module_admin.service.log_service import OperationLogService, LoginLogService
from module_admin.entity.vo.log_vo import OperLogModel, LogininforModel
from config.enums import BusinessType
from config.env import AppConfig
from exceptions.exception import LoginException, ServiceException, ServiceWarning
from module_admin.entity.vo.log_vo import LogininforModel, OperLogModel
from module_admin.service.log_service import LoginLogService, OperationLogService
from module_admin.service.login_service import LoginService
from utils.log_util import logger
from utils.response_util import ResponseUtil
def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'operation'):
class Log:
"""
日志装饰器
:param log_type: 日志类型login表示登录日志为空表示为操作日志
:param title: 当前日志装饰器装饰的模块标题
:param business_type: 业务类型0其它 1新增 2修改 3删除 4授权 5导出 6导入 7强退 8生成代码 9清空数据
:return:
"""
def decorator(func):
def __init__(
self,
title: str,
business_type: BusinessType,
log_type: Optional[Literal['login', 'operation']] = 'operation',
):
"""
日志装饰器
:param title: 当前日志装饰器装饰的模块标题
:param business_type: 业务类型OTHER其它 INSERT新增 UPDATE修改 DELETE删除 GRANT授权 EXPORT导出 IMPORT导入 FORCE强退 GENCODE生成代码 CLEAN清空数据
:param log_type: 日志类型login表示登录日志operation表示为操作日志
:return:
"""
self.title = title
self.business_type = business_type.value
self.log_type = log_type
def __call__(self, func):
@wraps(func)
async def wrapper(*args, **kwargs):
start_time = time.time()
@@ -42,36 +61,24 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope
request_method = request.method
operator_type = 0
user_agent = request.headers.get('User-Agent')
if "Windows" in user_agent or "Macintosh" in user_agent or "Linux" in user_agent:
if 'Windows' in user_agent or 'Macintosh' in user_agent or 'Linux' in user_agent:
operator_type = 1
if "Mobile" in user_agent or "Android" in user_agent or "iPhone" in user_agent:
if 'Mobile' in user_agent or 'Android' in user_agent or 'iPhone' in user_agent:
operator_type = 2
# 获取请求的url
oper_url = request.url.path
# 获取请求的ip及ip归属区域
oper_ip = request.headers.get("X-Forwarded-For")
oper_ip = request.headers.get('X-Forwarded-For')
oper_location = '内网IP'
if AppConfig.app_ip_location_query:
try:
if oper_ip != '127.0.0.1' and oper_ip != 'localhost':
ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}')
if ip_result.status_code == 200:
prov = ip_result.json().get('data').get('prov')
city = ip_result.json().get('data').get('city')
if prov or city:
oper_location = f'{prov}-{city}'
else:
oper_location = '未知'
else:
oper_location = '未知'
except Exception as e:
oper_location = '未知'
print(e)
oper_location = get_ip_location(oper_ip)
# 根据不同的请求类型使用不同的方法获取请求参数
content_type = request.headers.get("Content-Type")
if content_type and ("multipart/form-data" in content_type or 'application/x-www-form-urlencoded' in content_type):
content_type = request.headers.get('Content-Type')
if content_type and (
'multipart/form-data' in content_type or 'application/x-www-form-urlencoded' in content_type
):
payload = await request.form()
oper_param = "\n".join([f"{key}: {value}" for key, value in payload.items()])
oper_param = '\n'.join([f'{key}: {value}' for key, value in payload.items()])
else:
payload = await request.body()
# 通过 request.path_params 直接访问路径参数
@@ -90,7 +97,7 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope
oper_time = datetime.now()
# 此处在登录之前向原始函数传递一些登录信息,用于监测在线用户的相关信息
login_log = {}
if log_type == 'login':
if self.log_type == 'login':
user_agent_info = parse(user_agent)
browser = f'{user_agent_info.browser.family}'
system_os = f'{user_agent_info.os.family}'
@@ -103,18 +110,36 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope
loginLocation=oper_location,
browser=browser,
os=system_os,
loginTime=oper_time.strftime('%Y-%m-%d %H:%M:%S')
loginTime=oper_time.strftime('%Y-%m-%d %H:%M:%S'),
)
kwargs['form_data'].login_info = login_log
# 调用原始函数
result = await func(*args, **kwargs)
try:
# 调用原始函数
result = await func(*args, **kwargs)
except (LoginException, ServiceWarning) as e:
logger.warning(e.message)
result = ResponseUtil.failure(data=e.data, msg=e.message)
except ServiceException as e:
logger.error(e.message)
result = ResponseUtil.error(data=e.data, msg=e.message)
except Exception as e:
logger.exception(e)
result = ResponseUtil.error(msg=str(e))
# 获取请求耗时
cost_time = float(time.time() - start_time) * 100
# 判断请求是否来自api文档
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
request_from_swagger = (
request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
)
request_from_redoc = (
request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
)
# 根据响应结果的类型使用不同的方法获取响应结果参数
if isinstance(result, JSONResponse) or isinstance(result, ORJSONResponse) or isinstance(result, UJSONResponse):
if (
isinstance(result, JSONResponse)
or isinstance(result, ORJSONResponse)
or isinstance(result, UJSONResponse)
):
result_dict = json.loads(str(result.body, 'utf-8'))
else:
if request_from_swagger or request_from_redoc:
@@ -133,7 +158,7 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope
else:
error_msg = result_dict.get('msg')
# 根据日志类型向对应的日志表插入数据
if log_type == 'login':
if self.log_type == 'login':
# 登录请求来自于api文档时不记录登录日志其余情况则记录
if request_from_swagger or request_from_redoc:
pass
@@ -145,14 +170,14 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope
login_log['status'] = str(status)
login_log['msg'] = result_dict.get('msg')
LoginLogService.add_login_log_services(query_db, LogininforModel(**login_log))
await LoginLogService.add_login_log_services(query_db, LogininforModel(**login_log))
else:
current_user = await LoginService.get_current_user(request, token, query_db)
oper_name = current_user.user.user_name
dept_name = current_user.user.dept.dept_name if current_user.user.dept else None
operation_log = OperLogModel(
title=title,
businessType=business_type,
title=self.title,
businessType=self.business_type,
method=func_path,
requestMethod=request_method,
operatorType=operator_type,
@@ -166,12 +191,34 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope
status=status,
errorMsg=error_msg,
operTime=oper_time,
costTime=int(cost_time)
costTime=int(cost_time),
)
OperationLogService.add_operation_log_services(query_db, operation_log)
await OperationLogService.add_operation_log_services(query_db, operation_log)
return result
return wrapper
return decorator
@lru_cache()
def get_ip_location(oper_ip: str):
"""
查询ip归属区域
:param oper_ip: 需要查询的ip
:return: ip归属区域
"""
oper_location = '内网IP'
try:
if oper_ip != '127.0.0.1' and oper_ip != 'localhost':
oper_location = '未知'
ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}')
if ip_result.status_code == 200:
prov = ip_result.json().get('data').get('prov')
city = ip_result.json().get('data').get('city')
if prov or city:
oper_location = f'{prov}-{city}'
except Exception as e:
oper_location = '未知'
print(e)
return oper_location

View File

@@ -1,9 +1,8 @@
import inspect
from typing import Type
from fastapi import Query, Form
from fastapi import Form, Query
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from typing import Type
def as_query(cls: Type[BaseModel]):
@@ -20,8 +19,8 @@ def as_query(cls: Type[BaseModel]):
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Query(model_field.default),
annotation=model_field.annotation
default=Query(default=model_field.default, description=model_field.description),
annotation=model_field.annotation,
)
)
else:
@@ -29,8 +28,8 @@ def as_query(cls: Type[BaseModel]):
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Query(...),
annotation=model_field.annotation
default=Query(..., description=model_field.description),
annotation=model_field.annotation,
)
)
@@ -58,8 +57,8 @@ def as_form(cls: Type[BaseModel]):
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Form(model_field.default),
annotation=model_field.annotation
default=Form(default=model_field.default, description=model_field.description),
annotation=model_field.annotation,
)
)
else:
@@ -67,8 +66,8 @@ def as_form(cls: Type[BaseModel]):
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Form(...),
annotation=model_field.annotation
default=Form(..., description=model_field.description),
annotation=model_field.annotation,
)
)

View File

@@ -1,14 +1,35 @@
from fastapi import Depends
from typing import Optional
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from typing import Optional
class GetDataScope:
"""
获取当前用户数据权限对应的查询sql语句
"""
def __init__(self, query_alias: Optional[str] = '', db_alias: Optional[str] = 'db', user_alias: Optional[str] = 'user_id', dept_alias: Optional[str] = 'dept_id'):
DATA_SCOPE_ALL = '1'
DATA_SCOPE_CUSTOM = '2'
DATA_SCOPE_DEPT = '3'
DATA_SCOPE_DEPT_AND_CHILD = '4'
DATA_SCOPE_SELF = '5'
def __init__(
self,
query_alias: Optional[str] = '',
db_alias: Optional[str] = 'db',
user_alias: Optional[str] = 'user_id',
dept_alias: Optional[str] = 'dept_id',
):
"""
获取当前用户数据权限对应的查询sql语句
:param query_alias: 所要查询表对应的sqlalchemy模型名称默认为''
:param db_alias: orm对象别名默认为'db'
:param user_alias: 用户id字段别名默认为'user_id'
:param dept_alias: 部门id字段别名默认为'dept_id'
"""
self.query_alias = query_alias
self.db_alias = db_alias
self.user_alias = user_alias
@@ -17,21 +38,38 @@ class GetDataScope:
def __call__(self, current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
user_id = current_user.user.user_id
dept_id = current_user.user.dept_id
role_datascope_list = [dict(role_id=item.role_id, data_scope=int(item.data_scope)) for item in current_user.user.role]
max_data_scope_dict = min(role_datascope_list, key=lambda x: x['data_scope'])
max_role_id = max_data_scope_dict['role_id']
max_data_scope = max_data_scope_dict['data_scope']
if self.query_alias == '' or max_data_scope == 1 or user_id == 1:
param_sql = '1 == 1'
elif max_data_scope == 2:
param_sql = f"{self.query_alias}.{self.dept_alias}.in_({self.db_alias}.query(SysRoleDept.dept_id).filter(SysRoleDept.role_id == {max_role_id})) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1"
elif max_data_scope == 3:
param_sql = f"{self.query_alias}.{self.dept_alias} == {dept_id} if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1"
elif max_data_scope == 4:
param_sql = f"{self.query_alias}.{self.dept_alias}.in_({self.db_alias}.query(SysDept.dept_id).filter(or_(SysDept.dept_id == {dept_id}, func.find_in_set({dept_id}, SysDept.ancestors)))) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1"
elif max_data_scope == 5:
param_sql = f"{self.query_alias}.{self.user_alias} == {user_id} if hasattr({self.query_alias}, '{self.user_alias}') else 1 == 1"
else:
param_sql = '1 == 0'
custom_data_scope_role_id_list = [
item.role_id for item in current_user.user.role if item.data_scope == self.DATA_SCOPE_CUSTOM
]
param_sql_list = []
for role in current_user.user.role:
if current_user.user.admin or role.data_scope == self.DATA_SCOPE_ALL:
param_sql_list = ['1 == 1']
break
elif role.data_scope == self.DATA_SCOPE_CUSTOM:
if len(custom_data_scope_role_id_list) > 1:
param_sql_list.append(
f"{self.query_alias}.{self.dept_alias}.in_(select(SysRoleDept.dept_id).where(SysRoleDept.role_id.in_({custom_data_scope_role_id_list}))) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 0"
)
else:
param_sql_list.append(
f"{self.query_alias}.{self.dept_alias}.in_(select(SysRoleDept.dept_id).where(SysRoleDept.role_id == {role.role_id})) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 0"
)
elif role.data_scope == self.DATA_SCOPE_DEPT:
param_sql_list.append(
f"{self.query_alias}.{self.dept_alias} == {dept_id} if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 0"
)
elif role.data_scope == self.DATA_SCOPE_DEPT_AND_CHILD:
param_sql_list.append(
f"{self.query_alias}.{self.dept_alias}.in_(select(SysDept.dept_id).where(or_(SysDept.dept_id == {dept_id}, func.find_in_set({dept_id}, SysDept.ancestors)))) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 0"
)
elif role.data_scope == self.DATA_SCOPE_SELF:
param_sql_list.append(
f"{self.query_alias}.{self.user_alias} == {user_id} if hasattr({self.query_alias}, '{self.user_alias}') else 1 == 0"
)
else:
param_sql_list.append('1 == 0')
param_sql_list = list(dict.fromkeys(param_sql_list))
param_sql = f"or_({', '.join(param_sql_list)})"
return param_sql

View File

@@ -1,17 +1,22 @@
from fastapi import Depends
from typing import Union, List
from typing import List, Union
from exceptions.exception import PermissionException
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from exceptions.exception import PermissionException
class CheckUserInterfaceAuth:
"""
校验当前用户是否具有相应的接口权限
:param perm: 权限标识
:param is_strict: 当传入的权限标识是list类型时是否开启严格模式开启表示会校验列表中的每一个权限标识所有的校验结果都需要为True才会通过
"""
def __init__(self, perm: Union[str, List], is_strict: bool = False):
"""
校验当前用户是否具有相应的接口权限
:param perm: 权限标识
:param is_strict: 当传入的权限标识是list类型时是否开启严格模式开启表示会校验列表中的每一个权限标识所有的校验结果都需要为True才会通过
"""
self.perm = perm
self.is_strict = is_strict
@@ -29,16 +34,21 @@ class CheckUserInterfaceAuth:
else:
if any([perm_str in user_auth_list for perm_str in self.perm]):
return True
raise PermissionException(data="", message="该用户无此接口权限")
raise PermissionException(data='', message='该用户无此接口权限')
class CheckRoleInterfaceAuth:
"""
根据角色校验当前用户是否具有相应的接口权限
:param role_key: 角色标识
:param is_strict: 当传入的角色标识是list类型时是否开启严格模式开启表示会校验列表中的每一个角色标识所有的校验结果都需要为True才会通过
"""
def __init__(self, role_key: Union[str, List], is_strict: bool = False):
"""
根据角色校验当前用户是否具有相应的接口权限
:param role_key: 角色标识
:param is_strict: 当传入的角色标识是list类型时是否开启严格模式开启表示会校验列表中的每一个角色标识所有的校验结果都需要为True才会通过
"""
self.role_key = role_key
self.is_strict = is_strict
@@ -55,5 +65,4 @@ class CheckRoleInterfaceAuth:
else:
if any([role_key_str in user_role_key_list for role_key_str in self.role_key]):
return True
raise PermissionException(data="", message="该用户无此接口权限")
raise PermissionException(data='', message='该用户无此接口权限')

View File

@@ -1,94 +1,89 @@
from fastapi import APIRouter
from fastapi import Depends
from module_admin.service.login_service import LoginService
from module_admin.service.cache_service import *
from utils.response_util import *
from utils.log_util import *
from fastapi import APIRouter, Depends, Request
from typing import List
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.entity.vo.cache_vo import CacheInfoModel, CacheMonitorModel
from module_admin.service.cache_service import CacheService
from module_admin.service.login_service import LoginService
from utils.log_util import logger
from utils.response_util import ResponseUtil
cacheController = APIRouter(prefix='/monitor/cache', dependencies=[Depends(LoginService.get_current_user)])
@cacheController.get("", response_model=CacheMonitorModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
@cacheController.get(
'', response_model=CacheMonitorModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]
)
async def get_monitor_cache_info(request: Request):
try:
# 获取全量数据
cache_info_query_result = await CacheService.get_cache_monitor_statistical_info_services(request)
logger.info('获取成功')
return ResponseUtil.success(data=cache_info_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
# 获取全量数据
cache_info_query_result = await CacheService.get_cache_monitor_statistical_info_services(request)
logger.info('获取成功')
return ResponseUtil.success(data=cache_info_query_result)
@cacheController.get("/getNames", response_model=List[CacheInfoModel], dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
@cacheController.get(
'/getNames',
response_model=List[CacheInfoModel],
dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))],
)
async def get_monitor_cache_name(request: Request):
try:
# 获取全量数据
cache_name_list_result = CacheService.get_cache_monitor_cache_name_services()
logger.info('获取成功')
return ResponseUtil.success(data=cache_name_list_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
# 获取全量数据
cache_name_list_result = await CacheService.get_cache_monitor_cache_name_services()
logger.info('获取成功')
return ResponseUtil.success(data=cache_name_list_result)
@cacheController.get("/getKeys/{cache_name}", response_model=List[str], dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
@cacheController.get(
'/getKeys/{cache_name}',
response_model=List[str],
dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))],
)
async def get_monitor_cache_key(request: Request, cache_name: str):
try:
# 获取全量数据
cache_key_list_result = await CacheService.get_cache_monitor_cache_key_services(request, cache_name)
logger.info('获取成功')
return ResponseUtil.success(data=cache_key_list_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
# 获取全量数据
cache_key_list_result = await CacheService.get_cache_monitor_cache_key_services(request, cache_name)
logger.info('获取成功')
return ResponseUtil.success(data=cache_key_list_result)
@cacheController.get("/getValue/{cache_name}/{cache_key}", response_model=CacheInfoModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
@cacheController.get(
'/getValue/{cache_name}/{cache_key}',
response_model=CacheInfoModel,
dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))],
)
async def get_monitor_cache_value(request: Request, cache_name: str, cache_key: str):
try:
# 获取全量数据
cache_value_list_result = await CacheService.get_cache_monitor_cache_value_services(request, cache_name, cache_key)
logger.info('获取成功')
return ResponseUtil.success(data=cache_value_list_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
# 获取全量数据
cache_value_list_result = await CacheService.get_cache_monitor_cache_value_services(request, cache_name, cache_key)
logger.info('获取成功')
return ResponseUtil.success(data=cache_value_list_result)
@cacheController.delete("/clearCacheName/{cache_name}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
@cacheController.delete(
'/clearCacheName/{cache_name}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]
)
async def clear_monitor_cache_name(request: Request, cache_name: str):
try:
clear_cache_name_result = await CacheService.clear_cache_monitor_cache_name_services(request, cache_name)
if clear_cache_name_result.is_success:
logger.info(clear_cache_name_result.message)
return ResponseUtil.success(msg=clear_cache_name_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
clear_cache_name_result = await CacheService.clear_cache_monitor_cache_name_services(request, cache_name)
logger.info(clear_cache_name_result.message)
return ResponseUtil.success(msg=clear_cache_name_result.message)
@cacheController.delete("/clearCacheKey/{cache_key}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
@cacheController.delete(
'/clearCacheKey/{cache_key}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]
)
async def clear_monitor_cache_key(request: Request, cache_key: str):
try:
clear_cache_key_result = await CacheService.clear_cache_monitor_cache_key_services(request, cache_key)
if clear_cache_key_result.is_success:
logger.info(clear_cache_key_result.message)
return ResponseUtil.success(msg=clear_cache_key_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
clear_cache_key_result = await CacheService.clear_cache_monitor_cache_key_services(request, cache_key)
logger.info(clear_cache_key_result.message)
return ResponseUtil.success(msg=clear_cache_key_result.message)
@cacheController.delete("/clearCacheAll", dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
@cacheController.delete('/clearCacheAll', dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))])
async def clear_monitor_cache_all(request: Request):
try:
clear_cache_all_result = await CacheService.clear_cache_monitor_all_services(request)
if clear_cache_all_result.is_success:
logger.info(clear_cache_all_result.message)
return ResponseUtil.success(msg=clear_cache_all_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
clear_cache_all_result = await CacheService.clear_cache_monitor_all_services(request)
logger.info(clear_cache_all_result.message)
return ResponseUtil.success(msg=clear_cache_all_result.message)

View File

@@ -1,31 +1,40 @@
import uuid
from fastapi import APIRouter, Request
from config.env import RedisInitKeyConfig
from module_admin.service.captcha_service import *
from module_admin.entity.vo.login_vo import CaptchaCode
from utils.response_util import *
from utils.log_util import *
from datetime import timedelta
from fastapi import APIRouter, Request
from config.enums import RedisInitKeyConfig
from module_admin.entity.vo.login_vo import CaptchaCode
from module_admin.service.captcha_service import CaptchaService
from utils.response_util import ResponseUtil
from utils.log_util import logger
captchaController = APIRouter()
@captchaController.get("/captchaImage")
@captchaController.get('/captchaImage')
async def get_captcha_image(request: Request):
try:
captcha_enabled = True if await request.app.state.redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.captchaEnabled") == 'true' else False
register_enabled = True if await request.app.state.redis.get(
f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.registerUser") == 'true' else False
session_id = str(uuid.uuid4())
captcha_result = CaptchaService.create_captcha_image_service()
image = captcha_result[0]
computed_result = captcha_result[1]
await request.app.state.redis.set(f"{RedisInitKeyConfig.CAPTCHA_CODES.get('key')}:{session_id}", computed_result, ex=timedelta(minutes=2))
logger.info(f'编号为{session_id}的会话获取图片验证码成功')
return ResponseUtil.success(
model_content=CaptchaCode(captchaEnabled=captcha_enabled, registerEnabled=register_enabled, img=image, uuid=session_id)
captcha_enabled = (
True
if await request.app.state.redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:sys.account.captchaEnabled')
== 'true'
else False
)
register_enabled = (
True
if await request.app.state.redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:sys.account.registerUser') == 'true'
else False
)
session_id = str(uuid.uuid4())
captcha_result = await CaptchaService.create_captcha_image_service()
image = captcha_result[0]
computed_result = captcha_result[1]
await request.app.state.redis.set(
f'{RedisInitKeyConfig.CAPTCHA_CODES.key}:{session_id}', computed_result, ex=timedelta(minutes=2)
)
logger.info(f'编号为{session_id}的会话获取图片验证码成功')
return ResponseUtil.success(
model_content=CaptchaCode(
captchaEnabled=captcha_enabled, registerEnabled=register_enabled, img=image, uuid=session_id
)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
)

View File

@@ -1,53 +1,36 @@
from fastapi import APIRouter
from fastapi import Depends, File, Query
from fastapi import APIRouter, BackgroundTasks, Depends, File, Query, Request, UploadFile
from module_admin.service.common_service import CommonService
from module_admin.service.login_service import LoginService
from module_admin.service.common_service import *
from utils.response_util import *
from utils.log_util import *
from utils.log_util import logger
from utils.response_util import ResponseUtil
commonController = APIRouter(prefix='/common', dependencies=[Depends(LoginService.get_current_user)])
@commonController.post("/upload")
@commonController.post('/upload')
async def common_upload(request: Request, file: UploadFile = File(...)):
try:
upload_result = CommonService.upload_service(request, file)
if upload_result.is_success:
logger.info('上传成功')
return ResponseUtil.success(model_content=upload_result.result)
else:
logger.warning('上传失败')
return ResponseUtil.failure(msg=upload_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
upload_result = await CommonService.upload_service(request, file)
logger.info('上传成功')
return ResponseUtil.success(model_content=upload_result.result)
@commonController.get("/download")
async def common_download(request: Request, background_tasks: BackgroundTasks, file_name: str = Query(alias='fileName'), delete: bool = Query()):
try:
download_result = CommonService.download_services(background_tasks, file_name, delete)
if download_result.is_success:
logger.info(download_result.message)
return ResponseUtil.streaming(data=download_result.result)
else:
logger.warning(download_result.message)
return ResponseUtil.failure(msg=download_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@commonController.get('/download')
async def common_download(
request: Request,
background_tasks: BackgroundTasks,
file_name: str = Query(alias='fileName'),
delete: bool = Query(),
):
download_result = await CommonService.download_services(background_tasks, file_name, delete)
logger.info(download_result.message)
return ResponseUtil.streaming(data=download_result.result)
@commonController.get("/download/resource")
async def common_download(request: Request, resource: str = Query()):
try:
download_resource_result = CommonService.download_resource_services(resource)
if download_resource_result.is_success:
logger.info(download_resource_result.message)
return ResponseUtil.streaming(data=download_resource_result.result)
else:
logger.warning(download_resource_result.message)
return ResponseUtil.failure(msg=download_resource_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@commonController.get('/download/resource')
async def common_download_resource(request: Request, resource: str = Query()):
download_resource_result = await CommonService.download_resource_services(resource)
logger.info(download_resource_result.message)
return ResponseUtil.streaming(data=download_resource_result.result)

View File

@@ -1,132 +1,123 @@
from fastapi import APIRouter
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Form, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.config_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from utils.common_util import bytes2file_response
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.entity.vo.config_vo import ConfigModel, ConfigPageQueryModel, DeleteConfigModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.config_service import ConfigService
from module_admin.service.login_service import LoginService
from utils.common_util import bytes2file_response
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
configController = APIRouter(prefix='/system/config', dependencies=[Depends(LoginService.get_current_user)])
@configController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:config:list'))])
async def get_system_config_list(request: Request, config_page_query: ConfigPageQueryModel = Depends(ConfigPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
config_page_query_result = ConfigService.get_config_list_services(query_db, config_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=config_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@configController.get(
'/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:config:list'))]
)
async def get_system_config_list(
request: Request,
config_page_query: ConfigPageQueryModel = Depends(ConfigPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
config_page_query_result = await ConfigService.get_config_list_services(query_db, config_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=config_page_query_result)
@configController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:config:add'))])
@log_decorator(title='参数管理', business_type=1)
async def add_system_config(request: Request, add_config: ConfigModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_config.create_by = current_user.user.user_name
add_config.update_by = current_user.user.user_name
add_config_result = await ConfigService.add_config_services(request, query_db, add_config)
if add_config_result.is_success:
logger.info(add_config_result.message)
return ResponseUtil.success(msg=add_config_result.message)
else:
logger.warning(add_config_result.message)
return ResponseUtil.failure(msg=add_config_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@configController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:config:add'))])
@ValidateFields(validate_model='add_config')
@Log(title='参数管理', business_type=BusinessType.INSERT)
async def add_system_config(
request: Request,
add_config: ConfigModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_config.create_by = current_user.user.user_name
add_config.create_time = datetime.now()
add_config.update_by = current_user.user.user_name
add_config.update_time = datetime.now()
add_config_result = await ConfigService.add_config_services(request, query_db, add_config)
logger.info(add_config_result.message)
return ResponseUtil.success(msg=add_config_result.message)
@configController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:config:edit'))])
@log_decorator(title='参数管理', business_type=2)
async def edit_system_config(request: Request, edit_config: ConfigModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_config.update_by = current_user.user.user_name
edit_config.update_time = datetime.now()
edit_config_result = await ConfigService.edit_config_services(request, query_db, edit_config)
if edit_config_result.is_success:
logger.info(edit_config_result.message)
return ResponseUtil.success(msg=edit_config_result.message)
else:
logger.warning(edit_config_result.message)
return ResponseUtil.failure(msg=edit_config_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@configController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:config:edit'))])
@ValidateFields(validate_model='edit_config')
@Log(title='参数管理', business_type=BusinessType.UPDATE)
async def edit_system_config(
request: Request,
edit_config: ConfigModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_config.update_by = current_user.user.user_name
edit_config.update_time = datetime.now()
edit_config_result = await ConfigService.edit_config_services(request, query_db, edit_config)
logger.info(edit_config_result.message)
return ResponseUtil.success(msg=edit_config_result.message)
@configController.delete("/refreshCache", dependencies=[Depends(CheckUserInterfaceAuth('system:config:remove'))])
@log_decorator(title='参数管理', business_type=2)
async def refresh_system_config(request: Request, query_db: Session = Depends(get_db)):
try:
refresh_config_result = await ConfigService.refresh_sys_config_services(request, query_db)
if refresh_config_result.is_success:
logger.info(refresh_config_result.message)
return ResponseUtil.success(msg=refresh_config_result.message)
else:
logger.warning(refresh_config_result.message)
return ResponseUtil.failure(msg=refresh_config_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@configController.delete('/refreshCache', dependencies=[Depends(CheckUserInterfaceAuth('system:config:remove'))])
@Log(title='参数管理', business_type=BusinessType.UPDATE)
async def refresh_system_config(request: Request, query_db: AsyncSession = Depends(get_db)):
refresh_config_result = await ConfigService.refresh_sys_config_services(request, query_db)
logger.info(refresh_config_result.message)
return ResponseUtil.success(msg=refresh_config_result.message)
@configController.delete("/{config_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:config:remove'))])
@log_decorator(title='参数管理', business_type=3)
async def delete_system_config(request: Request, config_ids: str, query_db: Session = Depends(get_db)):
try:
delete_config = DeleteConfigModel(configIds=config_ids)
delete_config_result = await ConfigService.delete_config_services(request, query_db, delete_config)
if delete_config_result.is_success:
logger.info(delete_config_result.message)
return ResponseUtil.success(msg=delete_config_result.message)
else:
logger.warning(delete_config_result.message)
return ResponseUtil.failure(msg=delete_config_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@configController.delete('/{config_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:config:remove'))])
@Log(title='参数管理', business_type=BusinessType.DELETE)
async def delete_system_config(request: Request, config_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_config = DeleteConfigModel(configIds=config_ids)
delete_config_result = await ConfigService.delete_config_services(request, query_db, delete_config)
logger.info(delete_config_result.message)
return ResponseUtil.success(msg=delete_config_result.message)
@configController.get("/{config_id}", response_model=ConfigModel, dependencies=[Depends(CheckUserInterfaceAuth('system:config:query'))])
async def query_detail_system_config(request: Request, config_id: int, query_db: Session = Depends(get_db)):
try:
config_detail_result = ConfigService.config_detail_services(query_db, config_id)
logger.info(f'获取config_id为{config_id}的信息成功')
return ResponseUtil.success(data=config_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@configController.get(
'/{config_id}', response_model=ConfigModel, dependencies=[Depends(CheckUserInterfaceAuth('system:config:query'))]
)
async def query_detail_system_config(request: Request, config_id: int, query_db: AsyncSession = Depends(get_db)):
config_detail_result = await ConfigService.config_detail_services(query_db, config_id)
logger.info(f'获取config_id为{config_id}的信息成功')
return ResponseUtil.success(data=config_detail_result)
@configController.get("/configKey/{config_key}")
@configController.get('/configKey/{config_key}')
async def query_system_config(request: Request, config_key: str):
try:
# 获取全量数据
config_query_result = await ConfigService.query_config_list_from_cache_services(request.app.state.redis, config_key)
logger.info('获取成功')
return ResponseUtil.success(msg=config_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
# 获取全量数据
config_query_result = await ConfigService.query_config_list_from_cache_services(request.app.state.redis, config_key)
logger.info('获取成功')
return ResponseUtil.success(msg=config_query_result)
@configController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:config:export'))])
@log_decorator(title='参数管理', business_type=5)
async def export_system_config_list(request: Request, config_page_query: ConfigPageQueryModel = Depends(ConfigPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
config_query_result = ConfigService.get_config_list_services(query_db, config_page_query, is_page=False)
config_export_result = ConfigService.export_config_list_services(config_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(config_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@configController.post('/export', dependencies=[Depends(CheckUserInterfaceAuth('system:config:export'))])
@Log(title='参数管理', business_type=BusinessType.EXPORT)
async def export_system_config_list(
request: Request,
config_page_query: ConfigPageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
config_query_result = await ConfigService.get_config_list_services(query_db, config_page_query, is_page=False)
config_export_result = await ConfigService.export_config_list_services(config_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(config_export_result))

View File

@@ -1,102 +1,132 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.dept_service import *
from utils.response_util import *
from utils.log_util import *
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.data_scope import GetDataScope
from module_admin.annotation.log_annotation import log_decorator
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.entity.vo.dept_vo import DeleteDeptModel, DeptModel, DeptQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.dept_service import DeptService
from module_admin.service.login_service import LoginService
from utils.log_util import logger
from utils.response_util import ResponseUtil
deptController = APIRouter(prefix='/system/dept', dependencies=[Depends(LoginService.get_current_user)])
@deptController.get("/list/exclude/{dept_id}", response_model=List[DeptModel], dependencies=[Depends(CheckUserInterfaceAuth('system:dept:list'))])
async def get_system_dept_tree_for_edit_option(request: Request, dept_id: int, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))):
try:
dept_query = DeptModel(deptId=dept_id)
dept_query_result = DeptService.get_dept_for_edit_option_services(query_db, dept_query, data_scope_sql)
logger.info('获取成功')
return ResponseUtil.success(data=dept_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@deptController.get(
'/list/exclude/{dept_id}',
response_model=List[DeptModel],
dependencies=[Depends(CheckUserInterfaceAuth('system:dept:list'))],
)
async def get_system_dept_tree_for_edit_option(
request: Request,
dept_id: int,
query_db: AsyncSession = Depends(get_db),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
dept_query = DeptModel(deptId=dept_id)
dept_query_result = await DeptService.get_dept_for_edit_option_services(query_db, dept_query, data_scope_sql)
logger.info('获取成功')
return ResponseUtil.success(data=dept_query_result)
@deptController.get("/list", response_model=List[DeptModel], dependencies=[Depends(CheckUserInterfaceAuth('system:dept:list'))])
async def get_system_dept_list(request: Request, dept_query: DeptQueryModel = Depends(DeptQueryModel.as_query), query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))):
try:
dept_query_result = DeptService.get_dept_list_services(query_db, dept_query, data_scope_sql)
logger.info('获取成功')
return ResponseUtil.success(data=dept_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@deptController.get(
'/list', response_model=List[DeptModel], dependencies=[Depends(CheckUserInterfaceAuth('system:dept:list'))]
)
async def get_system_dept_list(
request: Request,
dept_query: DeptQueryModel = Depends(DeptQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
dept_query_result = await DeptService.get_dept_list_services(query_db, dept_query, data_scope_sql)
logger.info('获取成功')
return ResponseUtil.success(data=dept_query_result)
@deptController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:dept:add'))])
@log_decorator(title='部门管理', business_type=1)
async def add_system_dept(request: Request, add_dept: DeptModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_dept.create_by = current_user.user.user_name
add_dept.update_by = current_user.user.user_name
add_dept_result = DeptService.add_dept_services(query_db, add_dept)
if add_dept_result.is_success:
logger.info(add_dept_result.message)
return ResponseUtil.success(data=add_dept_result)
else:
logger.warning(add_dept_result.message)
return ResponseUtil.failure(msg=add_dept_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@deptController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:dept:add'))])
@ValidateFields(validate_model='add_dept')
@Log(title='部门管理', business_type=BusinessType.INSERT)
async def add_system_dept(
request: Request,
add_dept: DeptModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_dept.create_by = current_user.user.user_name
add_dept.create_time = datetime.now()
add_dept.update_by = current_user.user.user_name
add_dept.update_time = datetime.now()
add_dept_result = await DeptService.add_dept_services(query_db, add_dept)
logger.info(add_dept_result.message)
return ResponseUtil.success(data=add_dept_result)
@deptController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:dept:edit'))])
@log_decorator(title='部门管理', business_type=2)
async def edit_system_dept(request: Request, edit_dept: DeptModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_dept.update_by = current_user.user.user_name
edit_dept.update_time = datetime.now()
edit_dept_result = DeptService.edit_dept_services(query_db, edit_dept)
if edit_dept_result.is_success:
logger.info(edit_dept_result.message)
return ResponseUtil.success(msg=edit_dept_result.message)
else:
logger.warning(edit_dept_result.message)
return ResponseUtil.failure(msg=edit_dept_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@deptController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:dept:edit'))])
@ValidateFields(validate_model='edit_dept')
@Log(title='部门管理', business_type=BusinessType.UPDATE)
async def edit_system_dept(
request: Request,
edit_dept: DeptModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
if not current_user.user.admin:
await DeptService.check_dept_data_scope_services(query_db, edit_dept.dept_id, data_scope_sql)
edit_dept.update_by = current_user.user.user_name
edit_dept.update_time = datetime.now()
edit_dept_result = await DeptService.edit_dept_services(query_db, edit_dept)
logger.info(edit_dept_result.message)
return ResponseUtil.success(msg=edit_dept_result.message)
@deptController.delete("/{dept_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:dept:remove'))])
@log_decorator(title='部门管理', business_type=3)
async def delete_system_dept(request: Request, dept_ids: str, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
delete_dept = DeleteDeptModel(deptIds=dept_ids)
delete_dept.update_by = current_user.user.user_name
delete_dept.update_time = datetime.now()
delete_dept_result = DeptService.delete_dept_services(query_db, delete_dept)
if delete_dept_result.is_success:
logger.info(delete_dept_result.message)
return ResponseUtil.success(msg=delete_dept_result.message)
else:
logger.warning(delete_dept_result.message)
return ResponseUtil.failure(msg=delete_dept_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@deptController.delete('/{dept_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:dept:remove'))])
@Log(title='部门管理', business_type=BusinessType.DELETE)
async def delete_system_dept(
request: Request,
dept_ids: str,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
dept_id_list = dept_ids.split(',') if dept_ids else []
if dept_id_list:
for dept_id in dept_id_list:
if not current_user.user.admin:
await DeptService.check_dept_data_scope_services(query_db, int(dept_id), data_scope_sql)
delete_dept = DeleteDeptModel(deptIds=dept_ids)
delete_dept.update_by = current_user.user.user_name
delete_dept.update_time = datetime.now()
delete_dept_result = await DeptService.delete_dept_services(query_db, delete_dept)
logger.info(delete_dept_result.message)
return ResponseUtil.success(msg=delete_dept_result.message)
@deptController.get("/{dept_id}", response_model=DeptModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:query'))])
async def query_detail_system_dept(request: Request, dept_id: int, query_db: Session = Depends(get_db)):
try:
detail_dept_result = DeptService.dept_detail_services(query_db, dept_id)
logger.info(f'获取dept_id为{dept_id}的信息成功')
return ResponseUtil.success(data=detail_dept_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@deptController.get(
'/{dept_id}', response_model=DeptModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:query'))]
)
async def query_detail_system_dept(
request: Request,
dept_id: int,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
if not current_user.user.admin:
await DeptService.check_dept_data_scope_services(query_db, dept_id, data_scope_sql)
detail_dept_result = await DeptService.dept_detail_services(query_db, dept_id)
logger.info(f'获取dept_id为{dept_id}的信息成功')
return ResponseUtil.success(data=detail_dept_result)

View File

@@ -1,233 +1,239 @@
from fastapi import APIRouter
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Form, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.dict_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import PageResponseModel
from utils.common_util import bytes2file_response
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.entity.vo.dict_vo import (
DeleteDictDataModel,
DeleteDictTypeModel,
DictDataModel,
DictDataPageQueryModel,
DictTypeModel,
DictTypePageQueryModel,
)
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.dict_service import DictDataService, DictTypeService
from module_admin.service.login_service import LoginService
from utils.common_util import bytes2file_response
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
dictController = APIRouter(prefix='/system/dict', dependencies=[Depends(LoginService.get_current_user)])
@dictController.get("/type/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))])
async def get_system_dict_type_list(request: Request, dict_type_page_query: DictTypePageQueryModel = Depends(DictTypePageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
dict_type_page_query_result = DictTypeService.get_dict_type_list_services(query_db, dict_type_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=dict_type_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.get(
'/type/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]
)
async def get_system_dict_type_list(
request: Request,
dict_type_page_query: DictTypePageQueryModel = Depends(DictTypePageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
dict_type_page_query_result = await DictTypeService.get_dict_type_list_services(
query_db, dict_type_page_query, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=dict_type_page_query_result)
@dictController.post("/type", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))])
@log_decorator(title='字典管理', business_type=1)
async def add_system_dict_type(request: Request, add_dict_type: DictTypeModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_dict_type.create_by = current_user.user.user_name
add_dict_type.update_by = current_user.user.user_name
add_dict_type_result = await DictTypeService.add_dict_type_services(request, query_db, add_dict_type)
if add_dict_type_result.is_success:
logger.info(add_dict_type_result.message)
return ResponseUtil.success(msg=add_dict_type_result.message)
else:
logger.warning(add_dict_type_result.message)
return ResponseUtil.failure(msg=add_dict_type_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.post('/type', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))])
@ValidateFields(validate_model='add_dict_type')
@Log(title='字典类型', business_type=BusinessType.INSERT)
async def add_system_dict_type(
request: Request,
add_dict_type: DictTypeModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_dict_type.create_by = current_user.user.user_name
add_dict_type.create_time = datetime.now()
add_dict_type.update_by = current_user.user.user_name
add_dict_type.update_time = datetime.now()
add_dict_type_result = await DictTypeService.add_dict_type_services(request, query_db, add_dict_type)
logger.info(add_dict_type_result.message)
return ResponseUtil.success(msg=add_dict_type_result.message)
@dictController.put("/type", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))])
@log_decorator(title='字典管理', business_type=2)
async def edit_system_dict_type(request: Request, edit_dict_type: DictTypeModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_dict_type.update_by = current_user.user.user_name
edit_dict_type.update_time = datetime.now()
edit_dict_type_result = await DictTypeService.edit_dict_type_services(request, query_db, edit_dict_type)
if edit_dict_type_result.is_success:
logger.info(edit_dict_type_result.message)
return ResponseUtil.success(msg=edit_dict_type_result.message)
else:
logger.warning(edit_dict_type_result.message)
return ResponseUtil.failure(msg=edit_dict_type_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.put('/type', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))])
@ValidateFields(validate_model='edit_dict_type')
@Log(title='字典类型', business_type=BusinessType.UPDATE)
async def edit_system_dict_type(
request: Request,
edit_dict_type: DictTypeModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_dict_type.update_by = current_user.user.user_name
edit_dict_type.update_time = datetime.now()
edit_dict_type_result = await DictTypeService.edit_dict_type_services(request, query_db, edit_dict_type)
logger.info(edit_dict_type_result.message)
return ResponseUtil.success(msg=edit_dict_type_result.message)
@dictController.delete("/type/refreshCache", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))])
@log_decorator(title='字典管理', business_type=2)
async def refresh_system_dict(request: Request, query_db: Session = Depends(get_db)):
try:
refresh_dict_result = await DictTypeService.refresh_sys_dict_services(request, query_db)
if refresh_dict_result.is_success:
logger.info(refresh_dict_result.message)
return ResponseUtil.success(msg=refresh_dict_result.message)
else:
logger.warning(refresh_dict_result.message)
return ResponseUtil.failure(msg=refresh_dict_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.delete('/type/refreshCache', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))])
@Log(title='字典类型', business_type=BusinessType.UPDATE)
async def refresh_system_dict(request: Request, query_db: AsyncSession = Depends(get_db)):
refresh_dict_result = await DictTypeService.refresh_sys_dict_services(request, query_db)
logger.info(refresh_dict_result.message)
return ResponseUtil.success(msg=refresh_dict_result.message)
@dictController.delete("/type/{dict_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))])
@log_decorator(title='字典管理', business_type=3)
async def delete_system_dict_type(request: Request, dict_ids: str, query_db: Session = Depends(get_db)):
try:
delete_dict_type = DeleteDictTypeModel(dictIds=dict_ids)
delete_dict_type_result = await DictTypeService.delete_dict_type_services(request, query_db, delete_dict_type)
if delete_dict_type_result.is_success:
logger.info(delete_dict_type_result.message)
return ResponseUtil.success(msg=delete_dict_type_result.message)
else:
logger.warning(delete_dict_type_result.message)
return ResponseUtil.failure(msg=delete_dict_type_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.delete('/type/{dict_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))])
@Log(title='字典类型', business_type=BusinessType.DELETE)
async def delete_system_dict_type(request: Request, dict_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_dict_type = DeleteDictTypeModel(dictIds=dict_ids)
delete_dict_type_result = await DictTypeService.delete_dict_type_services(request, query_db, delete_dict_type)
logger.info(delete_dict_type_result.message)
return ResponseUtil.success(msg=delete_dict_type_result.message)
@dictController.get("/type/optionselect", response_model=List[DictTypeModel])
async def query_system_dict_type_options(request: Request, query_db: Session = Depends(get_db)):
try:
dict_type_query_result = DictTypeService.get_dict_type_list_services(query_db, DictTypePageQueryModel(**dict()), is_page=False)
logger.info(f'获取成功')
return ResponseUtil.success(data=dict_type_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.get('/type/optionselect', response_model=List[DictTypeModel])
async def query_system_dict_type_options(request: Request, query_db: AsyncSession = Depends(get_db)):
dict_type_query_result = await DictTypeService.get_dict_type_list_services(
query_db, DictTypePageQueryModel(**dict()), is_page=False
)
logger.info('获取成功')
return ResponseUtil.success(data=dict_type_query_result)
@dictController.get("/type/{dict_id}", response_model=DictTypeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))])
async def query_detail_system_dict_type(request: Request, dict_id: int, query_db: Session = Depends(get_db)):
try:
dict_type_detail_result = DictTypeService.dict_type_detail_services(query_db, dict_id)
logger.info(f'获取dict_id为{dict_id}的信息成功')
return ResponseUtil.success(data=dict_type_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.get(
'/type/{dict_id}', response_model=DictTypeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))]
)
async def query_detail_system_dict_type(request: Request, dict_id: int, query_db: AsyncSession = Depends(get_db)):
dict_type_detail_result = await DictTypeService.dict_type_detail_services(query_db, dict_id)
logger.info(f'获取dict_id为{dict_id}的信息成功')
return ResponseUtil.success(data=dict_type_detail_result)
@dictController.post("/type/export", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))])
@log_decorator(title='字典管理', business_type=5)
async def export_system_dict_type_list(request: Request, dict_type_page_query: DictTypePageQueryModel = Depends(DictTypePageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
dict_type_query_result = DictTypeService.get_dict_type_list_services(query_db, dict_type_page_query, is_page=False)
dict_type_export_result = DictTypeService.export_dict_type_list_services(dict_type_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(dict_type_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.post('/type/export', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))])
@Log(title='字典类型', business_type=BusinessType.EXPORT)
async def export_system_dict_type_list(
request: Request,
dict_type_page_query: DictTypePageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
dict_type_query_result = await DictTypeService.get_dict_type_list_services(
query_db, dict_type_page_query, is_page=False
)
dict_type_export_result = await DictTypeService.export_dict_type_list_services(dict_type_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(dict_type_export_result))
@dictController.get("/data/type/{dict_type}")
async def query_system_dict_type_data(request: Request, dict_type: str, query_db: Session = Depends(get_db)):
try:
# 获取全量数据
dict_data_query_result = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type)
logger.info('获取成功')
return ResponseUtil.success(data=dict_data_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.get('/data/type/{dict_type}')
async def query_system_dict_type_data(request: Request, dict_type: str, query_db: AsyncSession = Depends(get_db)):
# 获取全量数据
dict_data_query_result = await DictDataService.query_dict_data_list_from_cache_services(
request.app.state.redis, dict_type
)
logger.info('获取成功')
return ResponseUtil.success(data=dict_data_query_result)
@dictController.get("/data/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))])
async def get_system_dict_data_list(request: Request, dict_data_page_query: DictDataPageQueryModel = Depends(DictDataPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
dict_data_page_query_result = DictDataService.get_dict_data_list_services(query_db, dict_data_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=dict_data_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.get(
'/data/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]
)
async def get_system_dict_data_list(
request: Request,
dict_data_page_query: DictDataPageQueryModel = Depends(DictDataPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
dict_data_page_query_result = await DictDataService.get_dict_data_list_services(
query_db, dict_data_page_query, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=dict_data_page_query_result)
@dictController.post("/data", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))])
@log_decorator(title='字典管理', business_type=1)
async def add_system_dict_data(request: Request, add_dict_data: DictDataModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_dict_data.create_by = current_user.user.user_name
add_dict_data.update_by = current_user.user.user_name
add_dict_data_result = await DictDataService.add_dict_data_services(request, query_db, add_dict_data)
if add_dict_data_result.is_success:
logger.info(add_dict_data_result.message)
return ResponseUtil.success(msg=add_dict_data_result.message)
else:
logger.warning(add_dict_data_result.message)
return ResponseUtil.failure(msg=add_dict_data_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.post('/data', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))])
@ValidateFields(validate_model='add_dict_data')
@Log(title='字典数据', business_type=BusinessType.INSERT)
async def add_system_dict_data(
request: Request,
add_dict_data: DictDataModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_dict_data.create_by = current_user.user.user_name
add_dict_data.create_time = datetime.now()
add_dict_data.update_by = current_user.user.user_name
add_dict_data.update_time = datetime.now()
add_dict_data_result = await DictDataService.add_dict_data_services(request, query_db, add_dict_data)
logger.info(add_dict_data_result.message)
return ResponseUtil.success(msg=add_dict_data_result.message)
@dictController.put("/data", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))])
@log_decorator(title='字典管理', business_type=2)
async def edit_system_dict_data(request: Request, edit_dict_data: DictDataModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_dict_data.update_by = current_user.user.user_name
edit_dict_data.update_time = datetime.now()
edit_dict_data_result = await DictDataService.edit_dict_data_services(request, query_db, edit_dict_data)
if edit_dict_data_result.is_success:
logger.info(edit_dict_data_result.message)
return ResponseUtil.success(msg=edit_dict_data_result.message)
else:
logger.warning(edit_dict_data_result.message)
return ResponseUtil.failure(msg=edit_dict_data_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.put('/data', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))])
@ValidateFields(validate_model='edit_dict_data')
@Log(title='字典数据', business_type=BusinessType.UPDATE)
async def edit_system_dict_data(
request: Request,
edit_dict_data: DictDataModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_dict_data.update_by = current_user.user.user_name
edit_dict_data.update_time = datetime.now()
edit_dict_data_result = await DictDataService.edit_dict_data_services(request, query_db, edit_dict_data)
logger.info(edit_dict_data_result.message)
return ResponseUtil.success(msg=edit_dict_data_result.message)
@dictController.delete("/data/{dict_codes}", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))])
@log_decorator(title='字典管理', business_type=3)
async def delete_system_dict_data(request: Request, dict_codes: str, query_db: Session = Depends(get_db)):
try:
delete_dict_data = DeleteDictDataModel(dictCodes=dict_codes)
delete_dict_data_result = await DictDataService.delete_dict_data_services(request, query_db, delete_dict_data)
if delete_dict_data_result.is_success:
logger.info(delete_dict_data_result.message)
return ResponseUtil.success(msg=delete_dict_data_result.message)
else:
logger.warning(delete_dict_data_result.message)
return ResponseUtil.failure(msg=delete_dict_data_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.delete('/data/{dict_codes}', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))])
@Log(title='字典数据', business_type=BusinessType.DELETE)
async def delete_system_dict_data(request: Request, dict_codes: str, query_db: AsyncSession = Depends(get_db)):
delete_dict_data = DeleteDictDataModel(dictCodes=dict_codes)
delete_dict_data_result = await DictDataService.delete_dict_data_services(request, query_db, delete_dict_data)
logger.info(delete_dict_data_result.message)
return ResponseUtil.success(msg=delete_dict_data_result.message)
@dictController.get("/data/{dict_code}", response_model=DictDataModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))])
async def query_detail_system_dict_data(request: Request, dict_code: int, query_db: Session = Depends(get_db)):
try:
detail_dict_data_result = DictDataService.dict_data_detail_services(query_db, dict_code)
logger.info(f'获取dict_code为{dict_code}的信息成功')
return ResponseUtil.success(data=detail_dict_data_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.get(
'/data/{dict_code}',
response_model=DictDataModel,
dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))],
)
async def query_detail_system_dict_data(request: Request, dict_code: int, query_db: AsyncSession = Depends(get_db)):
detail_dict_data_result = await DictDataService.dict_data_detail_services(query_db, dict_code)
logger.info(f'获取dict_code为{dict_code}的信息成功')
return ResponseUtil.success(data=detail_dict_data_result)
@dictController.post("/data/export", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))])
@log_decorator(title='字典管理', business_type=5)
async def export_system_dict_data_list(request: Request, dict_data_page_query: DictDataPageQueryModel = Depends(DictDataPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
dict_data_query_result = DictDataService.get_dict_data_list_services(query_db, dict_data_page_query, is_page=False)
dict_data_export_result = DictDataService.export_dict_data_list_services(dict_data_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(dict_data_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@dictController.post('/data/export', dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))])
@Log(title='字典数据', business_type=BusinessType.EXPORT)
async def export_system_dict_data_list(
request: Request,
dict_data_page_query: DictDataPageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
dict_data_query_result = await DictDataService.get_dict_data_list_services(
query_db, dict_data_page_query, is_page=False
)
dict_data_export_result = await DictDataService.export_dict_data_list_services(dict_data_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(dict_data_export_result))

View File

@@ -1,199 +1,194 @@
from fastapi import APIRouter
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Form, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.job_service import *
from module_admin.service.job_log_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from utils.common_util import bytes2file_response
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.entity.vo.job_vo import (
DeleteJobLogModel,
DeleteJobModel,
EditJobModel,
JobLogPageQueryModel,
JobModel,
JobPageQueryModel,
)
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.job_log_service import JobLogService
from module_admin.service.job_service import JobService
from module_admin.service.login_service import LoginService
from utils.common_util import bytes2file_response
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
jobController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)])
@jobController.get("/job/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))])
async def get_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
notice_page_query_result = JobService.get_job_list_services(query_db, job_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=notice_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.get(
'/job/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]
)
async def get_system_job_list(
request: Request,
job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
notice_page_query_result = await JobService.get_job_list_services(query_db, job_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=notice_page_query_result)
@jobController.post("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))])
@log_decorator(title='定时任务管理', business_type=1)
async def add_system_job(request: Request, add_job: JobModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_job.create_by = current_user.user.user_name
add_job.update_by = current_user.user.user_name
add_job_result = JobService.add_job_services(query_db, add_job)
if add_job_result.is_success:
logger.info(add_job_result.message)
return ResponseUtil.success(msg=add_job_result.message)
else:
logger.warning(add_job_result.message)
return ResponseUtil.failure(msg=add_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.post('/job', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))])
@ValidateFields(validate_model='add_job')
@Log(title='定时任务', business_type=BusinessType.INSERT)
async def add_system_job(
request: Request,
add_job: JobModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_job.create_by = current_user.user.user_name
add_job.create_time = datetime.now()
add_job.update_by = current_user.user.user_name
add_job.update_time = datetime.now()
add_job_result = await JobService.add_job_services(query_db, add_job)
logger.info(add_job_result.message)
return ResponseUtil.success(msg=add_job_result.message)
@jobController.put("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))])
@log_decorator(title='定时任务管理', business_type=2)
async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_job.update_by = current_user.user.user_name
edit_job.update_time = datetime.now()
edit_job_result = JobService.edit_job_services(query_db, edit_job)
if edit_job_result.is_success:
logger.info(edit_job_result.message)
return ResponseUtil.success(msg=edit_job_result.message)
else:
logger.warning(edit_job_result.message)
return ResponseUtil.failure(msg=edit_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.put('/job', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))])
@ValidateFields(validate_model='edit_job')
@Log(title='定时任务', business_type=BusinessType.UPDATE)
async def edit_system_job(
request: Request,
edit_job: EditJobModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_job.update_by = current_user.user.user_name
edit_job.update_time = datetime.now()
edit_job_result = await JobService.edit_job_services(query_db, edit_job)
logger.info(edit_job_result.message)
return ResponseUtil.success(msg=edit_job_result.message)
@jobController.put("/job/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))])
@log_decorator(title='定时任务管理', business_type=2)
async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_job.update_by = current_user.user.user_name
edit_job.update_time = datetime.now()
edit_job.type = 'status'
edit_job_result = JobService.edit_job_services(query_db, edit_job)
if edit_job_result.is_success:
logger.info(edit_job_result.message)
return ResponseUtil.success(msg=edit_job_result.message)
else:
logger.warning(edit_job_result.message)
return ResponseUtil.failure(msg=edit_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.put('/job/changeStatus', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))])
@Log(title='定时任务', business_type=BusinessType.UPDATE)
async def change_system_job_status(
request: Request,
change_job: EditJobModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_job = EditJobModel(
jobId=change_job.job_id,
status=change_job.status,
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
type='status',
)
edit_job_result = await JobService.edit_job_services(query_db, edit_job)
logger.info(edit_job_result.message)
return ResponseUtil.success(msg=edit_job_result.message)
@jobController.put("/job/run", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))])
@log_decorator(title='定时任务管理', business_type=2)
async def execute_system_job(request: Request, execute_job: JobModel, query_db: Session = Depends(get_db)):
try:
execute_job_result = JobService.execute_job_once_services(query_db, execute_job)
if execute_job_result.is_success:
logger.info(execute_job_result.message)
return ResponseUtil.success(msg=execute_job_result.message)
else:
logger.warning(execute_job_result.message)
return ResponseUtil.failure(msg=execute_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.put('/job/run', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))])
@Log(title='定时任务', business_type=BusinessType.UPDATE)
async def execute_system_job(request: Request, execute_job: JobModel, query_db: AsyncSession = Depends(get_db)):
execute_job_result = await JobService.execute_job_once_services(query_db, execute_job)
logger.info(execute_job_result.message)
return ResponseUtil.success(msg=execute_job_result.message)
@jobController.delete("/job/{job_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务管理', business_type=3)
async def delete_system_job(request: Request, job_ids: str, query_db: Session = Depends(get_db)):
try:
delete_job = DeleteJobModel(jobIds=job_ids)
delete_job_result = JobService.delete_job_services(query_db, delete_job)
if delete_job_result.is_success:
logger.info(delete_job_result.message)
return ResponseUtil.success(msg=delete_job_result.message)
else:
logger.warning(delete_job_result.message)
return ResponseUtil.failure(msg=delete_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.delete('/job/{job_ids}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@Log(title='定时任务', business_type=BusinessType.DELETE)
async def delete_system_job(request: Request, job_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_job = DeleteJobModel(jobIds=job_ids)
delete_job_result = await JobService.delete_job_services(query_db, delete_job)
logger.info(delete_job_result.message)
return ResponseUtil.success(msg=delete_job_result.message)
@jobController.get("/job/{job_id}", response_model=JobModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))])
async def query_detail_system_job(request: Request, job_id: int, query_db: Session = Depends(get_db)):
try:
job_detail_result = JobService.job_detail_services(query_db, job_id)
logger.info(f'获取job_id为{job_id}的信息成功')
return ResponseUtil.success(data=job_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.get(
'/job/{job_id}', response_model=JobModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))]
)
async def query_detail_system_job(request: Request, job_id: int, query_db: AsyncSession = Depends(get_db)):
job_detail_result = await JobService.job_detail_services(query_db, job_id)
logger.info(f'获取job_id为{job_id}的信息成功')
return ResponseUtil.success(data=job_detail_result)
@jobController.post("/job/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@log_decorator(title='定时任务管理', business_type=5)
async def export_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
job_query_result = JobService.get_job_list_services(query_db, job_page_query, is_page=False)
job_export_result = await JobService.export_job_list_services(request, job_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(job_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.post('/job/export', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@Log(title='定时任务', business_type=BusinessType.EXPORT)
async def export_system_job_list(
request: Request,
job_page_query: JobPageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
job_query_result = await JobService.get_job_list_services(query_db, job_page_query, is_page=False)
job_export_result = await JobService.export_job_list_services(request, job_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(job_export_result))
@jobController.get("/jobLog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))])
async def get_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
job_log_page_query_result = JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=job_log_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.get(
'/jobLog/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]
)
async def get_system_job_log_list(
request: Request,
job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
job_log_page_query_result = await JobLogService.get_job_log_list_services(
query_db, job_log_page_query, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=job_log_page_query_result)
@jobController.delete("/jobLog/{job_log_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务日志管理', business_type=3)
async def delete_system_job_log(request: Request, job_log_ids: str, query_db: Session = Depends(get_db)):
try:
delete_job_log = DeleteJobLogModel(jobLogIds=job_log_ids)
delete_job_log_result = JobLogService.delete_job_log_services(query_db, delete_job_log)
if delete_job_log_result.is_success:
logger.info(delete_job_log_result.message)
return ResponseUtil.success(msg=delete_job_log_result.message)
else:
logger.warning(delete_job_log_result.message)
return ResponseUtil.failure(msg=delete_job_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.delete('/jobLog/clean', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@Log(title='定时任务调度日志', business_type=BusinessType.CLEAN)
async def clear_system_job_log(request: Request, query_db: AsyncSession = Depends(get_db)):
clear_job_log_result = await JobLogService.clear_job_log_services(query_db)
logger.info(clear_job_log_result.message)
return ResponseUtil.success(msg=clear_job_log_result.message)
@jobController.post("/jobLog/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务日志管理', business_type=9)
async def clear_system_job_log(request: Request, query_db: Session = Depends(get_db)):
try:
clear_job_log_result = JobLogService.clear_job_log_services(query_db)
if clear_job_log_result.is_success:
logger.info(clear_job_log_result.message)
return ResponseUtil.success(msg=clear_job_log_result.message)
else:
logger.warning(clear_job_log_result.message)
return ResponseUtil.failure(msg=clear_job_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.delete('/jobLog/{job_log_ids}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@Log(title='定时任务调度日志', business_type=BusinessType.DELETE)
async def delete_system_job_log(request: Request, job_log_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_job_log = DeleteJobLogModel(jobLogIds=job_log_ids)
delete_job_log_result = await JobLogService.delete_job_log_services(query_db, delete_job_log)
logger.info(delete_job_log_result.message)
return ResponseUtil.success(msg=delete_job_log_result.message)
@jobController.post("/jobLog/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@log_decorator(title='定时任务日志管理', business_type=5)
async def export_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
job_log_query_result = JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=False)
job_log_export_result = await JobLogService.export_job_log_list_services(request, job_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.post('/jobLog/export', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@Log(title='定时任务调度日志', business_type=BusinessType.EXPORT)
async def export_system_job_log_list(
request: Request,
job_log_page_query: JobLogPageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
job_log_query_result = await JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=False)
job_log_export_result = await JobLogService.export_job_log_list_services(request, job_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result))

View File

@@ -1,149 +1,150 @@
from fastapi import APIRouter
from fastapi import Depends
from fastapi import APIRouter, Depends, Form, Request
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService
from module_admin.service.log_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from utils.common_util import bytes2file_response
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.entity.vo.log_vo import (
DeleteLoginLogModel,
DeleteOperLogModel,
LoginLogPageQueryModel,
OperLogPageQueryModel,
UnlockUser,
)
from module_admin.service.log_service import LoginLogService, OperationLogService
from module_admin.service.login_service import LoginService
from utils.common_util import bytes2file_response
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
logController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)])
@logController.get("/operlog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:list'))])
async def get_system_operation_log_list(request: Request, operation_log_page_query: OperLogPageQueryModel = Depends(OperLogPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
operation_log_page_query_result = OperationLogService.get_operation_log_list_services(query_db, operation_log_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=operation_log_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.get(
'/operlog/list',
response_model=PageResponseModel,
dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:list'))],
)
async def get_system_operation_log_list(
request: Request,
operation_log_page_query: OperLogPageQueryModel = Depends(OperLogPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
operation_log_page_query_result = await OperationLogService.get_operation_log_list_services(
query_db, operation_log_page_query, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=operation_log_page_query_result)
@logController.delete("/operlog/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))])
@log_decorator(title='操作日志管理', business_type=9)
async def clear_system_operation_log(request: Request, query_db: Session = Depends(get_db)):
try:
clear_operation_log_result = OperationLogService.clear_operation_log_services(query_db)
if clear_operation_log_result.is_success:
logger.info(clear_operation_log_result.message)
return ResponseUtil.success(msg=clear_operation_log_result.message)
else:
logger.warning(clear_operation_log_result.message)
return ResponseUtil.failure(msg=clear_operation_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete('/operlog/clean', dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))])
@Log(title='操作日志', business_type=BusinessType.CLEAN)
async def clear_system_operation_log(request: Request, query_db: AsyncSession = Depends(get_db)):
clear_operation_log_result = await OperationLogService.clear_operation_log_services(query_db)
logger.info(clear_operation_log_result.message)
return ResponseUtil.success(msg=clear_operation_log_result.message)
@logController.delete("/operlog/{oper_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))])
@log_decorator(title='操作日志管理', business_type=3)
async def delete_system_operation_log(request: Request, oper_ids: str, query_db: Session = Depends(get_db)):
try:
delete_operation_log = DeleteOperLogModel(operIds=oper_ids)
delete_operation_log_result = OperationLogService.delete_operation_log_services(query_db, delete_operation_log)
if delete_operation_log_result.is_success:
logger.info(delete_operation_log_result.message)
return ResponseUtil.success(msg=delete_operation_log_result.message)
else:
logger.warning(delete_operation_log_result.message)
return ResponseUtil.failure(msg=delete_operation_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete('/operlog/{oper_ids}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))])
@Log(title='操作日志', business_type=BusinessType.DELETE)
async def delete_system_operation_log(request: Request, oper_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_operation_log = DeleteOperLogModel(operIds=oper_ids)
delete_operation_log_result = await OperationLogService.delete_operation_log_services(
query_db, delete_operation_log
)
logger.info(delete_operation_log_result.message)
return ResponseUtil.success(msg=delete_operation_log_result.message)
@logController.post("/operlog/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:export'))])
@log_decorator(title='操作日志管理', business_type=5)
async def export_system_operation_log_list(request: Request, operation_log_page_query: OperLogPageQueryModel = Depends(OperLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
operation_log_query_result = OperationLogService.get_operation_log_list_services(query_db, operation_log_page_query, is_page=False)
operation_log_export_result = await OperationLogService.export_operation_log_list_services(request, operation_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(operation_log_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.post('/operlog/export', dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:export'))])
@Log(title='操作日志', business_type=BusinessType.EXPORT)
async def export_system_operation_log_list(
request: Request,
operation_log_page_query: OperLogPageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
operation_log_query_result = await OperationLogService.get_operation_log_list_services(
query_db, operation_log_page_query, is_page=False
)
operation_log_export_result = await OperationLogService.export_operation_log_list_services(
request, operation_log_query_result
)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(operation_log_export_result))
@logController.get("/logininfor/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:list'))])
async def get_system_login_log_list(request: Request, login_log_page_query: LoginLogPageQueryModel = Depends(LoginLogPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
login_log_page_query_result = LoginLogService.get_login_log_list_services(query_db, login_log_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=login_log_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.get(
'/logininfor/list',
response_model=PageResponseModel,
dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:list'))],
)
async def get_system_login_log_list(
request: Request,
login_log_page_query: LoginLogPageQueryModel = Depends(LoginLogPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
login_log_page_query_result = await LoginLogService.get_login_log_list_services(
query_db, login_log_page_query, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=login_log_page_query_result)
@logController.delete("/logininfor/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))])
@log_decorator(title='登录日志管理', business_type=9)
async def clear_system_login_log(request: Request, query_db: Session = Depends(get_db)):
try:
clear_login_log_result = LoginLogService.clear_login_log_services(query_db)
if clear_login_log_result.is_success:
logger.info(clear_login_log_result.message)
return ResponseUtil.success(msg=clear_login_log_result.message)
else:
logger.warning(clear_login_log_result.message)
return ResponseUtil.failure(msg=clear_login_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete('/logininfor/clean', dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))])
@Log(title='登录日志', business_type=BusinessType.CLEAN)
async def clear_system_login_log(request: Request, query_db: AsyncSession = Depends(get_db)):
clear_login_log_result = await LoginLogService.clear_login_log_services(query_db)
logger.info(clear_login_log_result.message)
return ResponseUtil.success(msg=clear_login_log_result.message)
@logController.delete("/logininfor/{info_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))])
@log_decorator(title='登录日志管理', business_type=3)
async def delete_system_login_log(request: Request, info_ids: str, query_db: Session = Depends(get_db)):
try:
delete_login_log = DeleteLoginLogModel(infoIds=info_ids)
delete_login_log_result = LoginLogService.delete_login_log_services(query_db, delete_login_log)
if delete_login_log_result.is_success:
logger.info(delete_login_log_result.message)
return ResponseUtil.success(msg=delete_login_log_result.message)
else:
logger.warning(delete_login_log_result.message)
return ResponseUtil.failure(msg=delete_login_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete(
'/logininfor/{info_ids}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))]
)
@Log(title='登录日志', business_type=BusinessType.DELETE)
async def delete_system_login_log(request: Request, info_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_login_log = DeleteLoginLogModel(infoIds=info_ids)
delete_login_log_result = await LoginLogService.delete_login_log_services(query_db, delete_login_log)
logger.info(delete_login_log_result.message)
return ResponseUtil.success(msg=delete_login_log_result.message)
@logController.get("/logininfor/unlock/{user_name}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:unlock'))])
@log_decorator(title='登录日志管理', business_type=0)
async def clear_system_login_log(request: Request, user_name: str, query_db: Session = Depends(get_db)):
try:
unlock_user = UnlockUser(userName=user_name)
unlock_user_result = await LoginLogService.unlock_user_services(request, unlock_user)
if unlock_user_result.is_success:
logger.info(unlock_user_result.message)
return ResponseUtil.success(msg=unlock_user_result.message)
else:
logger.warning(unlock_user_result.message)
return ResponseUtil.failure(msg=unlock_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.get(
'/logininfor/unlock/{user_name}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:unlock'))]
)
@Log(title='账户解锁', business_type=BusinessType.OTHER)
async def unlock_system_user(request: Request, user_name: str, query_db: AsyncSession = Depends(get_db)):
unlock_user = UnlockUser(userName=user_name)
unlock_user_result = await LoginLogService.unlock_user_services(request, unlock_user)
logger.info(unlock_user_result.message)
return ResponseUtil.success(msg=unlock_user_result.message)
@logController.post("/logininfor/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:export'))])
@log_decorator(title='登录日志管理', business_type=5)
async def export_system_login_log_list(request: Request, login_log_page_query: LoginLogPageQueryModel = Depends(LoginLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
login_log_query_result = LoginLogService.get_login_log_list_services(query_db, login_log_page_query, is_page=False)
login_log_export_result = LoginLogService.export_login_log_list_services(login_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(login_log_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.post('/logininfor/export', dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:export'))])
@Log(title='登录日志', business_type=BusinessType.EXPORT)
async def export_system_login_log_list(
request: Request,
login_log_page_query: LoginLogPageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
login_log_query_result = await LoginLogService.get_login_log_list_services(
query_db, login_log_page_query, is_page=False
)
login_log_export_result = await LoginLogService.export_login_log_list_services(login_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(login_log_export_result))

View File

@@ -1,107 +1,113 @@
from fastapi import APIRouter
from module_admin.service.login_service import *
from module_admin.entity.vo.login_vo import *
from module_admin.dao.login_dao import *
from module_admin.annotation.log_annotation import log_decorator
from config.env import JwtConfig, RedisInitKeyConfig
import jwt
import uuid
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends, Request
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Optional
from config.enums import BusinessType, RedisInitKeyConfig
from config.env import AppConfig, JwtConfig
from config.get_db import get_db
from module_admin.annotation.log_annotation import Log
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.login_vo import UserLogin, UserRegister, Token
from module_admin.entity.vo.user_vo import CurrentUserModel, EditUserModel
from module_admin.service.login_service import CustomOAuth2PasswordRequestForm, LoginService, oauth2_scheme
from module_admin.service.user_service import UserService
from utils.log_util import logger
from utils.response_util import ResponseUtil
from utils.log_util import *
from datetime import timedelta
loginController = APIRouter()
@loginController.post("/login", response_model=Token)
@log_decorator(title='用户登录', business_type=0, log_type='login')
async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = Depends(), query_db: Session = Depends(get_db)):
captcha_enabled = True if await request.app.state.redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.captchaEnabled") == 'true' else False
@loginController.post('/login', response_model=Token)
@Log(title='用户登录', business_type=BusinessType.OTHER, log_type='login')
async def login(
request: Request, form_data: CustomOAuth2PasswordRequestForm = Depends(), query_db: AsyncSession = Depends(get_db)
):
captcha_enabled = (
True
if await request.app.state.redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:sys.account.captchaEnabled')
== 'true'
else False
)
user = UserLogin(
userName=form_data.username,
password=form_data.password,
code=form_data.code,
uuid=form_data.uuid,
loginInfo=form_data.login_info,
captchaEnabled=captcha_enabled
captchaEnabled=captcha_enabled,
)
try:
result = await LoginService.authenticate_user(request, query_db, user)
except LoginException as e:
return ResponseUtil.failure(msg=e.message)
try:
access_token_expires = timedelta(minutes=JwtConfig.jwt_expire_minutes)
session_id = str(uuid.uuid4())
access_token = LoginService.create_access_token(
data={
"user_id": str(result[0].user_id),
"user_name": result[0].user_name,
"dept_name": result[1].dept_name if result[1] else None,
"session_id": session_id,
"login_info": user.login_info
},
expires_delta=access_token_expires
result = await LoginService.authenticate_user(request, query_db, user)
access_token_expires = timedelta(minutes=JwtConfig.jwt_expire_minutes)
session_id = str(uuid.uuid4())
access_token = await LoginService.create_access_token(
data={
'user_id': str(result[0].user_id),
'user_name': result[0].user_name,
'dept_name': result[1].dept_name if result[1] else None,
'session_id': session_id,
'login_info': user.login_info,
},
expires_delta=access_token_expires,
)
if AppConfig.app_same_time_login:
await request.app.state.redis.set(
f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{session_id}',
access_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes),
)
if AppConfig.app_same_time_login:
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", access_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes))
else:
# 此方法可实现同一账号同一时间只能登录一次
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{result[0].user_id}", access_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes))
UserService.edit_user_services(query_db, EditUserModel(userId=result[0].user_id, loginDate=datetime.now(), type='status'))
logger.info('登录成功')
# 判断请求是否来自于api文档如果是返回指定格式的结果用于修复api文档认证成功后token显示undefined的bug
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
if request_from_swagger or request_from_redoc:
return {'access_token': access_token, 'token_type': 'Bearer'}
return ResponseUtil.success(
msg='登录成功',
dict_content={'token': access_token}
else:
# 此方法可实现同一账号同一时间只能登录一次
await request.app.state.redis.set(
f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{result[0].user_id}',
access_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes),
)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
await UserService.edit_user_services(
query_db, EditUserModel(userId=result[0].user_id, loginDate=datetime.now(), type='status')
)
logger.info('登录成功')
# 判断请求是否来自于api文档如果是返回指定格式的结果用于修复api文档认证成功后token显示undefined的bug
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
if request_from_swagger or request_from_redoc:
return {'access_token': access_token, 'token_type': 'Bearer'}
return ResponseUtil.success(msg='登录成功', dict_content={'token': access_token})
@loginController.get("/getInfo", response_model=CurrentUserModel)
async def get_login_user_info(request: Request, current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
logger.info('获取成功')
return ResponseUtil.success(model_content=current_user)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@loginController.get('/getInfo', response_model=CurrentUserModel)
async def get_login_user_info(
request: Request, current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
logger.info('获取成功')
return ResponseUtil.success(model_content=current_user)
@loginController.get("/getRouters")
async def get_login_user_routers(request: Request, current_user: CurrentUserModel = Depends(LoginService.get_current_user), query_db: Session = Depends(get_db)):
try:
logger.info('获取成功')
user_routers = await LoginService.get_current_user_routers(current_user.user.user_id, query_db)
return ResponseUtil.success(data=user_routers)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@loginController.get('/getRouters')
async def get_login_user_routers(
request: Request,
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
query_db: AsyncSession = Depends(get_db),
):
logger.info('获取成功')
user_routers = await LoginService.get_current_user_routers(current_user.user.user_id, query_db)
return ResponseUtil.success(data=user_routers)
@loginController.post("/register", response_model=CrudResponseModel)
async def register_user(request: Request, user_register: UserRegister, query_db: Session = Depends(get_db)):
try:
user_register_result = await LoginService.register_user_services(request, query_db, user_register)
if user_register_result.is_success:
logger.info(user_register_result.message)
return ResponseUtil.success(data=user_register_result, msg=user_register_result.message)
else:
logger.warning(user_register_result.message)
return ResponseUtil.failure(msg=user_register_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@loginController.post('/register', response_model=CrudResponseModel)
async def register_user(request: Request, user_register: UserRegister, query_db: AsyncSession = Depends(get_db)):
user_register_result = await LoginService.register_user_services(request, query_db, user_register)
logger.info(user_register_result.message)
return ResponseUtil.success(data=user_register_result, msg=user_register_result.message)
# @loginController.post("/getSmsCode", response_model=SmsCode)
# async def get_sms_code(request: Request, user: ResetUserModel, query_db: Session = Depends(get_db)):
# async def get_sms_code(request: Request, user: ResetUserModel, query_db: AsyncSession = Depends(get_db)):
# try:
# sms_result = await LoginService.get_sms_code_services(request, query_db, user)
# if sms_result.is_success:
@@ -116,7 +122,7 @@ async def register_user(request: Request, user_register: UserRegister, query_db:
#
#
# @loginController.post("/forgetPwd", response_model=CrudResponseModel)
# async def forget_user_pwd(request: Request, forget_user: ResetUserModel, query_db: Session = Depends(get_db)):
# async def forget_user_pwd(request: Request, forget_user: ResetUserModel, query_db: AsyncSession = Depends(get_db)):
# try:
# forget_user_result = await LoginService.forget_user_services(request, query_db, forget_user)
# if forget_user_result.is_success:
@@ -130,14 +136,13 @@ async def register_user(request: Request, user_register: UserRegister, query_db:
# return ResponseUtil.error(msg=str(e))
@loginController.post("/logout")
@loginController.post('/logout')
async def logout(request: Request, token: Optional[str] = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm], options={'verify_exp': False})
session_id: str = payload.get("session_id")
await LoginService.logout_services(request, session_id)
logger.info('退出成功')
return ResponseUtil.success(msg="退出成功")
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
payload = jwt.decode(
token, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm], options={'verify_exp': False}
)
session_id: str = payload.get('session_id')
await LoginService.logout_services(request, session_id)
logger.info('退出成功')
return ResponseUtil.success(msg='退出成功')

View File

@@ -1,109 +1,114 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService
from module_admin.service.menu_service import *
from utils.response_util import *
from utils.log_util import *
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.entity.vo.menu_vo import DeleteMenuModel, MenuModel, MenuQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from module_admin.service.menu_service import MenuService
from utils.log_util import logger
from utils.response_util import ResponseUtil
menuController = APIRouter(prefix='/system/menu', dependencies=[Depends(LoginService.get_current_user)])
@menuController.get("/treeselect")
async def get_system_menu_tree(request: Request, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
menu_query_result = MenuService.get_menu_tree_services(query_db, current_user)
logger.info('获取成功')
return ResponseUtil.success(data=menu_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@menuController.get('/treeselect')
async def get_system_menu_tree(
request: Request,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
menu_query_result = await MenuService.get_menu_tree_services(query_db, current_user)
logger.info('获取成功')
return ResponseUtil.success(data=menu_query_result)
@menuController.get("/roleMenuTreeselect/{role_id}")
async def get_system_role_menu_tree(request: Request, role_id: int, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
role_menu_query_result = MenuService.get_role_menu_tree_services(query_db, role_id, current_user)
logger.info('获取成功')
return ResponseUtil.success(model_content=role_menu_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@menuController.get('/roleMenuTreeselect/{role_id}')
async def get_system_role_menu_tree(
request: Request,
role_id: int,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
role_menu_query_result = await MenuService.get_role_menu_tree_services(query_db, role_id, current_user)
logger.info('获取成功')
return ResponseUtil.success(model_content=role_menu_query_result)
@menuController.get("/list", response_model=List[MenuModel], dependencies=[Depends(CheckUserInterfaceAuth('system:menu:list'))])
async def get_system_menu_list(request: Request, menu_query: MenuQueryModel = Depends(MenuQueryModel.as_query), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
menu_query_result = MenuService.get_menu_list_services(query_db, menu_query, current_user)
logger.info('获取成功')
return ResponseUtil.success(data=menu_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@menuController.get(
'/list', response_model=List[MenuModel], dependencies=[Depends(CheckUserInterfaceAuth('system:menu:list'))]
)
async def get_system_menu_list(
request: Request,
menu_query: MenuQueryModel = Depends(MenuQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
menu_query_result = await MenuService.get_menu_list_services(query_db, menu_query, current_user)
logger.info('获取成功')
return ResponseUtil.success(data=menu_query_result)
@menuController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:menu:add'))])
@log_decorator(title='菜单管理', business_type=1)
async def add_system_menu(request: Request, add_menu: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_menu.create_by = current_user.user.user_name
add_menu.update_by = current_user.user.user_name
add_menu_result = MenuService.add_menu_services(query_db, add_menu)
if add_menu_result.is_success:
logger.info(add_menu_result.message)
return ResponseUtil.success(msg=add_menu_result.message)
else:
logger.warning(add_menu_result.message)
return ResponseUtil.failure(msg=add_menu_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@menuController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:menu:add'))])
@ValidateFields(validate_model='add_menu')
@Log(title='菜单管理', business_type=BusinessType.INSERT)
async def add_system_menu(
request: Request,
add_menu: MenuModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_menu.create_by = current_user.user.user_name
add_menu.create_time = datetime.now()
add_menu.update_by = current_user.user.user_name
add_menu.update_time = datetime.now()
add_menu_result = await MenuService.add_menu_services(query_db, add_menu)
logger.info(add_menu_result.message)
return ResponseUtil.success(msg=add_menu_result.message)
@menuController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:menu:edit'))])
@log_decorator(title='菜单管理', business_type=2)
async def edit_system_menu(request: Request, edit_menu: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_menu.update_by = current_user.user.user_name
edit_menu.update_time = datetime.now()
edit_menu_result = MenuService.edit_menu_services(query_db, edit_menu)
if edit_menu_result.is_success:
logger.info(edit_menu_result.message)
return ResponseUtil.success(msg=edit_menu_result.message)
else:
logger.warning(edit_menu_result.message)
return ResponseUtil.failure(msg=edit_menu_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@menuController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:menu:edit'))])
@ValidateFields(validate_model='edit_menu')
@Log(title='菜单管理', business_type=BusinessType.UPDATE)
async def edit_system_menu(
request: Request,
edit_menu: MenuModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_menu.update_by = current_user.user.user_name
edit_menu.update_time = datetime.now()
edit_menu_result = await MenuService.edit_menu_services(query_db, edit_menu)
logger.info(edit_menu_result.message)
return ResponseUtil.success(msg=edit_menu_result.message)
@menuController.delete("/{menu_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:menu:remove'))])
@log_decorator(title='菜单管理', business_type=3)
async def delete_system_menu(request: Request, menu_ids: str, query_db: Session = Depends(get_db)):
try:
delete_menu = DeleteMenuModel(menuIds=menu_ids)
delete_menu_result = MenuService.delete_menu_services(query_db, delete_menu)
if delete_menu_result.is_success:
logger.info(delete_menu_result.message)
return ResponseUtil.success(msg=delete_menu_result.message)
else:
logger.warning(delete_menu_result.message)
return ResponseUtil.failure(msg=delete_menu_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@menuController.delete('/{menu_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:menu:remove'))])
@Log(title='菜单管理', business_type=BusinessType.DELETE)
async def delete_system_menu(request: Request, menu_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_menu = DeleteMenuModel(menuIds=menu_ids)
delete_menu_result = await MenuService.delete_menu_services(query_db, delete_menu)
logger.info(delete_menu_result.message)
return ResponseUtil.success(msg=delete_menu_result.message)
@menuController.get("/{menu_id}", response_model=MenuModel, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:query'))])
async def query_detail_system_menu(request: Request, menu_id: int, query_db: Session = Depends(get_db)):
try:
menu_detail_result = MenuService.menu_detail_services(query_db, menu_id)
logger.info(f'获取menu_id为{menu_id}的信息成功')
return ResponseUtil.success(data=menu_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@menuController.get(
'/{menu_id}', response_model=MenuModel, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:query'))]
)
async def query_detail_system_menu(request: Request, menu_id: int, query_db: AsyncSession = Depends(get_db)):
menu_detail_result = await MenuService.menu_detail_services(query_db, menu_id)
logger.info(f'获取menu_id为{menu_id}的信息成功')
return ResponseUtil.success(data=menu_detail_result)

View File

@@ -1,89 +1,89 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.notice_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.entity.vo.notice_vo import DeleteNoticeModel, NoticeModel, NoticePageQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from module_admin.service.notice_service import NoticeService
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
noticeController = APIRouter(prefix='/system/notice', dependencies=[Depends(LoginService.get_current_user)])
@noticeController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:list'))])
async def get_system_notice_list(request: Request, notice_page_query: NoticePageQueryModel = Depends(NoticePageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
notice_page_query_result = NoticeService.get_notice_list_services(query_db, notice_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=notice_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.get(
'/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:list'))]
)
async def get_system_notice_list(
request: Request,
notice_page_query: NoticePageQueryModel = Depends(NoticePageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
notice_page_query_result = await NoticeService.get_notice_list_services(query_db, notice_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=notice_page_query_result)
@noticeController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:notice:add'))])
@log_decorator(title='通知公告管理', business_type=1)
async def add_system_notice(request: Request, add_notice: NoticeModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_notice.create_by = current_user.user.user_name
add_notice.update_by = current_user.user.user_name
add_notice_result = NoticeService.add_notice_services(query_db, add_notice)
if add_notice_result.is_success:
logger.info(add_notice_result.message)
return ResponseUtil.success(msg=add_notice_result.message)
else:
logger.warning(add_notice_result.message)
return ResponseUtil.failure(msg=add_notice_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:notice:add'))])
@ValidateFields(validate_model='add_notice')
@Log(title='通知公告', business_type=BusinessType.INSERT)
async def add_system_notice(
request: Request,
add_notice: NoticeModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_notice.create_by = current_user.user.user_name
add_notice.create_time = datetime.now()
add_notice.update_by = current_user.user.user_name
add_notice.update_time = datetime.now()
add_notice_result = await NoticeService.add_notice_services(query_db, add_notice)
logger.info(add_notice_result.message)
return ResponseUtil.success(msg=add_notice_result.message)
@noticeController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:notice:edit'))])
@log_decorator(title='通知公告管理', business_type=2)
async def edit_system_notice(request: Request, edit_notice: NoticeModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_notice.update_by = current_user.user.user_name
edit_notice.update_time = datetime.now()
edit_notice_result = NoticeService.edit_notice_services(query_db, edit_notice)
if edit_notice_result.is_success:
logger.info(edit_notice_result.message)
return ResponseUtil.success(msg=edit_notice_result.message)
else:
logger.warning(edit_notice_result.message)
return ResponseUtil.failure(msg=edit_notice_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:notice:edit'))])
@ValidateFields(validate_model='edit_notice')
@Log(title='通知公告', business_type=BusinessType.UPDATE)
async def edit_system_notice(
request: Request,
edit_notice: NoticeModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_notice.update_by = current_user.user.user_name
edit_notice.update_time = datetime.now()
edit_notice_result = await NoticeService.edit_notice_services(query_db, edit_notice)
logger.info(edit_notice_result.message)
return ResponseUtil.success(msg=edit_notice_result.message)
@noticeController.delete("/{notice_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:notice:remove'))])
@log_decorator(title='通知公告管理', business_type=3)
async def delete_system_notice(request: Request, notice_ids: str, query_db: Session = Depends(get_db)):
try:
delete_notice = DeleteNoticeModel(noticeIds=notice_ids)
delete_notice_result = NoticeService.delete_notice_services(query_db, delete_notice)
if delete_notice_result.is_success:
logger.info(delete_notice_result.message)
return ResponseUtil.success(msg=delete_notice_result.message)
else:
logger.warning(delete_notice_result.message)
return ResponseUtil.failure(msg=delete_notice_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.delete('/{notice_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:notice:remove'))])
@Log(title='通知公告', business_type=BusinessType.DELETE)
async def delete_system_notice(request: Request, notice_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_notice = DeleteNoticeModel(noticeIds=notice_ids)
delete_notice_result = await NoticeService.delete_notice_services(query_db, delete_notice)
logger.info(delete_notice_result.message)
return ResponseUtil.success(msg=delete_notice_result.message)
@noticeController.get("/{notice_id}", response_model=NoticeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:query'))])
async def query_detail_system_post(request: Request, notice_id: int, query_db: Session = Depends(get_db)):
try:
notice_detail_result = NoticeService.notice_detail_services(query_db, notice_id)
logger.info(f'获取notice_id为{notice_id}的信息成功')
return ResponseUtil.success(data=notice_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.get(
'/{notice_id}', response_model=NoticeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:query'))]
)
async def query_detail_system_post(request: Request, notice_id: int, query_db: AsyncSession = Depends(get_db)):
notice_detail_result = await NoticeService.notice_detail_services(query_db, notice_id)
logger.info(f'获取notice_id为{notice_id}的信息成功')
return ResponseUtil.success(data=notice_detail_result)

View File

@@ -1,42 +1,40 @@
from fastapi import APIRouter
from fastapi import Depends
from fastapi import APIRouter, Depends, Request
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, Session
from module_admin.service.online_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.entity.vo.online_vo import DeleteOnlineModel, OnlineQueryModel
from module_admin.service.login_service import LoginService
from module_admin.service.online_service import OnlineService
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
onlineController = APIRouter(prefix='/monitor/online', dependencies=[Depends(LoginService.get_current_user)])
@onlineController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:list'))])
async def get_monitor_online_list(request: Request, online_page_query: OnlineQueryModel = Depends(OnlineQueryModel.as_query)):
try:
# 获取全量数据
online_query_result = await OnlineService.get_online_list_services(request, online_page_query)
logger.info('获取成功')
return ResponseUtil.success(model_content=PageResponseModel(rows=online_query_result, total=len(online_query_result)))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@onlineController.get(
'/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:list'))]
)
async def get_monitor_online_list(
request: Request, online_page_query: OnlineQueryModel = Depends(OnlineQueryModel.as_query)
):
# 获取全量数据
online_query_result = await OnlineService.get_online_list_services(request, online_page_query)
logger.info('获取成功')
return ResponseUtil.success(
model_content=PageResponseModel(rows=online_query_result, total=len(online_query_result))
)
@onlineController.delete("/{token_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:forceLogout'))])
@log_decorator(title='在线用户', business_type=7)
async def delete_monitor_online(request: Request, token_ids: str, query_db: Session = Depends(get_db)):
try:
delete_online = DeleteOnlineModel(tokenIds=token_ids)
delete_online_result = await OnlineService.delete_online_services(request, delete_online)
if delete_online_result.is_success:
logger.info(delete_online_result.message)
return ResponseUtil.success(msg=delete_online_result.message)
else:
logger.warning(delete_online_result.message)
return ResponseUtil.failure(msg=delete_online_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@onlineController.delete('/{token_ids}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:forceLogout'))])
@Log(title='在线用户', business_type=BusinessType.FORCE)
async def delete_monitor_online(request: Request, token_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_online = DeleteOnlineModel(tokenIds=token_ids)
delete_online_result = await OnlineService.delete_online_services(request, delete_online)
logger.info(delete_online_result.message)
return ResponseUtil.success(msg=delete_online_result.message)

View File

@@ -1,105 +1,105 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Form, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.post_service import *
from module_admin.entity.vo.post_vo import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from utils.common_util import bytes2file_response
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
from module_admin.service.login_service import LoginService
from module_admin.service.post_service import PostService
from module_admin.entity.vo.post_vo import DeletePostModel, PostModel, PostPageQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from utils.common_util import bytes2file_response
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
postController = APIRouter(prefix='/system/post', dependencies=[Depends(LoginService.get_current_user)])
@postController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:post:list'))])
async def get_system_post_list(request: Request, post_page_query: PostPageQueryModel = Depends(PostPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
# 获取分页数据
post_page_query_result = PostService.get_post_list_services(query_db, post_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=post_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@postController.get(
'/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:post:list'))]
)
async def get_system_post_list(
request: Request,
post_page_query: PostPageQueryModel = Depends(PostPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
# 获取分页数据
post_page_query_result = await PostService.get_post_list_services(query_db, post_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=post_page_query_result)
@postController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:post:add'))])
@log_decorator(title='岗位管理', business_type=1)
async def add_system_post(request: Request, add_post: PostModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_post.create_by = current_user.user.user_name
add_post.update_by = current_user.user.user_name
add_post_result = PostService.add_post_services(query_db, add_post)
if add_post_result.is_success:
logger.info(add_post_result.message)
return ResponseUtil.success(msg=add_post_result.message)
else:
logger.warning(add_post_result.message)
return ResponseUtil.failure(msg=add_post_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@postController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:post:add'))])
@ValidateFields(validate_model='add_post')
@Log(title='岗位管理', business_type=BusinessType.INSERT)
async def add_system_post(
request: Request,
add_post: PostModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_post.create_by = current_user.user.user_name
add_post.create_time = datetime.now()
add_post.update_by = current_user.user.user_name
add_post.update_time = datetime.now()
add_post_result = await PostService.add_post_services(query_db, add_post)
logger.info(add_post_result.message)
return ResponseUtil.success(msg=add_post_result.message)
@postController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:post:edit'))])
@log_decorator(title='岗位管理', business_type=2)
async def edit_system_post(request: Request, edit_post: PostModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_post.update_by = current_user.user.user_name
edit_post.update_time = datetime.now()
edit_post_result = PostService.edit_post_services(query_db, edit_post)
if edit_post_result.is_success:
logger.info(edit_post_result.message)
return ResponseUtil.success(msg=edit_post_result.message)
else:
logger.warning(edit_post_result.message)
return ResponseUtil.failure(msg=edit_post_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@postController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:post:edit'))])
@ValidateFields(validate_model='edit_post')
@Log(title='岗位管理', business_type=BusinessType.UPDATE)
async def edit_system_post(
request: Request,
edit_post: PostModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
edit_post.update_by = current_user.user.user_name
edit_post.update_time = datetime.now()
edit_post_result = await PostService.edit_post_services(query_db, edit_post)
logger.info(edit_post_result.message)
return ResponseUtil.success(msg=edit_post_result.message)
@postController.delete("/{post_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:post:remove'))])
@log_decorator(title='岗位管理', business_type=3)
async def delete_system_post(request: Request, post_ids: str, query_db: Session = Depends(get_db)):
try:
delete_post = DeletePostModel(postIds=post_ids)
delete_post_result = PostService.delete_post_services(query_db, delete_post)
if delete_post_result.is_success:
logger.info(delete_post_result.message)
return ResponseUtil.success(msg=delete_post_result.message)
else:
logger.warning(delete_post_result.message)
return ResponseUtil.failure(msg=delete_post_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@postController.delete('/{post_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:post:remove'))])
@Log(title='岗位管理', business_type=BusinessType.DELETE)
async def delete_system_post(request: Request, post_ids: str, query_db: AsyncSession = Depends(get_db)):
delete_post = DeletePostModel(postIds=post_ids)
delete_post_result = await PostService.delete_post_services(query_db, delete_post)
logger.info(delete_post_result.message)
return ResponseUtil.success(msg=delete_post_result.message)
@postController.get("/{post_id}", response_model=PostModel, dependencies=[Depends(CheckUserInterfaceAuth('system:post:query'))])
async def query_detail_system_post(request: Request, post_id: int, query_db: Session = Depends(get_db)):
try:
post_detail_result = PostService.post_detail_services(query_db, post_id)
logger.info(f'获取post_id为{post_id}的信息成功')
return ResponseUtil.success(data=post_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@postController.get(
'/{post_id}', response_model=PostModel, dependencies=[Depends(CheckUserInterfaceAuth('system:post:query'))]
)
async def query_detail_system_post(request: Request, post_id: int, query_db: AsyncSession = Depends(get_db)):
post_detail_result = await PostService.post_detail_services(query_db, post_id)
logger.info(f'获取post_id为{post_id}的信息成功')
return ResponseUtil.success(data=post_detail_result)
@postController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:post:export'))])
@log_decorator(title='岗位管理', business_type=5)
async def export_system_post_list(request: Request, post_page_query: PostPageQueryModel = Depends(PostPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
# 获取全量数据
post_query_result = PostService.get_post_list_services(query_db, post_page_query, is_page=False)
post_export_result = PostService.export_post_list_services(post_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(post_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@postController.post('/export', dependencies=[Depends(CheckUserInterfaceAuth('system:post:export'))])
@Log(title='岗位管理', business_type=BusinessType.EXPORT)
async def export_system_post_list(
request: Request,
post_page_query: PostPageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
):
# 获取全量数据
post_query_result = await PostService.get_post_list_services(query_db, post_page_query, is_page=False)
post_export_result = await PostService.export_post_list_services(post_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(post_export_result))

View File

@@ -1,230 +1,283 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from datetime import datetime
from fastapi import APIRouter, Depends, Form, Request
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.role_service import *
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 PageResponseModel
from utils.common_util import bytes2file_response
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.data_scope import GetDataScope
from module_admin.annotation.log_annotation import log_decorator
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.entity.vo.dept_vo import DeptModel
from module_admin.entity.vo.role_vo import AddRoleModel, DeleteRoleModel, RoleModel, RolePageQueryModel
from module_admin.entity.vo.user_vo import CrudUserRoleModel, CurrentUserModel, UserRolePageQueryModel
from module_admin.service.dept_service import DeptService
from module_admin.service.login_service import LoginService
from module_admin.service.role_service import RoleService
from module_admin.service.user_service import UserService
from utils.common_util import bytes2file_response
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
roleController = APIRouter(prefix='/system/role', dependencies=[Depends(LoginService.get_current_user)])
@roleController.get("/deptTree/{role_id}", dependencies=[Depends(CheckUserInterfaceAuth('system:role:query'))])
async def get_system_role_dept_tree(request: Request, role_id: int, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))):
try:
dept_query_result = DeptService.get_dept_tree_services(query_db, DeptModel(**{}), data_scope_sql)
role_dept_query_result = RoleService.get_role_dept_tree_services(query_db, role_id)
role_dept_query_result.depts = dept_query_result
logger.info('获取成功')
return ResponseUtil.success(model_content=role_dept_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@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_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:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:role:add'))])
@log_decorator(title='角色管理', business_type=1)
async def add_system_role(request: Request, add_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_role.create_by = current_user.user.user_name
add_role.update_by = current_user.user.user_name
add_role_result = RoleService.add_role_services(query_db, add_role)
if add_role_result.is_success:
logger.info(add_role_result.message)
return ResponseUtil.success(msg=add_role_result.message)
else:
logger.warning(add_role_result.message)
return ResponseUtil.failure(msg=add_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=2)
async def edit_system_role(request: Request, edit_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_role.update_by = current_user.user.user_name
edit_role.update_time = datetime.now()
edit_role_result = RoleService.edit_role_services(query_db, edit_role)
if edit_role_result.is_success:
logger.info(edit_role_result.message)
return ResponseUtil.success(msg=edit_role_result.message)
else:
logger.warning(edit_role_result.message)
return ResponseUtil.failure(msg=edit_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.get('/deptTree/{role_id}', dependencies=[Depends(CheckUserInterfaceAuth('system:role:query'))])
async def get_system_role_dept_tree(
request: Request,
role_id: int,
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)
role_dept_query_result = await RoleService.get_role_dept_tree_services(query_db, role_id)
role_dept_query_result.depts = dept_query_result
logger.info('获取成功')
return ResponseUtil.success(model_content=role_dept_query_result)
@roleController.put("/dataScope", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def edit_system_role_datascope(request: Request, role_data_scope: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
role_data_scope.update_by = current_user.user.user_name
role_data_scope.update_time = datetime.now()
role_data_scope_result = RoleService.role_datascope_services(query_db, role_data_scope)
if role_data_scope_result.is_success:
logger.info(role_data_scope_result.message)
return ResponseUtil.success(msg=role_data_scope_result.message)
else:
logger.warning(role_data_scope_result.message)
return ResponseUtil.failure(msg=role_data_scope_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.delete("/{role_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:role:remove'))])
@log_decorator(title='角色管理', business_type=3)
async def delete_system_role(request: Request, role_ids: str, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
delete_role = DeleteRoleModel(
roleIds=role_ids,
updateBy=current_user.user.user_name,
updateTime=datetime.now()
)
delete_role_result = RoleService.delete_role_services(query_db, delete_role)
if delete_role_result.is_success:
logger.info(delete_role_result.message)
return ResponseUtil.success(msg=delete_role_result.message)
else:
logger.warning(delete_role_result.message)
return ResponseUtil.failure(msg=delete_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.get("/{role_id}", response_model=RoleModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:query'))])
async def query_detail_system_role(request: Request, role_id: int, query_db: Session = Depends(get_db)):
try:
role_detail_result = RoleService.role_detail_services(query_db, role_id)
logger.info(f'获取role_id为{role_id}的信息成功')
return ResponseUtil.success(data=role_detail_result.model_dump(by_alias=True))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@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: AsyncSession = Depends(get_db),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
role_page_query_result = await RoleService.get_role_list_services(
query_db, role_page_query, data_scope_sql, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=role_page_query_result)
@roleController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:role:export'))])
@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_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))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:role:add'))])
@ValidateFields(validate_model='add_role')
@Log(title='角色管理', business_type=BusinessType.INSERT)
async def add_system_role(
request: Request,
add_role: AddRoleModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
add_role.create_by = current_user.user.user_name
add_role.create_time = datetime.now()
add_role.update_by = current_user.user.user_name
add_role.update_time = datetime.now()
add_role_result = await RoleService.add_role_services(query_db, add_role)
logger.info(add_role_result.message)
return ResponseUtil.success(msg=add_role_result.message)
@roleController.put("/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=2)
async def reset_system_role_status(request: Request, edit_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_role.update_by = current_user.user.user_name
edit_role.update_time = datetime.now()
edit_role.type = 'status'
edit_role_result = RoleService.edit_role_services(query_db, edit_role)
if edit_role_result.is_success:
logger.info(edit_role_result.message)
return ResponseUtil.success(msg=edit_role_result.message)
else:
logger.warning(edit_role_result.message)
return ResponseUtil.failure(msg=edit_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@ValidateFields(validate_model='edit_role')
@Log(title='角色管理', business_type=BusinessType.UPDATE)
async def edit_system_role(
request: Request,
edit_role: AddRoleModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
await RoleService.check_role_allowed_services(edit_role)
if not current_user.user.admin:
await RoleService.check_role_data_scope_services(query_db, str(edit_role.role_id), data_scope_sql)
edit_role.update_by = current_user.user.user_name
edit_role.update_time = datetime.now()
edit_role_result = await RoleService.edit_role_services(query_db, edit_role)
logger.info(edit_role_result.message)
return ResponseUtil.success(msg=edit_role_result.message)
@roleController.get("/authUser/allocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))])
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_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:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put('/dataScope', dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@Log(title='角色管理', business_type=BusinessType.GRANT)
async def edit_system_role_datascope(
request: Request,
role_data_scope: AddRoleModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
await RoleService.check_role_allowed_services(role_data_scope)
if not current_user.user.admin:
await RoleService.check_role_data_scope_services(query_db, str(role_data_scope.role_id), data_scope_sql)
edit_role = AddRoleModel(
roleId=role_data_scope.role_id,
dataScope=role_data_scope.data_scope,
deptIds=role_data_scope.dept_ids,
deptCheckStrictly=role_data_scope.dept_check_strictly,
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
)
role_data_scope_result = await RoleService.role_datascope_services(query_db, edit_role)
logger.info(role_data_scope_result.message)
return ResponseUtil.success(msg=role_data_scope_result.message)
@roleController.get("/authUser/unallocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))])
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_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:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.delete('/{role_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:role:remove'))])
@Log(title='角色管理', business_type=BusinessType.DELETE)
async def delete_system_role(
request: Request,
role_ids: str,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
role_id_list = role_ids.split(',') if role_ids else []
if role_id_list:
for role_id in role_id_list:
await RoleService.check_role_allowed_services(RoleModel(roleId=int(role_id)))
if not current_user.user.admin:
await RoleService.check_role_data_scope_services(query_db, role_id, data_scope_sql)
delete_role = DeleteRoleModel(roleIds=role_ids, updateBy=current_user.user.user_name, updateTime=datetime.now())
delete_role_result = await RoleService.delete_role_services(query_db, delete_role)
logger.info(delete_role_result.message)
return ResponseUtil.success(msg=delete_role_result.message)
@roleController.put("/authUser/selectAll", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def add_system_role_user(request: Request, add_role_user: CrudUserRoleModel = Depends(CrudUserRoleModel.as_query), query_db: Session = Depends(get_db)):
try:
add_role_user_result = UserService.add_user_role_services(query_db, add_role_user)
if add_role_user_result.is_success:
logger.info(add_role_user_result.message)
return ResponseUtil.success(msg=add_role_user_result.message)
else:
logger.warning(add_role_user_result.message)
return ResponseUtil.failure(msg=add_role_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.get(
'/{role_id}', response_model=RoleModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:query'))]
)
async def query_detail_system_role(
request: Request,
role_id: int,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
if not current_user.user.admin:
await RoleService.check_role_data_scope_services(query_db, str(role_id), data_scope_sql)
role_detail_result = await RoleService.role_detail_services(query_db, role_id)
logger.info(f'获取role_id为{role_id}的信息成功')
return ResponseUtil.success(data=role_detail_result.model_dump(by_alias=True))
@roleController.put("/authUser/cancel", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def cancel_system_role_user(request: Request, cancel_user_role: CrudUserRoleModel, query_db: Session = Depends(get_db)):
try:
cancel_user_role_result = UserService.delete_user_role_services(query_db, cancel_user_role)
if cancel_user_role_result.is_success:
logger.info(cancel_user_role_result.message)
return ResponseUtil.success(msg=cancel_user_role_result.message)
else:
logger.warning(cancel_user_role_result.message)
return ResponseUtil.failure(msg=cancel_user_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.post('/export', dependencies=[Depends(CheckUserInterfaceAuth('system:role:export'))])
@Log(title='角色管理', business_type=BusinessType.EXPORT)
async def export_system_role_list(
request: Request,
role_page_query: RolePageQueryModel = Form(),
query_db: AsyncSession = Depends(get_db),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
# 获取全量数据
role_query_result = await RoleService.get_role_list_services(
query_db, role_page_query, data_scope_sql, is_page=False
)
role_export_result = await RoleService.export_role_list_services(role_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(role_export_result))
@roleController.put("/authUser/cancelAll", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def batch_cancel_system_role_user(request: Request, batch_cancel_user_role: CrudUserRoleModel = Depends(CrudUserRoleModel.as_query), query_db: Session = Depends(get_db)):
try:
batch_cancel_user_role_result = UserService.delete_user_role_services(query_db, batch_cancel_user_role)
if batch_cancel_user_role_result.is_success:
logger.info(batch_cancel_user_role_result.message)
return ResponseUtil.success(msg=batch_cancel_user_role_result.message)
else:
logger.warning(batch_cancel_user_role_result.message)
return ResponseUtil.failure(msg=batch_cancel_user_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put('/changeStatus', dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@Log(title='角色管理', business_type=BusinessType.UPDATE)
async def reset_system_role_status(
request: Request,
change_role: AddRoleModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
await RoleService.check_role_allowed_services(change_role)
if not current_user.user.admin:
await RoleService.check_role_data_scope_services(query_db, str(change_role.role_id), data_scope_sql)
edit_role = AddRoleModel(
roleId=change_role.role_id,
status=change_role.status,
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
type='status',
)
edit_role_result = await RoleService.edit_role_services(query_db, edit_role)
logger.info(edit_role_result.message)
return ResponseUtil.success(msg=edit_role_result.message)
@roleController.get(
'/authUser/allocatedList',
response_model=PageResponseModel,
dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))],
)
async def get_system_allocated_user_list(
request: Request,
user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
data_scope_sql: str = Depends(GetDataScope('SysUser')),
):
role_user_allocated_page_query_result = await RoleService.get_role_user_allocated_list_services(
query_db, user_role, data_scope_sql, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=role_user_allocated_page_query_result)
@roleController.get(
'/authUser/unallocatedList',
response_model=PageResponseModel,
dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))],
)
async def get_system_unallocated_user_list(
request: Request,
user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
data_scope_sql: str = Depends(GetDataScope('SysUser')),
):
role_user_unallocated_page_query_result = await RoleService.get_role_user_unallocated_list_services(
query_db, user_role, data_scope_sql, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=role_user_unallocated_page_query_result)
@roleController.put('/authUser/selectAll', dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@Log(title='角色管理', business_type=BusinessType.GRANT)
async def add_system_role_user(
request: Request,
add_role_user: CrudUserRoleModel = Depends(CrudUserRoleModel.as_query),
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
data_scope_sql: str = Depends(GetDataScope('SysDept')),
):
if not current_user.user.admin:
await RoleService.check_role_data_scope_services(query_db, str(add_role_user.role_id), data_scope_sql)
add_role_user_result = await UserService.add_user_role_services(query_db, add_role_user)
logger.info(add_role_user_result.message)
return ResponseUtil.success(msg=add_role_user_result.message)
@roleController.put('/authUser/cancel', dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@Log(title='角色管理', business_type=BusinessType.GRANT)
async def cancel_system_role_user(
request: Request, cancel_user_role: CrudUserRoleModel, query_db: AsyncSession = Depends(get_db)
):
cancel_user_role_result = await UserService.delete_user_role_services(query_db, cancel_user_role)
logger.info(cancel_user_role_result.message)
return ResponseUtil.success(msg=cancel_user_role_result.message)
@roleController.put('/authUser/cancelAll', dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@Log(title='角色管理', business_type=BusinessType.GRANT)
async def batch_cancel_system_role_user(
request: Request,
batch_cancel_user_role: CrudUserRoleModel = Depends(CrudUserRoleModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
batch_cancel_user_role_result = await UserService.delete_user_role_services(query_db, batch_cancel_user_role)
logger.info(batch_cancel_user_role_result.message)
return ResponseUtil.success(msg=batch_cancel_user_role_result.message)

View File

@@ -1,22 +1,21 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from module_admin.service.login_service import LoginService
from module_admin.service.server_service import *
from utils.response_util import *
from utils.log_util import *
from fastapi import APIRouter, Depends, Request
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.entity.vo.server_vo import ServerMonitorModel
from module_admin.service.login_service import LoginService
from module_admin.service.server_service import ServerService
from utils.response_util import ResponseUtil
from utils.log_util import logger
serverController = APIRouter(prefix='/monitor/server', dependencies=[Depends(LoginService.get_current_user)])
@serverController.get("", response_model=ServerMonitorModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:server:list'))])
@serverController.get(
'', response_model=ServerMonitorModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:server:list'))]
)
async def get_monitor_server_info(request: Request):
try:
# 获取全量数据
server_info_query_result = ServerService.get_server_monitor_info()
logger.info('获取成功')
return ResponseUtil.success(data=server_info_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
# 获取全量数据
server_info_query_result = await ServerService.get_server_monitor_info()
logger.info('获取成功')
return ResponseUtil.success(data=server_info_query_result)

View File

@@ -1,171 +1,250 @@
from fastapi import APIRouter, Request
from fastapi import Depends, File, Query
import os
from datetime import datetime
from fastapi import APIRouter, Depends, File, Form, Query, Request, UploadFile
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Literal, Optional, Union
from pydantic_validation_decorator import ValidateFields
from config.get_db import get_db
from config.enums import BusinessType
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 PageResponseModel
from utils.response_util import *
from utils.log_util import *
from utils.common_util import bytes2file_response
from utils.upload_util import UploadUtil
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import Log
from module_admin.aspect.data_scope import GetDataScope
from module_admin.annotation.log_annotation import log_decorator
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 UserService
from module_admin.service.role_service import RoleService
from module_admin.service.dept_service import DeptService
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: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))):
try:
dept_query_result = DeptService.get_dept_tree_services(query_db, DeptModel(**{}), data_scope_sql)
logger.info('获取成功')
return ResponseUtil.success(data=dept_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@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: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))):
try:
# 获取分页数据
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:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@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
)
logger.info('获取成功')
return ResponseUtil.success(model_content=user_page_query_result)
@userController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:user:add'))])
@log_decorator(title='用户管理', business_type=1)
async def add_system_user(request: Request, add_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_user.password = PwdUtil.get_password_hash(add_user.password)
add_user.create_by = current_user.user.user_name
add_user.update_by = current_user.user.user_name
add_user_result = UserService.add_user_services(query_db, add_user)
if add_user_result.is_success:
logger.info(add_user_result.message)
return ResponseUtil.success(msg=add_user_result.message)
else:
logger.warning(add_user_result.message)
return ResponseUtil.failure(msg=add_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
@log_decorator(title='用户管理', business_type=2)
async def edit_system_user(request: Request, edit_user: EditUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.delete("/{user_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:user:remove'))])
@log_decorator(title='用户管理', business_type=3)
async def delete_system_user(request: Request, user_ids: str, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
delete_user = DeleteUserModel(
userIds=user_ids,
updateBy=current_user.user.user_name,
updateTime=datetime.now()
@userController.post('', dependencies=[Depends(CheckUserInterfaceAuth('system:user:add'))])
@ValidateFields(validate_model='add_user')
@Log(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')),
):
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([str(item) for item in add_user.role_ids]), role_data_scope_sql
)
delete_user_result = UserService.delete_user_services(query_db, delete_user)
if delete_user_result.is_success:
logger.info(delete_user_result.message)
return ResponseUtil.success(msg=delete_user_result.message)
else:
logger.warning(delete_user_result.message)
return ResponseUtil.failure(msg=delete_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
add_user.password = PwdUtil.get_password_hash(add_user.password)
add_user.create_by = current_user.user.user_name
add_user.create_time = datetime.now()
add_user.update_by = current_user.user.user_name
add_user.update_time = datetime.now()
add_user_result = await UserService.add_user_services(query_db, add_user)
logger.info(add_user_result.message)
return ResponseUtil.success(msg=add_user_result.message)
@userController.put("/resetPwd", dependencies=[Depends(CheckUserInterfaceAuth('system:user:resetPwd'))])
@log_decorator(title='用户管理', business_type=2)
async def reset_system_user_pwd(request: Request, edit_user: EditUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user.password = PwdUtil.get_password_hash(edit_user.password)
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
edit_user.type = 'pwd'
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put('', dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
@ValidateFields(validate_model='edit_user')
@Log(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')),
):
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)
await DeptService.check_dept_data_scope_services(query_db, edit_user.dept_id, dept_data_scope_sql)
await RoleService.check_role_data_scope_services(
query_db, ','.join([str(item) for item in edit_user.role_ids]), role_data_scope_sql
)
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
edit_user_result = await UserService.edit_user_services(query_db, edit_user)
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
@userController.put("/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
@log_decorator(title='用户管理', business_type=2)
async def change_system_user_status(request: Request, edit_user: EditUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
edit_user.type = 'status'
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.delete('/{user_ids}', dependencies=[Depends(CheckUserInterfaceAuth('system:user:remove'))])
@Log(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')),
):
user_id_list = user_ids.split(',') if user_ids else []
if user_id_list:
if current_user.user.user_id in user_id_list:
logger.warning('当前登录用户不能删除')
return ResponseUtil.failure(msg='当前登录用户不能删除')
for user_id in user_id_list:
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_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.get("/profile", response_model=UserProfileModel)
async def query_detail_system_user(request: Request, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
profile_user_result = 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)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put('/resetPwd', dependencies=[Depends(CheckUserInterfaceAuth('system:user:resetPwd'))])
@Log(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')),
):
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)
edit_user = EditUserModel(
userId=reset_user.user_id,
password=PwdUtil.get_password_hash(reset_user.password),
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
type='pwd',
)
edit_user_result = await UserService.edit_user_services(query_db, edit_user)
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
@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: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
detail_user_result = UserService.user_detail_services(query_db, user_id)
logger.info(f'获取user_id为{user_id}的信息成功')
return ResponseUtil.success(model_content=detail_user_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put('/changeStatus', dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
@Log(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')),
):
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)
edit_user = EditUserModel(
userId=change_user.user_id,
status=change_user.status,
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
type='status',
)
edit_user_result = await UserService.edit_user_services(query_db, edit_user)
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
@userController.post("/profile/avatar")
@log_decorator(title='个人信息', business_type=2)
async def change_system_user_profile_avatar(request: Request, avatarfile: bytes = File(), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
relative_path = f'avatar/{datetime.now().strftime("%Y")}/{datetime.now().strftime("%m")}/{datetime.now().strftime("%d")}'
@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, Literal['']]] = '',
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)
logger.info(f'获取user_id为{user_id}的信息成功')
return ResponseUtil.success(model_content=detail_user_result)
@userController.post('/profile/avatar')
@Log(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),
):
if avatarfile:
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)
@@ -180,127 +259,141 @@ 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 = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(dict_content={'imgUrl': edit_user.avatar}, msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
edit_user_result = await UserService.edit_user_services(query_db, edit_user)
logger.info(edit_user_result.message)
return ResponseUtil.success(dict_content={'imgUrl': edit_user.avatar}, msg=edit_user_result.message)
return ResponseUtil.failure(msg='上传图片异常,请联系管理员')
@userController.put("/profile")
@log_decorator(title='个人信息', business_type=2)
async def change_system_user_profile_info(request: Request, user_info: UserInfoModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user = EditUserModel(**user_info.model_dump(by_alias=True, exclude={'role_ids', 'post_ids'}), roleIds=user_info.role_ids.split(','), postIds=user_info.post_ids.split(','))
edit_user.user_id = current_user.user.user_id
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
print(edit_user.model_dump())
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put('/profile')
@Log(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),
):
edit_user = EditUserModel(
**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,
)
edit_user_result = await UserService.edit_user_services(query_db, edit_user)
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
@userController.put("/profile/updatePwd")
@log_decorator(title='个人信息', business_type=2)
async def reset_system_user_password(request: Request, old_password: str = Query(alias='oldPassword'), new_password: str = Query(alias='newPassword'), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
reset_user = ResetUserModel(
userId=current_user.user.user_id,
oldPassword=old_password,
password=PwdUtil.get_password_hash(new_password),
updateBy=current_user.user.user_name,
updateTime=datetime.now()
)
reset_user_result = UserService.reset_user_services(query_db, reset_user)
if reset_user_result.is_success:
logger.info(reset_user_result.message)
return ResponseUtil.success(msg=reset_user_result.message)
else:
logger.warning(reset_user_result.message)
return ResponseUtil.failure(msg=reset_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put('/profile/updatePwd')
@Log(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),
):
reset_user = ResetUserModel(
userId=current_user.user.user_id,
oldPassword=reset_password.old_password,
password=reset_password.new_password,
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
)
reset_user_result = await UserService.reset_user_services(query_db, reset_user)
logger.info(reset_user_result.message)
return ResponseUtil.success(msg=reset_user_result.message)
@userController.post("/importData", dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))])
@log_decorator(title='用户管理', business_type=6)
async def batch_import_system_user(request: Request, file: UploadFile = File(...), update_support: bool = Query(alias='updateSupport'), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
batch_import_result = await UserService.batch_import_user_services(query_db, file, update_support, current_user)
if batch_import_result.is_success:
logger.info(batch_import_result.message)
return ResponseUtil.success(msg=batch_import_result.message)
else:
logger.warning(batch_import_result.message)
return ResponseUtil.failure(msg=batch_import_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.post('/importData', dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))])
@Log(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
)
logger.info(batch_import_result.message)
return ResponseUtil.success(msg=batch_import_result.message)
@userController.post("/importTemplate", dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))])
async def export_system_user_template(request: Request, query_db: Session = Depends(get_db)):
try:
user_import_template_result = UserService.get_user_import_template_services()
logger.info('获取成功')
return ResponseUtil.streaming(data=bytes2file_response(user_import_template_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@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('获取成功')
return ResponseUtil.streaming(data=bytes2file_response(user_import_template_result))
@userController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:user:export'))])
@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_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))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.post('/export', dependencies=[Depends(CheckUserInterfaceAuth('system:user:export'))])
@Log(title='用户管理', business_type=BusinessType.EXPORT)
async def export_system_user_list(
request: Request,
user_page_query: UserPageQueryModel = 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_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'))])
async def get_system_allocated_role_list(request: Request, user_id: int, query_db: Session = Depends(get_db)):
try:
user_role_query = UserRoleQueryModel(userId=user_id)
user_role_allocated_query_result = UserService.get_user_role_allocated_list_services(query_db, user_role_query)
logger.info('获取成功')
return ResponseUtil.success(model_content=user_role_allocated_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@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
)
logger.info('获取成功')
return ResponseUtil.success(model_content=user_role_allocated_query_result)
@userController.put("/authRole", response_model=UserRoleResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
async def update_system_role_user(request: Request, user_id: int = Query(alias='userId'), role_ids: str = Query(alias='roleIds'), query_db: Session = Depends(get_db)):
try:
add_user_role_result = UserService.add_user_role_services(query_db, CrudUserRoleModel(userId=user_id, roleIds=role_ids))
if add_user_role_result.is_success:
logger.info(add_user_role_result.message)
return ResponseUtil.success(msg=add_user_role_result.message)
else:
logger.warning(add_user_role_result.message)
return ResponseUtil.failure(msg=add_user_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put(
'/authRole',
response_model=UserRoleResponseModel,
dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))],
)
@Log(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')),
):
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)
)
logger.info(add_user_role_result.message)
return ResponseUtil.success(msg=add_user_role_result.message)

View File

@@ -1,8 +1,9 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.config_do import SysConfig
from module_admin.entity.vo.config_vo import *
from utils.page_util import PageUtil
from datetime import datetime, time
from sqlalchemy import delete, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.config_do import SysConfig
from module_admin.entity.vo.config_vo import ConfigModel, ConfigPageQueryModel
from utils.page_util import PageUtil
class ConfigDao:
@@ -11,91 +12,105 @@ class ConfigDao:
"""
@classmethod
def get_config_detail_by_id(cls, db: Session, config_id: int):
async def get_config_detail_by_id(cls, db: AsyncSession, config_id: int):
"""
根据参数配置id获取参数配置详细信息
:param db: orm对象
:param config_id: 参数配置id
:return: 参数配置信息对象
"""
config_info = db.query(SysConfig) \
.filter(SysConfig.config_id == config_id) \
.first()
config_info = (await db.execute(select(SysConfig).where(SysConfig.config_id == config_id))).scalars().first()
return config_info
@classmethod
def get_config_detail_by_info(cls, db: Session, config: ConfigModel):
async def get_config_detail_by_info(cls, db: AsyncSession, config: ConfigModel):
"""
根据参数配置参数获取参数配置信息
:param db: orm对象
:param config: 参数配置参数对象
:return: 参数配置信息对象
"""
config_info = db.query(SysConfig) \
.filter(SysConfig.config_key == config.config_key if config.config_key else True,
SysConfig.config_value == config.config_value if config.config_value else True) \
config_info = (
(
await db.execute(
select(SysConfig).where(
SysConfig.config_key == config.config_key if config.config_key else True,
SysConfig.config_value == config.config_value if config.config_value else True,
)
)
)
.scalars()
.first()
)
return config_info
@classmethod
def get_config_list(cls, db: Session, query_object: ConfigPageQueryModel, is_page: bool = False):
async def get_config_list(cls, db: AsyncSession, query_object: ConfigPageQueryModel, is_page: bool = False):
"""
根据查询参数获取参数配置列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 参数配置列表信息对象
"""
query = db.query(SysConfig) \
.filter(SysConfig.config_name.like(f'%{query_object.config_name}%') if query_object.config_name else True,
SysConfig.config_key.like(f'%{query_object.config_key}%') if query_object.config_key else True,
SysConfig.config_type == query_object.config_type if query_object.config_type else True,
SysConfig.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
) \
query = (
select(SysConfig)
.where(
SysConfig.config_name.like(f'%{query_object.config_name}%') if query_object.config_name else True,
SysConfig.config_key.like(f'%{query_object.config_key}%') if query_object.config_key else True,
SysConfig.config_type == query_object.config_type if query_object.config_type else True,
SysConfig.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,
)
.order_by(SysConfig.config_id)
.distinct()
config_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
config_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return config_list
@classmethod
def add_config_dao(cls, db: Session, config: ConfigModel):
async def add_config_dao(cls, db: AsyncSession, config: ConfigModel):
"""
新增参数配置数据库操作
:param db: orm对象
:param config: 参数配置对象
:return:
"""
db_config = SysConfig(**config.model_dump())
db.add(db_config)
db.flush()
await db.flush()
return db_config
@classmethod
def edit_config_dao(cls, db: Session, config: dict):
async def edit_config_dao(cls, db: AsyncSession, config: dict):
"""
编辑参数配置数据库操作
:param db: orm对象
:param config: 需要更新的参数配置字典
:return:
"""
db.query(SysConfig) \
.filter(SysConfig.config_id == config.get('config_id')) \
.update(config)
await db.execute(update(SysConfig), [config])
@classmethod
def delete_config_dao(cls, db: Session, config: ConfigModel):
async def delete_config_dao(cls, db: AsyncSession, config: ConfigModel):
"""
删除参数配置数据库操作
:param db: orm对象
:param config: 参数配置对象
:return:
"""
db.query(SysConfig) \
.filter(SysConfig.config_id == config.config_id) \
.delete()
await db.execute(delete(SysConfig).where(SysConfig.config_id.in_([config.config_id])))

View File

@@ -1,8 +1,11 @@
from sqlalchemy.orm import Session
from sqlalchemy import bindparam, func, or_, select, update # noqa: F401
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.util import immutabledict
from typing import List
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.do.role_do import SysRoleDept
from module_admin.entity.vo.dept_vo import *
from utils.time_format_util import list_format_datetime
from module_admin.entity.do.role_do import SysRoleDept # noqa: F401
from module_admin.entity.do.user_do import SysUser
from module_admin.entity.vo.dept_vo import DeptModel
class DeptDao:
@@ -11,185 +14,294 @@ class DeptDao:
"""
@classmethod
def get_dept_by_id(cls, db: Session, dept_id: int):
async def get_dept_by_id(cls, db: AsyncSession, dept_id: int):
"""
根据部门id获取在用部门信息
:param db: orm对象
:param dept_id: 部门id
:return: 在用部门信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.status == 0,
SysDept.del_flag == 0) \
.first()
dept_info = (await db.execute(select(SysDept).where(SysDept.dept_id == dept_id))).scalars().first()
return dept_info
@classmethod
def get_dept_by_id_for_list(cls, db: Session, dept_id: int):
"""
用于获取部门列表的工具方法
:param db: orm对象
:param dept_id: 部门id
:return: 部门id对应的信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.del_flag == 0) \
.first()
return dept_info
@classmethod
def get_dept_detail_by_id(cls, db: Session, dept_id: int):
async def get_dept_detail_by_id(cls, db: AsyncSession, dept_id: int):
"""
根据部门id获取部门详细信息
:param db: orm对象
:param dept_id: 部门id
:return: 部门信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.del_flag == 0) \
dept_info = (
(await db.execute(select(SysDept).where(SysDept.dept_id == dept_id, SysDept.del_flag == '0')))
.scalars()
.first()
)
return dept_info
@classmethod
def get_dept_detail_by_info(cls, db: Session, dept: DeptModel):
async def get_dept_detail_by_info(cls, db: AsyncSession, dept: DeptModel):
"""
根据部门参数获取部门信息
:param db: orm对象
:param dept: 部门参数对象
:return: 部门信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.parent_id == dept.parent_id if dept.parent_id else True,
SysDept.dept_name == dept.dept_name if dept.dept_name else True) \
dept_info = (
(
await db.execute(
select(SysDept).where(
SysDept.parent_id == dept.parent_id if dept.parent_id else True,
SysDept.dept_name == dept.dept_name if dept.dept_name else True,
)
)
)
.scalars()
.first()
)
return dept_info
@classmethod
def get_dept_info_for_edit_option(cls, db: Session, dept_info: DeptModel, data_scope_sql: str):
async def get_dept_info_for_edit_option(cls, db: AsyncSession, dept_info: DeptModel, data_scope_sql: str):
"""
获取部门编辑对应的在用部门列表信息
:param db: orm对象
:param dept_info: 部门对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门列表信息
"""
dept_result = db.query(SysDept) \
.filter(SysDept.dept_id != dept_info.dept_id,
SysDept.parent_id != dept_info.dept_id,
SysDept.del_flag == 0, SysDept.status == 0,
eval(data_scope_sql)) \
.order_by(SysDept.order_num) \
.distinct().all()
dept_result = (
(
await db.execute(
select(SysDept)
.where(
SysDept.dept_id != dept_info.dept_id,
~SysDept.dept_id.in_(
select(SysDept.dept_id).where(func.find_in_set(dept_info.dept_id, SysDept.ancestors))
),
SysDept.del_flag == '0',
SysDept.status == '0',
eval(data_scope_sql),
)
.order_by(SysDept.order_num)
.distinct()
)
)
.scalars()
.all()
)
return list_format_datetime(dept_result)
return dept_result
@classmethod
def get_children_dept(cls, db: Session, dept_id: int):
async def get_children_dept_dao(cls, db: AsyncSession, dept_id: int):
"""
根据部门id查询当前部门的子部门列表信息
:param db: orm对象
:param dept_id: 部门id
:return: 子部门信息列表
"""
dept_result = db.query(SysDept) \
.filter(SysDept.parent_id == dept_id,
SysDept.del_flag == 0) \
.all()
dept_result = (
(await db.execute(select(SysDept).where(func.find_in_set(dept_id, SysDept.ancestors)))).scalars().all()
)
return list_format_datetime(dept_result)
return dept_result
@classmethod
def get_dept_all_ancestors(cls, db: Session):
"""
获取所有部门的ancestors信息
:param db: orm对象
:return: ancestors信息列表
"""
ancestors = db.query(SysDept.ancestors)\
.filter(SysDept.del_flag == 0)\
.all()
return ancestors
@classmethod
def get_dept_list_for_tree(cls, db: Session, dept_info: DeptModel, data_scope_sql: str):
async def get_dept_list_for_tree(cls, db: AsyncSession, dept_info: DeptModel, data_scope_sql: str):
"""
获取所有在用部门列表信息
:param db: orm对象
:param dept_info: 部门对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 在用部门列表信息
"""
dept_result = db.query(SysDept) \
.filter(SysDept.status == 0,
SysDept.del_flag == 0,
SysDept.dept_name.like(f'%{dept_info.dept_name}%') if dept_info.dept_name else True,
eval(data_scope_sql)) \
.order_by(SysDept.order_num) \
.distinct().all()
dept_result = (
(
await db.execute(
select(SysDept)
.where(
SysDept.status == '0',
SysDept.del_flag == '0',
SysDept.dept_name.like(f'%{dept_info.dept_name}%') if dept_info.dept_name else True,
eval(data_scope_sql),
)
.order_by(SysDept.order_num)
.distinct()
)
)
.scalars()
.all()
)
return dept_result
@classmethod
def get_dept_list(cls, db: Session, page_object: DeptModel, data_scope_sql: str):
async def get_dept_list(cls, db: AsyncSession, page_object: DeptModel, data_scope_sql: str):
"""
根据查询参数获取部门列表信息
:param db: orm对象
:param page_object: 不分页查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门列表信息对象
"""
dept_result = db.query(SysDept) \
.filter(SysDept.del_flag == 0,
SysDept.status == page_object.status if page_object.status else True,
SysDept.dept_name.like(f'%{page_object.dept_name}%') if page_object.dept_name else True,
eval(data_scope_sql)) \
.order_by(SysDept.order_num) \
.distinct().all()
dept_result = (
(
await db.execute(
select(SysDept)
.where(
SysDept.del_flag == '0',
SysDept.dept_id == page_object.dept_id if page_object.dept_id is not None else True,
SysDept.status == page_object.status if page_object.status else True,
SysDept.dept_name.like(f'%{page_object.dept_name}%') if page_object.dept_name else True,
eval(data_scope_sql),
)
.order_by(SysDept.order_num)
.distinct()
)
)
.scalars()
.all()
)
return dept_result
@classmethod
def add_dept_dao(cls, db: Session, dept: DeptModel):
async def add_dept_dao(cls, db: AsyncSession, dept: DeptModel):
"""
新增部门数据库操作
:param db: orm对象
:param dept: 部门对象
:return: 新增校验结果
"""
db_dept = SysDept(**dept.model_dump())
db.add(db_dept)
db.flush()
await db.flush()
return db_dept
@classmethod
def edit_dept_dao(cls, db: Session, dept: dict):
async def edit_dept_dao(cls, db: AsyncSession, dept: dict):
"""
编辑部门数据库操作
:param db: orm对象
:param dept: 需要更新的部门字典
:return: 编辑校验结果
"""
db.query(SysDept) \
.filter(SysDept.dept_id == dept.get('dept_id')) \
.update(dept)
await db.execute(update(SysDept), [dept])
@classmethod
def delete_dept_dao(cls, db: Session, dept: DeptModel):
async def update_dept_children_dao(cls, db: AsyncSession, update_dept: List):
"""
更新子部门信息
:param db: orm对象
:param update_dept: 需要更新的部门列表
:return:
"""
await db.execute(
update(SysDept)
.where(SysDept.dept_id == bindparam('dept_id'))
.values(
{
'dept_id': bindparam('dept_id'),
'ancestors': bindparam('ancestors'),
}
),
update_dept,
execution_options=immutabledict({'synchronize_session': None}),
)
@classmethod
async def update_dept_status_normal_dao(cls, db: AsyncSession, dept_id_list: List):
"""
批量更新部门状态为正常
:param db: orm对象
:param dept_id_list: 部门id列表
:return:
"""
await db.execute(update(SysDept).where(SysDept.dept_id.in_(dept_id_list)).values(status='0'))
@classmethod
async def delete_dept_dao(cls, db: AsyncSession, dept: DeptModel):
"""
删除部门数据库操作
:param db: orm对象
:param dept: 部门对象
:return:
"""
db.query(SysDept) \
.filter(SysDept.dept_id == dept.dept_id) \
.update({SysDept.del_flag: '2', SysDept.update_by: dept.update_by, SysDept.update_time: dept.update_time})
await db.execute(
update(SysDept)
.where(SysDept.dept_id == dept.dept_id)
.values(del_flag='2', update_by=dept.update_by, update_time=dept.update_time)
)
@classmethod
async def count_normal_children_dept_dao(cls, db: AsyncSession, dept_id: int):
"""
根据部门id查询查询所有子部门正常状态的数量
:param db: orm对象
:param dept_id: 部门id
:return: 所有子部门(正常状态)的数量
"""
normal_children_dept_count = (
await db.execute(
select(func.count('*'))
.select_from(SysDept)
.where(SysDept.status == '0', SysDept.del_flag == '0', func.find_in_set(dept_id, SysDept.ancestors))
)
).scalar()
return normal_children_dept_count
@classmethod
async def count_children_dept_dao(cls, db: AsyncSession, dept_id: int):
"""
根据部门id查询查询所有子部门所有状态的数量
:param db: orm对象
:param dept_id: 部门id
:return: 所有子部门(所有状态)的数量
"""
children_dept_count = (
await db.execute(
select(func.count('*'))
.select_from(SysDept)
.where(SysDept.del_flag == '0', SysDept.parent_id == dept_id)
.limit(1)
)
).scalar()
return children_dept_count
@classmethod
async def count_dept_user_dao(cls, db: AsyncSession, dept_id: int):
"""
根据部门id查询查询部门下的用户数量
:param db: orm对象
:param dept_id: 部门id
:return: 部门下的用户数量
"""
dept_user_count = (
await db.execute(
select(func.count('*')).select_from(SysUser).where(SysUser.dept_id == dept_id, SysUser.del_flag == '0')
)
).scalar()
return dept_user_count

View File

@@ -1,10 +1,10 @@
from sqlalchemy import and_
from sqlalchemy.orm import Session
from module_admin.entity.do.dict_do import SysDictType, SysDictData
from module_admin.entity.vo.dict_vo import *
from utils.time_format_util import list_format_datetime
from utils.page_util import PageUtil
from datetime import datetime, time
from sqlalchemy import and_, delete, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.dict_do import SysDictType, SysDictData
from module_admin.entity.vo.dict_vo import DictDataModel, DictDataPageQueryModel, DictTypeModel, DictTypePageQueryModel
from utils.page_util import PageUtil
from utils.time_format_util import list_format_datetime
class DictTypeDao:
@@ -13,105 +13,120 @@ class DictTypeDao:
"""
@classmethod
def get_dict_type_detail_by_id(cls, db: Session, dict_id: int):
async def get_dict_type_detail_by_id(cls, db: AsyncSession, dict_id: int):
"""
根据字典类型id获取字典类型详细信息
:param db: orm对象
:param dict_id: 字典类型id
:return: 字典类型信息对象
"""
dict_type_info = db.query(SysDictType) \
.filter(SysDictType.dict_id == dict_id) \
.first()
dict_type_info = (await db.execute(select(SysDictType).where(SysDictType.dict_id == dict_id))).scalars().first()
return dict_type_info
@classmethod
def get_dict_type_detail_by_info(cls, db: Session, dict_type: DictTypeModel):
async def get_dict_type_detail_by_info(cls, db: AsyncSession, dict_type: DictTypeModel):
"""
根据字典类型参数获取字典类型信息
:param db: orm对象
:param dict_type: 字典类型参数对象
:return: 字典类型信息对象
"""
dict_type_info = db.query(SysDictType) \
.filter(SysDictType.dict_type == dict_type.dict_type if dict_type.dict_type else True,
SysDictType.dict_name == dict_type.dict_name if dict_type.dict_name else True) \
dict_type_info = (
(
await db.execute(
select(SysDictType).where(
SysDictType.dict_type == dict_type.dict_type if dict_type.dict_type else True,
SysDictType.dict_name == dict_type.dict_name if dict_type.dict_name else True,
)
)
)
.scalars()
.first()
)
return dict_type_info
@classmethod
def get_all_dict_type(cls, db: Session):
async def get_all_dict_type(cls, db: AsyncSession):
"""
获取所有的字典类型信息
:param db: orm对象
:return: 字典类型信息列表对象
"""
dict_type_info = db.query(SysDictType).all()
dict_type_info = (await db.execute(select(SysDictType))).scalars().all()
return list_format_datetime(dict_type_info)
@classmethod
def get_dict_type_list(cls, db: Session, query_object: DictTypePageQueryModel, is_page: bool = False):
async def get_dict_type_list(cls, db: AsyncSession, query_object: DictTypePageQueryModel, is_page: bool = False):
"""
根据查询参数获取字典类型列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 字典类型列表信息对象
"""
query = db.query(SysDictType) \
.filter(SysDictType.dict_name.like(f'%{query_object.dict_name}%') if query_object.dict_name else True,
SysDictType.dict_type.like(f'%{query_object.dict_type}%') if query_object.dict_type else True,
SysDictType.status == query_object.status if query_object.status else True,
SysDictType.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
) \
query = (
select(SysDictType)
.where(
SysDictType.dict_name.like(f'%{query_object.dict_name}%') if query_object.dict_name else True,
SysDictType.dict_type.like(f'%{query_object.dict_type}%') if query_object.dict_type else True,
SysDictType.status == query_object.status if query_object.status else True,
SysDictType.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,
)
.order_by(SysDictType.dict_id)
.distinct()
dict_type_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
dict_type_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return dict_type_list
@classmethod
def add_dict_type_dao(cls, db: Session, dict_type: DictTypeModel):
async def add_dict_type_dao(cls, db: AsyncSession, dict_type: DictTypeModel):
"""
新增字典类型数据库操作
:param db: orm对象
:param dict_type: 字典类型对象
:return:
"""
db_dict_type = SysDictType(**dict_type.dict())
db_dict_type = SysDictType(**dict_type.model_dump())
db.add(db_dict_type)
db.flush()
await db.flush()
return db_dict_type
@classmethod
def edit_dict_type_dao(cls, db: Session, dict_type: dict):
async def edit_dict_type_dao(cls, db: AsyncSession, dict_type: dict):
"""
编辑字典类型数据库操作
:param db: orm对象
:param dict_type: 需要更新的字典类型字典
:return:
"""
db.query(SysDictType) \
.filter(SysDictType.dict_id == dict_type.get('dict_id')) \
.update(dict_type)
await db.execute(update(SysDictType), [dict_type])
@classmethod
def delete_dict_type_dao(cls, db: Session, dict_type: DictTypeModel):
async def delete_dict_type_dao(cls, db: AsyncSession, dict_type: DictTypeModel):
"""
删除字典类型数据库操作
:param db: orm对象
:param dict_type: 字典类型对象
:return:
"""
db.query(SysDictType) \
.filter(SysDictType.dict_id == dict_type.dict_id) \
.delete()
await db.execute(delete(SysDictType).where(SysDictType.dict_id.in_([dict_type.dict_id])))
class DictDataDao:
@@ -120,105 +135,147 @@ class DictDataDao:
"""
@classmethod
def get_dict_data_detail_by_id(cls, db: Session, dict_code: int):
async def get_dict_data_detail_by_id(cls, db: AsyncSession, dict_code: int):
"""
根据字典数据id获取字典数据详细信息
:param db: orm对象
:param dict_code: 字典数据id
:return: 字典数据信息对象
"""
dict_data_info = db.query(SysDictData) \
.filter(SysDictData.dict_code == dict_code) \
.first()
dict_data_info = (
(await db.execute(select(SysDictData).where(SysDictData.dict_code == dict_code))).scalars().first()
)
return dict_data_info
@classmethod
def get_dict_data_detail_by_info(cls, db: Session, dict_data: DictDataModel):
async def get_dict_data_detail_by_info(cls, db: AsyncSession, dict_data: DictDataModel):
"""
根据字典数据参数获取字典数据信息
:param db: orm对象
:param dict_data: 字典数据参数对象
:return: 字典数据信息对象
"""
dict_data_info = db.query(SysDictData) \
.filter(SysDictData.dict_type == dict_data.dict_type if dict_data.dict_type else True,
SysDictData.dict_label == dict_data.dict_label if dict_data.dict_label else True,
SysDictData.dict_value == dict_data.dict_value if dict_data.dict_value else True) \
dict_data_info = (
(
await db.execute(
select(SysDictData).where(
SysDictData.dict_type == dict_data.dict_type,
SysDictData.dict_label == dict_data.dict_label,
SysDictData.dict_value == dict_data.dict_value,
)
)
)
.scalars()
.first()
)
return dict_data_info
@classmethod
def get_dict_data_list(cls, db: Session, query_object: DictDataPageQueryModel, is_page: bool = False):
async def get_dict_data_list(cls, db: AsyncSession, query_object: DictDataPageQueryModel, is_page: bool = False):
"""
根据查询参数获取字典数据列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 字典数据列表信息对象
"""
query = db.query(SysDictData) \
.filter(SysDictData.dict_type == query_object.dict_type if query_object.dict_type else True,
SysDictData.dict_label.like(f'%{query_object.dict_label}%') if query_object.dict_label else True,
SysDictData.status == query_object.status if query_object.status else True
) \
.order_by(SysDictData.dict_sort) \
query = (
select(SysDictData)
.where(
SysDictData.dict_type == query_object.dict_type if query_object.dict_type else True,
SysDictData.dict_label.like(f'%{query_object.dict_label}%') if query_object.dict_label else True,
SysDictData.status == query_object.status if query_object.status else True,
)
.order_by(SysDictData.dict_sort)
.distinct()
dict_data_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
dict_data_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return dict_data_list
@classmethod
def query_dict_data_list(cls, db: Session, dict_type: str):
async def query_dict_data_list(cls, db: AsyncSession, dict_type: str):
"""
根据查询参数获取字典数据列表信息
:param db: orm对象
:param dict_type: 字典类型
:return: 字典数据列表信息对象
"""
dict_data_list = db.query(SysDictData).select_from(SysDictType) \
.filter(SysDictType.dict_type == dict_type if dict_type else True, SysDictType.status == 0) \
.outerjoin(SysDictData, and_(SysDictType.dict_type == SysDictData.dict_type, SysDictData.status == 0)) \
.order_by(SysDictData.dict_sort) \
.distinct().all()
dict_data_list = (
(
await db.execute(
select(SysDictData)
.select_from(SysDictType)
.where(SysDictType.dict_type == dict_type if dict_type else True, SysDictType.status == '0')
.join(
SysDictData,
and_(SysDictType.dict_type == SysDictData.dict_type, SysDictData.status == '0'),
isouter=True,
)
.order_by(SysDictData.dict_sort)
.distinct()
)
)
.scalars()
.all()
)
return dict_data_list
@classmethod
def add_dict_data_dao(cls, db: Session, dict_data: DictDataModel):
async def add_dict_data_dao(cls, db: AsyncSession, dict_data: DictDataModel):
"""
新增字典数据数据库操作
:param db: orm对象
:param dict_data: 字典数据对象
:return:
"""
db_data_type = SysDictData(**dict_data.dict())
db_data_type = SysDictData(**dict_data.model_dump())
db.add(db_data_type)
db.flush()
await db.flush()
return db_data_type
@classmethod
def edit_dict_data_dao(cls, db: Session, dict_data: dict):
async def edit_dict_data_dao(cls, db: AsyncSession, dict_data: dict):
"""
编辑字典数据数据库操作
:param db: orm对象
:param dict_data: 需要更新的字典数据字典
:return:
"""
db.query(SysDictData) \
.filter(SysDictData.dict_code == dict_data.get('dict_code')) \
.update(dict_data)
await db.execute(update(SysDictData), [dict_data])
@classmethod
def delete_dict_data_dao(cls, db: Session, dict_data: DictDataModel):
async def delete_dict_data_dao(cls, db: AsyncSession, dict_data: DictDataModel):
"""
删除字典数据数据库操作
:param db: orm对象
:param dict_data: 字典数据对象
:return:
"""
db.query(SysDictData) \
.filter(SysDictData.dict_code == dict_data.dict_code) \
.delete()
await db.execute(delete(SysDictData).where(SysDictData.dict_code.in_([dict_data.dict_code])))
@classmethod
async def count_dict_data_dao(cls, db: AsyncSession, dict_type: str):
"""
根据字典类型查询字典类型关联的字典数据数量
:param db: orm对象
:param dict_type: 字典类型
:return: 字典类型关联的字典数据数量
"""
dict_data_count = (
await db.execute(select(func.count('*')).select_from(SysDictData).where(SysDictData.dict_type == dict_type))
).scalar()
return dict_data_count

View File

@@ -1,6 +1,7 @@
from sqlalchemy.orm import Session
from sqlalchemy import delete, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.job_do import SysJob
from module_admin.entity.vo.job_vo import *
from module_admin.entity.vo.job_vo import JobModel, JobPageQueryModel
from utils.page_util import PageUtil
@@ -10,102 +11,116 @@ class JobDao:
"""
@classmethod
def get_job_detail_by_id(cls, db: Session, job_id: int):
async def get_job_detail_by_id(cls, db: AsyncSession, job_id: int):
"""
根据定时任务id获取定时任务详细信息
:param db: orm对象
:param job_id: 定时任务id
:return: 定时任务信息对象
"""
job_info = db.query(SysJob) \
.filter(SysJob.job_id == job_id) \
.first()
job_info = (await db.execute(select(SysJob).where(SysJob.job_id == job_id))).scalars().first()
return job_info
@classmethod
def get_job_detail_by_info(cls, db: Session, job: JobModel):
async def get_job_detail_by_info(cls, db: AsyncSession, job: JobModel):
"""
根据定时任务参数获取定时任务信息
:param db: orm对象
:param job: 定时任务参数对象
:return: 定时任务信息对象
"""
job_info = db.query(SysJob) \
.filter(SysJob.job_name == job.job_name if job.job_name else True,
SysJob.job_group == job.job_group if job.job_group else True,
SysJob.invoke_target == job.invoke_target if job.invoke_target else True,
SysJob.cron_expression == job.cron_expression if job.cron_expression else True) \
job_info = (
(
await db.execute(
select(SysJob).where(
SysJob.job_name == job.job_name,
SysJob.job_group == job.job_group,
SysJob.job_executor == job.job_executor,
SysJob.invoke_target == job.invoke_target,
SysJob.job_args == job.job_args,
SysJob.job_kwargs == job.job_kwargs,
SysJob.cron_expression == job.cron_expression,
)
)
)
.scalars()
.first()
)
return job_info
@classmethod
def get_job_list(cls, db: Session, query_object: JobPageQueryModel, is_page: bool = False):
async def get_job_list(cls, db: AsyncSession, query_object: JobPageQueryModel, is_page: bool = False):
"""
根据查询参数获取定时任务列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 定时任务列表信息对象
"""
query = db.query(SysJob) \
.filter(SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJob.job_group == query_object.job_group if query_object.job_group else True,
SysJob.status == query_object.status if query_object.status else True
) \
query = (
select(SysJob)
.where(
SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJob.job_group == query_object.job_group if query_object.job_group else True,
SysJob.status == query_object.status if query_object.status else True,
)
.order_by(SysJob.job_id)
.distinct()
job_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
job_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return job_list
@classmethod
def get_job_list_for_scheduler(cls, db: Session):
async def get_job_list_for_scheduler(cls, db: AsyncSession):
"""
获取定时任务列表信息
:param db: orm对象
:return: 定时任务列表信息对象
"""
job_list = db.query(SysJob) \
.filter(SysJob.status == 0) \
.distinct().all()
job_list = (await db.execute(select(SysJob).where(SysJob.status == '0').distinct())).scalars().all()
return job_list
@classmethod
def add_job_dao(cls, db: Session, job: JobModel):
async def add_job_dao(cls, db: AsyncSession, job: JobModel):
"""
新增定时任务数据库操作
:param db: orm对象
:param job: 定时任务对象
:return:
"""
db_job = SysJob(**job.model_dump())
db.add(db_job)
db.flush()
await db.flush()
return db_job
@classmethod
def edit_job_dao(cls, db: Session, job: dict):
async def edit_job_dao(cls, db: AsyncSession, job: dict):
"""
编辑定时任务数据库操作
:param db: orm对象
:param job: 需要更新的定时任务字典
:return:
"""
db.query(SysJob) \
.filter(SysJob.job_id == job.get('job_id')) \
.update(job)
await db.execute(update(SysJob), [job])
@classmethod
def delete_job_dao(cls, db: Session, job: JobModel):
async def delete_job_dao(cls, db: AsyncSession, job: JobModel):
"""
删除定时任务数据库操作
:param db: orm对象
:param job: 定时任务对象
:return:
"""
db.query(SysJob) \
.filter(SysJob.job_id == job.job_id) \
.delete()
await db.execute(delete(SysJob).where(SysJob.job_id.in_([job.job_id])))

View File

@@ -1,8 +1,10 @@
from datetime import datetime, time
from sqlalchemy import delete, desc, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session
from module_admin.entity.do.job_do import SysJobLog
from module_admin.entity.vo.job_vo import *
from module_admin.entity.vo.job_vo import JobLogModel, JobLogPageQueryModel
from utils.page_util import PageUtil
from datetime import datetime, time
class JobLogDao:
@@ -11,25 +13,32 @@ class JobLogDao:
"""
@classmethod
def get_job_log_list(cls, db: Session, query_object: JobLogPageQueryModel, is_page: bool = False):
async def get_job_log_list(cls, db: AsyncSession, query_object: JobLogPageQueryModel, is_page: bool = False):
"""
根据查询参数获取定时任务日志列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 定时任务日志列表信息对象
"""
query = db.query(SysJobLog) \
.filter(SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJobLog.job_group == query_object.job_group if query_object.job_group else True,
SysJobLog.status == query_object.status if query_object.status else True,
SysJobLog.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
) \
query = (
select(SysJobLog)
.where(
SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJobLog.job_group == query_object.job_group if query_object.job_group else True,
SysJobLog.status == query_object.status if query_object.status else True,
SysJobLog.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,
)
.order_by(desc(SysJobLog.create_time))
.distinct()
job_log_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
job_log_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return job_log_list
@@ -37,6 +46,7 @@ class JobLogDao:
def add_job_log_dao(cls, db: Session, job_log: JobLogModel):
"""
新增定时任务日志数据库操作
:param db: orm对象
:param job_log: 定时任务日志对象
:return:
@@ -48,23 +58,22 @@ class JobLogDao:
return db_job_log
@classmethod
def delete_job_log_dao(cls, db: Session, job_log: JobLogModel):
async def delete_job_log_dao(cls, db: AsyncSession, job_log: JobLogModel):
"""
删除定时任务日志数据库操作
:param db: orm对象
:param job_log: 定时任务日志对象
:return:
"""
db.query(SysJobLog) \
.filter(SysJobLog.job_log_id == job_log.job_log_id) \
.delete()
await db.execute(delete(SysJobLog).where(SysJobLog.job_log_id.in_([job_log.job_log_id])))
@classmethod
def clear_job_log_dao(cls, db: Session):
async def clear_job_log_dao(cls, db: AsyncSession):
"""
清除定时任务日志数据库操作
:param db: orm对象
:return:
"""
db.query(SysJobLog) \
.delete()
await db.execute(delete(SysJobLog))

View File

@@ -1,81 +1,91 @@
from sqlalchemy import asc, desc
from sqlalchemy.orm import Session
from module_admin.entity.do.log_do import SysOperLog, SysLogininfor
from module_admin.entity.vo.log_vo import *
from utils.page_util import PageUtil
from utils.common_util import CamelCaseUtil
from datetime import datetime, time
from sqlalchemy import asc, delete, desc, select
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.log_do import SysLogininfor, SysOperLog
from module_admin.entity.vo.log_vo import LogininforModel, LoginLogPageQueryModel, OperLogModel, OperLogPageQueryModel
from utils.common_util import SnakeCaseUtil
from utils.page_util import PageUtil
class OperationLogDao:
"""
操作日志管理模块数据库操作层
"""
@classmethod
def get_operation_log_list(cls, db: Session, query_object: OperLogPageQueryModel, is_page: bool = False):
async def get_operation_log_list(cls, db: AsyncSession, query_object: OperLogPageQueryModel, is_page: bool = False):
"""
根据查询参数获取操作日志列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 操作日志列表信息对象
"""
if query_object.is_asc == 'ascending':
order_by_column = asc(getattr(SysOperLog, CamelCaseUtil.camel_to_snake(query_object.order_by_column), None))
order_by_column = asc(getattr(SysOperLog, SnakeCaseUtil.camel_to_snake(query_object.order_by_column), None))
elif query_object.is_asc == 'descending':
order_by_column = desc(getattr(SysOperLog, CamelCaseUtil.camel_to_snake(query_object.order_by_column), None))
order_by_column = desc(
getattr(SysOperLog, SnakeCaseUtil.camel_to_snake(query_object.order_by_column), None)
)
else:
order_by_column = desc(SysOperLog.oper_time)
query = db.query(SysOperLog) \
.filter(SysOperLog.title.like(f'%{query_object.title}%') if query_object.title else True,
SysOperLog.oper_name.like(f'%{query_object.oper_name}%') if query_object.oper_name else True,
SysOperLog.business_type == query_object.business_type if query_object.business_type else True,
SysOperLog.status == query_object.status if query_object.status else True,
SysOperLog.oper_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
)\
.distinct().order_by(order_by_column)
operation_log_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
query = (
select(SysOperLog)
.where(
SysOperLog.title.like(f'%{query_object.title}%') if query_object.title else True,
SysOperLog.oper_name.like(f'%{query_object.oper_name}%') if query_object.oper_name else True,
SysOperLog.business_type == query_object.business_type if query_object.business_type else True,
SysOperLog.status == query_object.status if query_object.status else True,
SysOperLog.oper_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,
)
.distinct()
.order_by(order_by_column)
)
operation_log_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return operation_log_list
@classmethod
def add_operation_log_dao(cls, db: Session, operation_log: OperLogModel):
async def add_operation_log_dao(cls, db: AsyncSession, operation_log: OperLogModel):
"""
新增操作日志数据库操作
:param db: orm对象
:param operation_log: 操作日志对象
:return: 新增校验结果
"""
db_operation_log = SysOperLog(**operation_log.model_dump())
db.add(db_operation_log)
db.flush()
await db.flush()
return db_operation_log
@classmethod
def delete_operation_log_dao(cls, db: Session, operation_log: OperLogModel):
async def delete_operation_log_dao(cls, db: AsyncSession, operation_log: OperLogModel):
"""
删除操作日志数据库操作
:param db: orm对象
:param operation_log: 操作日志对象
:return:
"""
db.query(SysOperLog) \
.filter(SysOperLog.oper_id == operation_log.oper_id) \
.delete()
await db.execute(delete(SysOperLog).where(SysOperLog.oper_id.in_([operation_log.oper_id])))
@classmethod
def clear_operation_log_dao(cls, db: Session):
async def clear_operation_log_dao(cls, db: AsyncSession):
"""
清除操作日志数据库操作
:param db: orm对象
:return:
"""
db.query(SysOperLog) \
.delete()
await db.execute(delete(SysOperLog))
class LoginLogDao:
@@ -84,66 +94,77 @@ class LoginLogDao:
"""
@classmethod
def get_login_log_list(cls, db: Session, query_object: LoginLogPageQueryModel, is_page: bool = False):
async def get_login_log_list(cls, db: AsyncSession, query_object: LoginLogPageQueryModel, is_page: bool = False):
"""
根据查询参数获取登录日志列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 登录日志列表信息对象
"""
if query_object.is_asc == 'ascending':
order_by_column = asc(getattr(SysLogininfor, CamelCaseUtil.camel_to_snake(query_object.order_by_column), None))
order_by_column = asc(
getattr(SysLogininfor, SnakeCaseUtil.camel_to_snake(query_object.order_by_column), None)
)
elif query_object.is_asc == 'descending':
order_by_column = desc(getattr(SysLogininfor, CamelCaseUtil.camel_to_snake(query_object.order_by_column), None))
order_by_column = desc(
getattr(SysLogininfor, SnakeCaseUtil.camel_to_snake(query_object.order_by_column), None)
)
else:
order_by_column = desc(SysLogininfor.login_time)
query = db.query(SysLogininfor) \
.filter(SysLogininfor.ipaddr.like(f'%{query_object.ipaddr}%') if query_object.ipaddr else True,
SysLogininfor.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True,
SysLogininfor.status == query_object.status if query_object.status else True,
SysLogininfor.login_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
)\
.distinct().order_by(order_by_column)
login_log_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
query = (
select(SysLogininfor)
.where(
SysLogininfor.ipaddr.like(f'%{query_object.ipaddr}%') if query_object.ipaddr else True,
SysLogininfor.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True,
SysLogininfor.status == query_object.status if query_object.status else True,
SysLogininfor.login_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,
)
.distinct()
.order_by(order_by_column)
)
login_log_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return login_log_list
@classmethod
def add_login_log_dao(cls, db: Session, login_log: LogininforModel):
async def add_login_log_dao(cls, db: AsyncSession, login_log: LogininforModel):
"""
新增登录日志数据库操作
:param db: orm对象
:param login_log: 登录日志对象
:return: 新增校验结果
"""
db_login_log = SysLogininfor(**login_log.model_dump())
db.add(db_login_log)
db.flush()
await db.flush()
return db_login_log
@classmethod
def delete_login_log_dao(cls, db: Session, login_log: LogininforModel):
async def delete_login_log_dao(cls, db: AsyncSession, login_log: LogininforModel):
"""
删除登录日志数据库操作
:param db: orm对象
:param login_log: 登录日志对象
:return:
"""
db.query(SysLogininfor) \
.filter(SysLogininfor.info_id == login_log.info_id) \
.delete()
await db.execute(delete(SysLogininfor).where(SysLogininfor.info_id.in_([login_log.info_id])))
@classmethod
def clear_login_log_dao(cls, db: Session):
async def clear_login_log_dao(cls, db: AsyncSession):
"""
清除登录日志数据库操作
:param db: orm对象
:return:
"""
db.query(SysLogininfor) \
.delete()
await db.execute(delete(SysLogininfor))

View File

@@ -1,20 +1,28 @@
from sqlalchemy.orm import Session
from sqlalchemy import and_
from module_admin.entity.do.user_do import SysUser
from sqlalchemy import and_, select
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.do.user_do import SysUser
def login_by_account(db: Session, user_name: str):
async def login_by_account(db: AsyncSession, user_name: str):
"""
根据用户名查询用户信息
:param db: orm对象
:param user_name: 用户名
:return: 用户对象
"""
user = db.query(SysUser, SysDept)\
.filter(SysUser.user_name == user_name, SysUser.del_flag == '0') \
.outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \
.distinct() \
.first()
user = (
await db.execute(
select(SysUser, SysDept)
.where(SysUser.user_name == user_name, SysUser.del_flag == '0')
.join(
SysDept,
and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == '0', SysDept.del_flag == '0'),
isouter=True,
)
.distinct()
)
).first()
return user

View File

@@ -1,9 +1,9 @@
from sqlalchemy import and_
from sqlalchemy.orm import Session
from sqlalchemy import and_, delete, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.menu_do import SysMenu
from module_admin.entity.do.user_do import SysUser, SysUserRole
from module_admin.entity.do.role_do import SysRole, SysRoleMenu
from module_admin.entity.vo.menu_vo import *
from module_admin.entity.do.user_do import SysUser, SysUserRole
from module_admin.entity.vo.menu_vo import MenuModel, MenuQueryModel
class MenuDao:
@@ -12,39 +12,48 @@ class MenuDao:
"""
@classmethod
def get_menu_detail_by_id(cls, db: Session, menu_id: int):
async def get_menu_detail_by_id(cls, db: AsyncSession, menu_id: int):
"""
根据菜单id获取菜单详细信息
:param db: orm对象
:param menu_id: 菜单id
:return: 菜单信息对象
"""
menu_info = db.query(SysMenu) \
.filter(SysMenu.menu_id == menu_id) \
.first()
menu_info = (await db.execute(select(SysMenu).where(SysMenu.menu_id == menu_id))).scalars().first()
return menu_info
@classmethod
def get_menu_detail_by_info(cls, db: Session, menu: MenuModel):
async def get_menu_detail_by_info(cls, db: AsyncSession, menu: MenuModel):
"""
根据菜单参数获取菜单信息
:param db: orm对象
:param menu: 菜单参数对象
:return: 菜单信息对象
"""
menu_info = db.query(SysMenu) \
.filter(SysMenu.parent_id == menu.parent_id if menu.parent_id else True,
SysMenu.menu_name == menu.menu_name if menu.menu_name else True,
SysMenu.menu_type == menu.menu_type if menu.menu_type else True) \
menu_info = (
(
await db.execute(
select(SysMenu).where(
SysMenu.parent_id == menu.parent_id if menu.parent_id else True,
SysMenu.menu_name == menu.menu_name if menu.menu_name else True,
SysMenu.menu_type == menu.menu_type if menu.menu_type else True,
)
)
)
.scalars()
.first()
)
return menu_info
@classmethod
def get_menu_list_for_tree(cls, db: Session, user_id: int, role: list):
async def get_menu_list_for_tree(cls, db: AsyncSession, user_id: int, role: list):
"""
根据角色信息获取所有在用菜单列表信息
:param db: orm对象
:param user_id: 用户id
:param role: 用户角色列表信息
@@ -52,27 +61,43 @@ class MenuDao:
"""
role_id_list = [item.role_id for item in role]
if 1 in role_id_list:
menu_query_all = db.query(SysMenu) \
.filter(SysMenu.status == 0) \
.order_by(SysMenu.order_num) \
.distinct().all()
menu_query_all = (
(await db.execute(select(SysMenu).where(SysMenu.status == '0').order_by(SysMenu.order_num).distinct()))
.scalars()
.all()
)
else:
menu_query_all = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole,
and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0,)) \
.order_by(SysMenu.order_num) \
.distinct().all()
menu_query_all = (
(
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()
)
return menu_query_all
@classmethod
def get_menu_list(cls, db: Session, page_object: MenuQueryModel, user_id: int, role: list):
async def get_menu_list(cls, db: AsyncSession, page_object: MenuQueryModel, user_id: int, role: list):
"""
根据查询参数获取菜单列表信息
:param db: orm对象
:param page_object: 不分页查询参数对象
:param user_id: 用户id
@@ -81,62 +106,118 @@ class MenuDao:
"""
role_id_list = [item.role_id for item in role]
if 1 in role_id_list:
menu_query_all = db.query(SysMenu) \
.filter(SysMenu.status == page_object.status if page_object.status else True,
SysMenu.menu_name.like(
f'%{page_object.menu_name}%') if page_object.menu_name else True) \
.order_by(SysMenu.order_num) \
.distinct().all()
menu_query_all = (
(
await db.execute(
select(SysMenu)
.where(
SysMenu.status == page_object.status if page_object.status else True,
SysMenu.menu_name.like(f'%{page_object.menu_name}%') if page_object.menu_name else True,
)
.order_by(SysMenu.order_num)
.distinct()
)
)
.scalars()
.all()
)
else:
menu_query_all = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole,
and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id,
SysMenu.status == page_object.status if page_object.status else True,
SysMenu.menu_name.like(
f'%{page_object.menu_name}%') if page_object.menu_name else True)) \
.order_by(SysMenu.order_num) \
.distinct().all()
menu_query_all = (
(
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 == page_object.status if page_object.status else True,
SysMenu.menu_name.like(f'%{page_object.menu_name}%') if page_object.menu_name else True,
),
)
.order_by(SysMenu.order_num)
.distinct()
)
)
.scalars()
.all()
)
return menu_query_all
@classmethod
def add_menu_dao(cls, db: Session, menu: MenuModel):
async def add_menu_dao(cls, db: AsyncSession, menu: MenuModel):
"""
新增菜单数据库操作
:param db: orm对象
:param menu: 菜单对象
:return:
"""
db_menu = SysMenu(**menu.model_dump())
db.add(db_menu)
db.flush()
await db.flush()
return db_menu
@classmethod
def edit_menu_dao(cls, db: Session, menu: dict):
async def edit_menu_dao(cls, db: AsyncSession, menu: dict):
"""
编辑菜单数据库操作
:param db: orm对象
:param menu: 需要更新的菜单字典
:return:
"""
db.query(SysMenu) \
.filter(SysMenu.menu_id == menu.get('menu_id')) \
.update(menu)
await db.execute(update(SysMenu), [menu])
@classmethod
def delete_menu_dao(cls, db: Session, menu: MenuModel):
async def delete_menu_dao(cls, db: AsyncSession, menu: MenuModel):
"""
删除菜单数据库操作
:param db: orm对象
:param menu: 菜单对象
:return:
"""
db.query(SysMenu) \
.filter(SysMenu.menu_id == menu.menu_id) \
.delete()
await db.execute(delete(SysMenu).where(SysMenu.menu_id.in_([menu.menu_id])))
@classmethod
async def has_child_by_menu_id_dao(cls, db: AsyncSession, menu_id: int):
"""
根据菜单id查询菜单关联子菜单的数量
:param db: orm对象
:param menu_id: 菜单id
:return: 菜单关联子菜单的数量
"""
menu_count = (
await db.execute(select(func.count('*')).select_from(SysMenu).where(SysMenu.parent_id == menu_id))
).scalar()
return menu_count
@classmethod
async def check_menu_exist_role_dao(cls, db: AsyncSession, menu_id: int):
"""
根据菜单id查询菜单关联角色数量
:param db: orm对象
:param menu_id: 菜单id
:return: 菜单关联角色数量
"""
role_count = (
await db.execute(select(func.count('*')).select_from(SysRoleMenu).where(SysRoleMenu.menu_id == menu_id))
).scalar()
return role_count

View File

@@ -1,8 +1,9 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.notice_do import SysNotice
from module_admin.entity.vo.notice_vo import *
from utils.page_util import PageUtil
from datetime import datetime, time
from sqlalchemy import delete, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.notice_do import SysNotice
from module_admin.entity.vo.notice_vo import NoticeModel, NoticePageQueryModel
from utils.page_util import PageUtil
class NoticeDao:
@@ -11,92 +12,106 @@ class NoticeDao:
"""
@classmethod
def get_notice_detail_by_id(cls, db: Session, notice_id: int):
async def get_notice_detail_by_id(cls, db: AsyncSession, notice_id: int):
"""
根据通知公告id获取通知公告详细信息
:param db: orm对象
:param notice_id: 通知公告id
:return: 通知公告信息对象
"""
notice_info = db.query(SysNotice) \
.filter(SysNotice.notice_id == notice_id) \
.first()
notice_info = (await db.execute(select(SysNotice).where(SysNotice.notice_id == notice_id))).scalars().first()
return notice_info
@classmethod
def get_notice_detail_by_info(cls, db: Session, notice: NoticeModel):
async def get_notice_detail_by_info(cls, db: AsyncSession, notice: NoticeModel):
"""
根据通知公告参数获取通知公告信息
:param db: orm对象
:param notice: 通知公告参数对象
:return: 通知公告信息对象
"""
notice_info = db.query(SysNotice) \
.filter(SysNotice.notice_title == notice.notice_title if notice.notice_title else True,
SysNotice.notice_type == notice.notice_type if notice.notice_type else True,
SysNotice.notice_content == notice.notice_content if notice.notice_content else True) \
notice_info = (
(
await db.execute(
select(SysNotice).where(
SysNotice.notice_title == notice.notice_title,
SysNotice.notice_type == notice.notice_type,
SysNotice.notice_content == notice.notice_content,
)
)
)
.scalars()
.first()
)
return notice_info
@classmethod
def get_notice_list(cls, db: Session, query_object: NoticePageQueryModel, is_page: bool = False):
async def get_notice_list(cls, db: AsyncSession, query_object: NoticePageQueryModel, is_page: bool = False):
"""
根据查询参数获取通知公告列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 通知公告列表信息对象
"""
query = db.query(SysNotice) \
.filter(SysNotice.notice_title.like(f'%{query_object.notice_title}%') if query_object.notice_title else True,
SysNotice.update_by.like(f'%{query_object.update_by}%') if query_object.update_by else True,
SysNotice.notice_type == query_object.notice_type if query_object.notice_type else True,
SysNotice.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
) \
query = (
select(SysNotice)
.where(
SysNotice.notice_title.like(f'%{query_object.notice_title}%') if query_object.notice_title else True,
SysNotice.create_by.like(f'%{query_object.create_by}%') if query_object.create_by else True,
SysNotice.notice_type == query_object.notice_type if query_object.notice_type else True,
SysNotice.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,
)
.order_by(SysNotice.notice_id)
.distinct()
notice_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
notice_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return notice_list
@classmethod
def add_notice_dao(cls, db: Session, notice: NoticeModel):
async def add_notice_dao(cls, db: AsyncSession, notice: NoticeModel):
"""
新增通知公告数据库操作
:param db: orm对象
:param notice: 通知公告对象
:return:
"""
db_notice = SysNotice(**notice.model_dump())
db.add(db_notice)
db.flush()
await db.flush()
return db_notice
@classmethod
def edit_notice_dao(cls, db: Session, notice: dict):
async def edit_notice_dao(cls, db: AsyncSession, notice: dict):
"""
编辑通知公告数据库操作
:param db: orm对象
:param notice: 需要更新的通知公告字典
:return:
"""
db.query(SysNotice) \
.filter(SysNotice.notice_id == notice.get('notice_id')) \
.update(notice)
await db.execute(update(SysNotice), [notice])
@classmethod
def delete_notice_dao(cls, db: Session, notice: NoticeModel):
async def delete_notice_dao(cls, db: AsyncSession, notice: NoticeModel):
"""
删除通知公告数据库操作
:param db: orm对象
:param notice: 通知公告对象
:return:
"""
db.query(SysNotice) \
.filter(SysNotice.notice_id == notice.notice_id) \
.delete()
await db.execute(delete(SysNotice).where(SysNotice.notice_id.in_([notice.notice_id])))

View File

@@ -1,6 +1,8 @@
from sqlalchemy.orm import Session
from sqlalchemy import delete, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.post_do import SysPost
from module_admin.entity.vo.post_vo import *
from module_admin.entity.do.user_do import SysUserPost
from module_admin.entity.vo.post_vo import PostModel, PostPageQueryModel
from utils.page_util import PageUtil
@@ -10,104 +12,132 @@ class PostDao:
"""
@classmethod
def get_post_by_id(cls, db: Session, post_id: int):
async def get_post_by_id(cls, db: AsyncSession, post_id: int):
"""
根据岗位id获取在用岗位详细信息
:param db: orm对象
:param post_id: 岗位id
:return: 在用岗位信息对象
"""
post_info = db.query(SysPost) \
.filter(SysPost.post_id == post_id,
SysPost.status == 0) \
post_info = (
(await db.execute(select(SysPost).where(SysPost.post_id == post_id, SysPost.status == '0')))
.scalars()
.first()
)
return post_info
@classmethod
def get_post_detail_by_id(cls, db: Session, post_id: int):
async def get_post_detail_by_id(cls, db: AsyncSession, post_id: int):
"""
根据岗位id获取岗位详细信息
:param db: orm对象
:param post_id: 岗位id
:return: 岗位信息对象
"""
post_info = db.query(SysPost) \
.filter(SysPost.post_id == post_id) \
.first()
post_info = (await db.execute(select(SysPost).where(SysPost.post_id == post_id))).scalars().first()
return post_info
@classmethod
def get_post_detail_by_info(cls, db: Session, post: PostModel):
async def get_post_detail_by_info(cls, db: AsyncSession, post: PostModel):
"""
根据岗位参数获取岗位信息
:param db: orm对象
:param post: 岗位参数对象
:return: 岗位信息对象
"""
post_info = db.query(SysPost) \
.filter(SysPost.post_name == post.post_name if post.post_name else True,
SysPost.post_code == post.post_code if post.post_code else True,
SysPost.post_sort == post.post_sort if post.post_sort else True) \
post_info = (
(
await db.execute(
select(SysPost).where(
SysPost.post_name == post.post_name if post.post_name else True,
SysPost.post_code == post.post_code if post.post_code else True,
SysPost.post_sort == post.post_sort if post.post_sort else True,
)
)
)
.scalars()
.first()
)
return post_info
@classmethod
def get_post_list(cls, db: Session, query_object: PostPageQueryModel, is_page: bool = False):
async def get_post_list(cls, db: AsyncSession, query_object: PostPageQueryModel, is_page: bool = False):
"""
根据查询参数获取岗位列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 岗位列表信息对象
"""
query = db.query(SysPost) \
.filter(SysPost.post_code.like(f'%{query_object.post_code}%') if query_object.post_code else True,
SysPost.post_name.like(f'%{query_object.post_name}%') if query_object.post_name else True,
SysPost.status == query_object.status if query_object.status else True
) \
.order_by(SysPost.post_sort) \
query = (
select(SysPost)
.where(
SysPost.post_code.like(f'%{query_object.post_code}%') if query_object.post_code else True,
SysPost.post_name.like(f'%{query_object.post_name}%') if query_object.post_name else True,
SysPost.status == query_object.status if query_object.status else True,
)
.order_by(SysPost.post_sort)
.distinct()
post_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
post_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return post_list
@classmethod
def add_post_dao(cls, db: Session, post: PostModel):
async def add_post_dao(cls, db: AsyncSession, post: PostModel):
"""
新增岗位数据库操作
:param db: orm对象
:param post: 岗位对象
:return:
"""
db_post = SysPost(**post.model_dump())
db.add(db_post)
db.flush()
await db.flush()
return db_post
@classmethod
def edit_post_dao(cls, db: Session, post: dict):
async def edit_post_dao(cls, db: AsyncSession, post: dict):
"""
编辑岗位数据库操作
:param db: orm对象
:param post: 需要更新的岗位字典
:return:
"""
db.query(SysPost) \
.filter(SysPost.post_id == post.get('post_id')) \
.update(post)
await db.execute(update(SysPost), [post])
@classmethod
def delete_post_dao(cls, db: Session, post: PostModel):
async def delete_post_dao(cls, db: AsyncSession, post: PostModel):
"""
删除岗位数据库操作
:param db: orm对象
:param post: 岗位对象
:return:
"""
db.query(SysPost) \
.filter(SysPost.post_id == post.post_id) \
.delete()
await db.execute(delete(SysPost).where(SysPost.post_id.in_([post.post_id])))
@classmethod
async def count_user_post_dao(cls, db: AsyncSession, post_id: int):
"""
根据岗位id查询岗位关联的用户数量
:param db: orm对象
:param post_id: 岗位id
:return: 岗位关联的用户数量
"""
user_post_count = (
await db.execute(select(func.count('*')).select_from(SysUserPost).where(SysUserPost.post_id == post_id))
).scalar()
return user_post_count

View File

@@ -1,10 +1,12 @@
from sqlalchemy import desc, func
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
from sqlalchemy import and_, delete, desc, func, or_, select, update # noqa: F401
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.do.menu_do import SysMenu
from module_admin.entity.do.role_do import SysRole, SysRoleMenu, SysRoleDept
from module_admin.entity.do.user_do import SysUser, SysUserRole
from module_admin.entity.vo.role_vo import RoleDeptModel, RoleMenuModel, RoleModel, RolePageQueryModel
from utils.page_util import PageUtil
class RoleDao:
@@ -13,159 +15,236 @@ class RoleDao:
"""
@classmethod
def get_role_by_name(cls, db: Session, role_name: str):
async def get_role_by_name(cls, db: AsyncSession, role_name: str):
"""
根据角色名获取在用角色信息
:param db: orm对象
:param role_name: 角色名
:return: 当前角色名的角色信息对象
"""
query_role_info = db.query(SysRole) \
.filter(SysRole.status == 0, SysRole.del_flag == 0, SysRole.role_name == role_name) \
.order_by(desc(SysRole.create_time)).distinct().first()
query_role_info = (
(
await db.execute(
select(SysRole)
.where(SysRole.status == '0', SysRole.del_flag == '0', SysRole.role_name == role_name)
.order_by(desc(SysRole.create_time))
.distinct()
)
)
.scalars()
.first()
)
return query_role_info
@classmethod
def get_role_by_info(cls, db: Session, role: RoleModel):
async def get_role_by_info(cls, db: AsyncSession, role: RoleModel):
"""
根据角色参数获取角色信息
:param db: orm对象
:param role: 角色参数
:return: 当前角色参数的角色信息对象
"""
query_role_info = db.query(SysRole) \
.filter(SysRole.del_flag == 0,
SysRole.role_name == role.role_name if role.role_name else True,
SysRole.role_key == role.role_key if role.role_key else True) \
.order_by(desc(SysRole.create_time)).distinct().first()
query_role_info = (
(
await db.execute(
select(SysRole)
.where(
SysRole.del_flag == '0',
SysRole.role_name == role.role_name if role.role_name else True,
SysRole.role_key == role.role_key if role.role_key else True,
)
.order_by(desc(SysRole.create_time))
.distinct()
)
)
.scalars()
.first()
)
return query_role_info
@classmethod
def get_role_by_id(cls, db: Session, role_id: int):
async def get_role_by_id(cls, db: AsyncSession, role_id: int):
"""
根据角色id获取在用角色信息
:param db: orm对象
:param role_id: 角色id
:return: 当前角色id的角色信息对象
"""
role_info = db.query(SysRole) \
.filter(SysRole.role_id == role_id,
SysRole.status == 0,
SysRole.del_flag == 0) \
role_info = (
(
await db.execute(
select(SysRole).where(SysRole.role_id == role_id, SysRole.status == '0', SysRole.del_flag == '0')
)
)
.scalars()
.first()
)
return role_info
@classmethod
def get_role_detail_by_id(cls, db: Session, role_id: int):
async def get_role_detail_by_id(cls, db: AsyncSession, role_id: int):
"""
根据role_id获取角色详细信息
:param db: orm对象
:param role_id: 角色id
:return: 当前role_id的角色信息对象
"""
query_role_info = db.query(SysRole) \
.filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \
.distinct().first()
query_role_info = (
(await db.execute(select(SysRole).where(SysRole.del_flag == '0', SysRole.role_id == role_id).distinct()))
.scalars()
.first()
)
return query_role_info
@classmethod
def get_role_select_option_dao(cls, db: Session):
async def get_role_select_option_dao(cls, db: AsyncSession):
"""
获取编辑页面对应的在用角色列表信息
:param db: orm对象
:return: 角色列表信息
"""
role_info = db.query(SysRole) \
.filter(SysRole.role_id != 1, SysRole.status == 0, SysRole.del_flag == 0) \
role_info = (
(
await db.execute(
select(SysRole).where(SysRole.role_id != 1, SysRole.status == '0', SysRole.del_flag == '0')
)
)
.scalars()
.all()
)
return role_info
@classmethod
def get_role_list(cls, db: Session, query_object: RolePageQueryModel, is_page: bool = False):
async def get_role_list(
cls, db: AsyncSession, query_object: RolePageQueryModel, data_scope_sql: str, is_page: bool = False
):
"""
根据查询参数获取角色列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:param is_page: 是否开启分页
:return: 角色列表信息对象
"""
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,
SysRole.status == query_object.status if query_object.status else True,
SysRole.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
) \
.order_by(SysRole.role_sort) \
query = (
select(SysRole)
.join(SysUserRole, SysUserRole.role_id == SysRole.role_id, isouter=True)
.join(SysUser, SysUser.user_id == SysUserRole.user_id, isouter=True)
.join(SysDept, SysDept.dept_id == SysUser.dept_id, isouter=True)
.where(
SysRole.del_flag == '0',
SysRole.role_id == query_object.role_id if query_object.role_id is not None else True,
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,
SysRole.status == query_object.status if query_object.status else True,
SysRole.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),
)
.order_by(SysRole.role_sort)
.distinct()
role_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
role_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return role_list
@classmethod
def add_role_dao(cls, db: Session, role: RoleModel):
async def add_role_dao(cls, db: AsyncSession, role: RoleModel):
"""
新增角色数据库操作
:param db: orm对象
:param role: 角色对象
:return:
"""
db_role = SysRole(**role.model_dump(exclude={'admin'}))
db.add(db_role)
db.flush()
await db.flush()
return db_role
@classmethod
def edit_role_dao(cls, db: Session, role: dict):
async def edit_role_dao(cls, db: AsyncSession, role: dict):
"""
编辑角色数据库操作
:param db: orm对象
:param role: 需要更新的角色字典
:return:
"""
db.query(SysRole) \
.filter(SysRole.role_id == role.get('role_id')) \
.update(role)
await db.execute(update(SysRole), [role])
@classmethod
def delete_role_dao(cls, db: Session, role: RoleModel):
async def delete_role_dao(cls, db: AsyncSession, role: RoleModel):
"""
删除角色数据库操作
:param db: orm对象
:param role: 角色对象
:return:
"""
db.query(SysRole) \
.filter(SysRole.role_id == role.role_id) \
.update({SysRole.del_flag: '2', SysRole.update_by: role.update_by, SysRole.update_time: role.update_time})
await db.execute(
update(SysRole)
.where(SysRole.role_id == role.role_id)
.values(del_flag='2', update_by=role.update_by, update_time=role.update_time)
)
@classmethod
def get_role_menu_dao(cls, db: Session, role_id: int):
async def get_role_menu_dao(cls, db: AsyncSession, role: RoleModel):
"""
根据角色id获取角色菜单关联列表信息
:param db: orm对象
:param role_id: 角色id
:param role: 角色对象
:return: 角色菜单关联列表信息
"""
role_menu_query_all = db.query(SysRoleMenu) \
.filter(SysRoleMenu.role_id == role_id) \
.distinct().all()
role_menu_query_all = (
(
await db.execute(
select(SysMenu)
.join(SysRoleMenu, SysRoleMenu.menu_id == SysMenu.menu_id)
.where(
SysRoleMenu.role_id == role.role_id,
~SysMenu.menu_id.in_(
select(SysMenu.parent_id)
.select_from(SysMenu)
.join(
SysRoleMenu,
and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysRoleMenu.role_id == role.role_id),
)
)
if role.menu_check_strictly
else True,
)
.order_by(SysMenu.parent_id, SysMenu.order_num)
)
)
.scalars()
.all()
)
return role_menu_query_all
@classmethod
def add_role_menu_dao(cls, db: Session, role_menu: RoleMenuModel):
async def add_role_menu_dao(cls, db: AsyncSession, role_menu: RoleMenuModel):
"""
新增角色菜单关联信息数据库操作
:param db: orm对象
:param role_menu: 用户角色菜单关联对象
:return:
@@ -174,37 +253,57 @@ class RoleDao:
db.add(db_role_menu)
@classmethod
def delete_role_menu_dao(cls, db: Session, role_menu: RoleMenuModel):
async def delete_role_menu_dao(cls, db: AsyncSession, role_menu: RoleMenuModel):
"""
删除角色菜单关联信息数据库操作
:param db: orm对象
:param role_menu: 角色菜单关联对象
:return:
"""
db.query(SysRoleMenu) \
.filter(SysRoleMenu.role_id == role_menu.role_id) \
.delete()
await db.execute(delete(SysRoleMenu).where(SysRoleMenu.role_id.in_([role_menu.role_id])))
@classmethod
def get_role_dept_dao(cls, db: Session, role_id: int):
async def get_role_dept_dao(cls, db: AsyncSession, role: RoleModel):
"""
根据角色id获取角色部门关联列表信息
:param db: orm对象
:param role_id: 角色id
:param role: 角色对象
:return: 角色部门关联列表信息
"""
role_dept_query_all = db.query(SysRoleDept) \
.filter(SysRoleDept.role_id == role_id,
~db.query(SysDept).filter(func.find_in_set(SysRoleDept.dept_id, SysDept.ancestors)).exists()
) \
.distinct().all()
role_dept_query_all = (
(
await db.execute(
select(SysDept)
.join(SysRoleDept, SysRoleDept.dept_id == SysDept.dept_id)
.where(
SysRoleDept.role_id == role.role_id,
~SysDept.dept_id.in_(
select(SysDept.parent_id)
.select_from(SysDept)
.join(
SysRoleDept,
and_(SysRoleDept.dept_id == SysDept.dept_id, SysRoleDept.role_id == role.role_id),
)
)
if role.dept_check_strictly
else True,
)
.order_by(SysDept.parent_id, SysDept.order_num)
)
)
.scalars()
.all()
)
return role_dept_query_all
@classmethod
def add_role_dept_dao(cls, db: Session, role_dept: RoleDeptModel):
async def add_role_dept_dao(cls, db: AsyncSession, role_dept: RoleDeptModel):
"""
新增角色部门关联信息数据库操作
:param db: orm对象
:param role_dept: 用户角色部门关联对象
:return:
@@ -213,13 +312,27 @@ class RoleDao:
db.add(db_role_dept)
@classmethod
def delete_role_dept_dao(cls, db: Session, role_dept: RoleDeptModel):
async def delete_role_dept_dao(cls, db: AsyncSession, role_dept: RoleDeptModel):
"""
删除角色部门关联信息数据库操作
:param db: orm对象
:param role_dept: 角色部门关联对象
:return:
"""
db.query(SysRoleDept) \
.filter(SysRoleDept.role_id == role_dept.role_id) \
.delete()
await db.execute(delete(SysRoleDept).where(SysRoleDept.role_id.in_([role_dept.role_id])))
@classmethod
async def count_user_role_dao(cls, db: AsyncSession, role_id: int):
"""
根据角色id查询角色关联用户数量
:param db: orm对象
:param role_id: 角色id
:return: 角色关联用户数量
"""
user_count = (
await db.execute(select(func.count('*')).select_from(SysUserRole).where(SysUserRole.role_id == role_id))
).scalar()
return user_count

View File

@@ -1,13 +1,20 @@
from sqlalchemy import and_, or_, desc, func
from sqlalchemy.orm import Session
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 utils.page_util import PageUtil
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.dept_do import SysDept
from module_admin.entity.do.menu_do import SysMenu
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
class UserDao:
@@ -16,268 +23,457 @@ class UserDao:
"""
@classmethod
def get_user_by_name(cls, db: Session, user_name: str):
async def get_user_by_name(cls, db: AsyncSession, user_name: str):
"""
根据用户名获取用户信息
:param db: orm对象
:param user_name: 用户名
:return: 当前用户名的用户信息对象
"""
query_user_info = db.query(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_name == user_name) \
.order_by(desc(SysUser.create_time)).distinct().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
@classmethod
def get_user_by_info(cls, db: Session, user: UserModel):
async def get_user_by_info(cls, db: AsyncSession, user: UserModel):
"""
根据用户参数获取用户信息
:param db: orm对象
:param user: 用户参数
:return: 当前用户参数的用户信息对象
"""
query_user_info = db.query(SysUser) \
.filter(SysUser.del_flag == 0,
SysUser.user_name == user.user_name) \
.order_by(desc(SysUser.create_time)).distinct().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
@classmethod
def get_user_by_id(cls, db: Session, user_id: int):
async def get_user_by_id(cls, db: AsyncSession, user_id: int):
"""
根据user_id获取用户信息
:param db: orm对象
:param user_id: 用户id
:return: 当前user_id的用户信息对象
"""
query_user_basic_info = db.query(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.distinct().first()
query_user_dept_info = db.query(SysDept).select_from(SysUser) \
.filter(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().first()
query_user_role_info = db.query(SysRole).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.distinct().all()
query_user_post_info = db.query(SysPost).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \
.join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \
.distinct().all()
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 = db.query(SysMenu) \
.filter(SysMenu.status == 0) \
.distinct().all()
query_user_menu_info = (
(await db.execute(select(SysMenu).where(SysMenu.status == '0').distinct())).scalars().all()
)
else:
query_user_menu_info = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \
.order_by(SysMenu.order_num) \
.distinct().all()
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
@classmethod
def get_user_detail_by_id(cls, db: Session, user_id: int):
async def get_user_detail_by_id(cls, db: AsyncSession, user_id: int):
"""
根据user_id获取用户详细信息
:param db: orm对象
:param user_id: 用户id
:return: 当前user_id的用户信息对象
"""
query_user_basic_info = db.query(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.distinct().first()
query_user_dept_info = db.query(SysDept).select_from(SysUser) \
.filter(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().first()
query_user_role_info = db.query(SysRole).select_from(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.distinct().all()
query_user_post_info = db.query(SysPost).select_from(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \
.join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \
.distinct().all()
query_user_menu_info = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \
.distinct().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
def get_user_list(cls, db: Session, 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对象
:param query_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:param is_page: 是否开启分页
:return: 用户列表信息对象
"""
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))
)) if query_object.dept_id 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)
) \
.outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \
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,
)
.order_by(SysUser.user_id)
.distinct()
user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
)
user_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return user_list
@classmethod
def add_user_dao(cls, db: Session, user: UserModel):
async def add_user_dao(cls, db: AsyncSession, user: UserModel):
"""
新增用户数据库操作
:param db: orm对象
:param user: 用户对象
:return: 新增校验结果
"""
db_user = SysUser(**user.model_dump(exclude={'admin'}))
db.add(db_user)
db.flush()
await db.flush()
return db_user
@classmethod
def edit_user_dao(cls, db: Session, user: dict):
async def edit_user_dao(cls, db: AsyncSession, user: dict):
"""
编辑用户数据库操作
:param db: orm对象
:param user: 需要更新的用户字典
:return: 编辑校验结果
"""
db.query(SysUser) \
.filter(SysUser.user_id == user.get('user_id')) \
.update(user)
await db.execute(update(SysUser), [user])
@classmethod
def delete_user_dao(cls, db: Session, user: UserModel):
async def delete_user_dao(cls, db: AsyncSession, user: UserModel):
"""
删除用户数据库操作
:param db: orm对象
:param user: 用户对象
:return:
"""
db.query(SysUser) \
.filter(SysUser.user_id == user.user_id) \
.update({SysUser.del_flag: '2', SysUser.update_by: user.update_by, SysUser.update_time: user.update_time})
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)
)
@classmethod
def get_user_role_allocated_list_by_user_id(cls, db: Session, query_object: UserRoleQueryModel):
async def get_user_role_allocated_list_by_user_id(cls, db: AsyncSession, query_object: UserRoleQueryModel):
"""
根据用户id获取用户已分配的角色列表信息数据库操作
:param db: orm对象
:param query_object: 用户角色查询对象
:return: 用户已分配的角色列表信息
"""
allocated_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)
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()
)
)
).distinct().all()
.scalars()
.all()
)
return allocated_role_list
@classmethod
def get_user_role_allocated_list_by_role_id(cls, db: Session, query_object: UserRolePageQueryModel, 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对象
:param query_object: 用户角色查询对象
:param data_scope_sql: 数据权限对应的查询sql语句
:param is_page: 是否开启分页
:return: 角色已分配的用户列表信息
"""
query = db.query(SysUser) \
.filter(
SysUser.del_flag == 0,
SysUser.user_id != 1,
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,
SysUser.user_id.in_(
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
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 = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
.distinct()
)
allocated_user_list = await PageUtil.paginate(db, 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: UserRolePageQueryModel, 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对象
:param query_object: 用户角色查询对象
:param data_scope_sql: 数据权限对应的查询sql语句
:param is_page: 是否开启分页
:return: 角色未分配的用户列表信息
"""
query = db.query(SysUser) \
.filter(
SysUser.del_flag == 0,
SysUser.user_id != 1,
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,
~SysUser.user_id.in_(
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
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 = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
.distinct()
)
unallocated_user_list = await PageUtil.paginate(
db, query, query_object.page_num, query_object.page_size, is_page
)
return unallocated_user_list
@classmethod
def add_user_role_dao(cls, db: Session, user_role: UserRoleModel):
async def add_user_role_dao(cls, db: AsyncSession, user_role: UserRoleModel):
"""
新增用户角色关联信息数据库操作
:param db: orm对象
:param user_role: 用户角色关联对象
:return:
@@ -286,48 +482,60 @@ class UserDao:
db.add(db_user_role)
@classmethod
def delete_user_role_dao(cls, db: Session, user_role: UserRoleModel):
async def delete_user_role_dao(cls, db: AsyncSession, user_role: UserRoleModel):
"""
删除用户角色关联信息数据库操作
:param db: orm对象
:param user_role: 用户角色关联对象
:return:
"""
db.query(SysUserRole) \
.filter(SysUserRole.user_id == user_role.user_id) \
.delete()
await db.execute(delete(SysUserRole).where(SysUserRole.user_id.in_([user_role.user_id])))
@classmethod
def delete_user_role_by_user_and_role_dao(cls, db: Session, user_role: UserRoleModel):
async def delete_user_role_by_user_and_role_dao(cls, db: AsyncSession, user_role: UserRoleModel):
"""
根据用户id及角色id删除用户角色关联信息数据库操作
:param db: orm对象
:param user_role: 用户角色关联对象
:return:
"""
db.query(SysUserRole) \
.filter(SysUserRole.user_id == user_role.user_id,
SysUserRole.role_id == user_role.role_id if user_role.role_id else True) \
.delete()
await db.execute(
delete(SysUserRole).where(
SysUserRole.user_id == user_role.user_id if user_role.user_id else True,
SysUserRole.role_id == user_role.role_id if user_role.role_id else True,
)
)
@classmethod
def get_user_role_detail(cls, db: Session, user_role: UserRoleModel):
async def get_user_role_detail(cls, db: AsyncSession, user_role: UserRoleModel):
"""
根据用户角色关联获取用户角色关联详细信息
:param db: orm对象
:param user_role: 用户角色关联对象
:return: 用户角色关联信息
"""
user_role_info = db.query(SysUserRole) \
.filter(SysUserRole.user_id == user_role.user_id, SysUserRole.role_id == user_role.role_id) \
.distinct().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
@classmethod
def add_user_post_dao(cls, db: Session, user_post: UserPostModel):
async def add_user_post_dao(cls, db: AsyncSession, user_post: UserPostModel):
"""
新增用户岗位关联信息数据库操作
:param db: orm对象
:param user_post: 用户岗位关联对象
:return:
@@ -336,22 +544,25 @@ class UserDao:
db.add(db_user_post)
@classmethod
def delete_user_post_dao(cls, db: Session, user_post: UserPostModel):
async def delete_user_post_dao(cls, db: AsyncSession, user_post: UserPostModel):
"""
删除用户岗位关联信息数据库操作
:param db: orm对象
:param user_post: 用户岗位关联对象
:return:
"""
db.query(SysUserPost) \
.filter(SysUserPost.user_id == user_post.user_id) \
.delete()
await db.execute(delete(SysUserPost).where(SysUserPost.user_id.in_([user_post.user_id])))
@classmethod
def get_user_dept_info(cls, db: Session, dept_id: int):
dept_basic_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.status == 0,
SysDept.del_flag == 0) \
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()
)
return dept_basic_info

View File

@@ -1,12 +1,13 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysConfig(Base):
"""
参数配置表
"""
__tablename__ = 'sys_config'
config_id = Column(Integer, primary_key=True, autoincrement=True, comment='参数主键')
@@ -18,4 +19,4 @@ class SysConfig(Base):
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), nullable=True, default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500), nullable=True, default='', comment='备注')
remark = Column(String(500), nullable=True, default=None, comment='备注')

View File

@@ -1,12 +1,13 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysDept(Base):
"""
部门表
"""
__tablename__ = 'sys_dept'
dept_id = Column(Integer, primary_key=True, autoincrement=True, comment='部门id')
@@ -17,8 +18,8 @@ class SysDept(Base):
leader = Column(String(20), nullable=True, default=None, comment='负责人')
phone = Column(String(11), nullable=True, default=None, comment='联系电话')
email = Column(String(50), nullable=True, default=None, comment='邮箱')
status = Column(String(1), nullable=True, default=0, comment='部门状态0正常 1停用')
del_flag = Column(String(1), nullable=True, default=0, comment='删除标志0代表存在 2代表删除')
status = Column(String(1), nullable=True, default='0', comment='部门状态0正常 1停用')
del_flag = Column(String(1), nullable=True, default='0', comment='删除标志0代表存在 2代表删除')
create_by = Column(String(64), nullable=True, default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), nullable=True, default='', comment='更新者')

View File

@@ -1,12 +1,13 @@
from sqlalchemy import Column, Integer, String, DateTime, UniqueConstraint
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String, UniqueConstraint
from config.database import Base
class SysDictType(Base):
"""
字典类型表
"""
__tablename__ = 'sys_dict_type'
dict_id = Column(Integer, primary_key=True, autoincrement=True, comment='字典主键')
@@ -17,17 +18,16 @@ class SysDictType(Base):
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), nullable=True, default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500), nullable=True, default='', comment='备注')
remark = Column(String(500), nullable=True, default=None, comment='备注')
__table_args__ = (
UniqueConstraint('dict_type', name='uq_sys_dict_type_dict_type'),
)
__table_args__ = (UniqueConstraint('dict_type', name='uq_sys_dict_type_dict_type'),)
class SysDictData(Base):
"""
字典数据表
"""
__tablename__ = 'sys_dict_data'
dict_code = Column(Integer, primary_key=True, autoincrement=True, comment='字典编码')
@@ -35,12 +35,12 @@ class SysDictData(Base):
dict_label = Column(String(100), nullable=True, default='', comment='字典标签')
dict_value = Column(String(100), nullable=True, default='', comment='字典键值')
dict_type = Column(String(100), nullable=True, default='', comment='字典类型')
css_class = Column(String(100), nullable=True, default='', comment='样式属性(其他样式扩展)')
list_class = Column(String(100), nullable=True, default='', comment='表格回显样式')
css_class = Column(String(100), nullable=True, default=None, comment='样式属性(其他样式扩展)')
list_class = Column(String(100), nullable=True, default=None, comment='表格回显样式')
is_default = Column(String(1), nullable=True, default='N', comment='是否默认Y是 N否')
status = Column(String(1), nullable=True, default='0', comment='状态0正常 1停用')
create_by = Column(String(64), nullable=True, default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), nullable=True, default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500), nullable=True, default='', comment='备注')
remark = Column(String(500), nullable=True, default=None, comment='备注')

View File

@@ -1,47 +1,54 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysJob(Base):
"""
定时任务调度表
"""
__tablename__ = 'sys_job'
job_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务ID')
job_name = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务名称')
job_group = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务组名')
job_executor = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务执行器')
invoke_target = Column(String(500, collation='utf8_general_ci'), nullable=False, comment='调用目标字符串')
job_args = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='位置参数')
job_kwargs = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='关键字参数')
cron_expression = Column(String(255, collation='utf8_general_ci'), nullable=True, default='', comment='cron执行表达式')
misfire_policy = Column(String(20, collation='utf8_general_ci'), nullable=True, default='3', comment='计划执行错误策略1立即执行 2执行一次 3放弃执行')
concurrent = Column(String(1, collation='utf8_general_ci'), nullable=True, default='1', comment='是否并发执行0允许 1禁止')
status = Column(String(1, collation='utf8_general_ci'), nullable=True, default='0', comment='状态0正常 1暂停')
create_by = Column(String(64, collation='utf8_general_ci'), nullable=True, default='', comment='创建者')
job_name = Column(String(64), nullable=True, default='', comment='任务名称')
job_group = Column(String(64), nullable=True, default='default', comment='任务组名')
job_executor = Column(String(64), nullable=True, default='default', comment='任务执行器')
invoke_target = Column(String(500), nullable=False, comment='调用目标字符串')
job_args = Column(String(255), nullable=True, default='', comment='位置参数')
job_kwargs = Column(String(255), nullable=True, default='', comment='关键字参数')
cron_expression = Column(String(255), nullable=True, default='', comment='cron执行表达式')
misfire_policy = Column(
String(20),
nullable=True,
default='3',
comment='计划执行错误策略1立即执行 2执行一次 3放弃执行',
)
concurrent = Column(String(1), nullable=True, default='1', comment='是否并发执行0允许 1禁止')
status = Column(String(1), nullable=True, default='0', comment='状态0正常 1暂停')
create_by = Column(String(64), nullable=True, default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64, collation='utf8_general_ci'), nullable=True, default='', comment='更新者')
update_by = Column(String(64), nullable=True, default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500, collation='utf8_general_ci'), nullable=True, default='', comment='备注信息')
remark = Column(String(500), nullable=True, default='', comment='备注信息')
class SysJobLog(Base):
"""
定时任务调度日志表
"""
__tablename__ = 'sys_job_log'
job_log_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务日志ID')
job_name = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务名称')
job_group = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务组名')
job_executor = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务执行器')
invoke_target = Column(String(500, collation='utf8_general_ci'), nullable=False, comment='调用目标字符串')
job_args = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='位置参数')
job_kwargs = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='关键字参数')
job_trigger = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='任务触发器')
job_message = Column(String(500, collation='utf8_general_ci'), nullable=True, default='', comment='日志信息')
status = Column(String(1, collation='utf8_general_ci'), nullable=True, default='0', comment='执行状态0正常 1失败')
exception_info = Column(String(2000, collation='utf8_general_ci'), nullable=True, default='', comment='异常信息')
job_name = Column(String(64), nullable=False, comment='任务名称')
job_group = Column(String(64), nullable=False, comment='任务组名')
job_executor = Column(String(64), nullable=False, comment='任务执行器')
invoke_target = Column(String(500), nullable=False, comment='调用目标字符串')
job_args = Column(String(255), nullable=True, default='', comment='位置参数')
job_kwargs = Column(String(255), nullable=True, default='', comment='关键字参数')
job_trigger = Column(String(255), nullable=True, default='', comment='任务触发器')
job_message = Column(String(500), nullable=True, default='', comment='日志信息')
status = Column(String(1), nullable=True, default='0', comment='执行状态0正常 1失败')
exception_info = Column(String(2000), nullable=True, default='', comment='异常信息')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')

View File

@@ -1,22 +1,23 @@
from sqlalchemy import Column, Integer, String, DateTime, Text, BigInteger, Index
from config.database import Base
from datetime import datetime
from sqlalchemy import BigInteger, Column, DateTime, Index, Integer, String
from config.database import Base
class SysLogininfor(Base):
"""
系统访问记录
"""
__tablename__ = 'sys_logininfor'
info_id = Column(Integer, primary_key=True, autoincrement=True, comment='访问ID')
user_name = Column(String(50, collation='utf8_general_ci'), nullable=True, default='', comment='用户账号')
ipaddr = Column(String(128, collation='utf8_general_ci'), nullable=True, default='', comment='登录IP地址')
login_location = Column(String(255, collation='utf8_general_ci'), nullable=True, default='', comment='登录地点')
browser = Column(String(50, collation='utf8_general_ci'), nullable=True, default='', comment='浏览器类型')
os = Column(String(50, collation='utf8_general_ci'), nullable=True, default='', comment='操作系统')
status = Column(String(1, collation='utf8_general_ci'), nullable=True, default='0', comment='登录状态0成功 1失败')
msg = Column(String(255, collation='utf8_general_ci'), nullable=True, default='', comment='提示消息')
user_name = Column(String(50), nullable=True, default='', comment='用户账号')
ipaddr = Column(String(128), nullable=True, default='', comment='登录IP地址')
login_location = Column(String(255), nullable=True, default='', comment='登录地点')
browser = Column(String(50), nullable=True, default='', comment='浏览器类型')
os = Column(String(50), nullable=True, default='', comment='操作系统')
status = Column(String(1), nullable=True, default='0', comment='登录状态0成功 1失败')
msg = Column(String(255), nullable=True, default='', comment='提示消息')
login_time = Column(DateTime, nullable=True, default=datetime.now(), comment='访问时间')
idx_sys_logininfor_s = Index('idx_sys_logininfor_s', status)
@@ -27,23 +28,24 @@ class SysOperLog(Base):
"""
操作日志记录
"""
__tablename__ = 'sys_oper_log'
oper_id = Column(BigInteger, primary_key=True, autoincrement=True, comment='日志主键')
title = Column(String(50, collation='utf8_general_ci'), nullable=True, default='', comment='模块标题')
title = Column(String(50), nullable=True, default='', comment='模块标题')
business_type = Column(Integer, default=0, comment='业务类型0其它 1新增 2修改 3删除')
method = Column(String(100, collation='utf8_general_ci'), nullable=True, default='', comment='方法名称')
request_method = Column(String(10, collation='utf8_general_ci'), nullable=True, default='', comment='请求方式')
method = Column(String(100), nullable=True, default='', comment='方法名称')
request_method = Column(String(10), nullable=True, default='', comment='请求方式')
operator_type = Column(Integer, default=0, comment='操作类别0其它 1后台用户 2手机端用户')
oper_name = Column(String(50, collation='utf8_general_ci'), nullable=True, default='', comment='操作人员')
dept_name = Column(String(50, collation='utf8_general_ci'), nullable=True, default='', comment='部门名称')
oper_url = Column(String(255, collation='utf8_general_ci'), nullable=True, default='', comment='请求URL')
oper_ip = Column(String(128, collation='utf8_general_ci'), nullable=True, default='', comment='主机地址')
oper_location = Column(String(255, collation='utf8_general_ci'), nullable=True, default='', comment='操作地点')
oper_param = Column(String(2000, collation='utf8_general_ci'), nullable=True, default='', comment='请求参数')
json_result = Column(String(2000, collation='utf8_general_ci'), nullable=True, default='', comment='返回参数')
oper_name = Column(String(50), nullable=True, default='', comment='操作人员')
dept_name = Column(String(50), nullable=True, default='', comment='部门名称')
oper_url = Column(String(255), nullable=True, default='', comment='请求URL')
oper_ip = Column(String(128), nullable=True, default='', comment='主机地址')
oper_location = Column(String(255), nullable=True, default='', comment='操作地点')
oper_param = Column(String(2000), nullable=True, default='', comment='请求参数')
json_result = Column(String(2000), nullable=True, default='', comment='返回参数')
status = Column(Integer, default=0, comment='操作状态0正常 1异常')
error_msg = Column(String(2000, collation='utf8_general_ci'), nullable=True, default='', comment='错误消息')
error_msg = Column(String(2000), nullable=True, default='', comment='错误消息')
oper_time = Column(DateTime, nullable=True, default=datetime.now(), comment='操作时间')
cost_time = Column(BigInteger, default=0, comment='消耗时间')

View File

@@ -1,12 +1,13 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysMenu(Base):
"""
菜单权限表
"""
__tablename__ = 'sys_menu'
menu_id = Column(Integer, primary_key=True, autoincrement=True, comment='菜单ID')
@@ -16,6 +17,7 @@ class SysMenu(Base):
path = Column(String(200), nullable=True, default='', comment='路由地址')
component = Column(String(255), nullable=True, default=None, comment='组件路径')
query = Column(String(255), nullable=True, default=None, comment='路由参数')
route_name = Column(String(50), nullable=True, default='', comment='路由名称')
is_frame = Column(Integer, default=1, comment='是否为外链0是 1否')
is_cache = Column(Integer, default=0, comment='是否缓存0缓存 1不缓存')
menu_type = Column(String(1), nullable=True, default='', comment='菜单类型M目录 C菜单 F按钮')

View File

@@ -1,21 +1,22 @@
from sqlalchemy import Column, Integer, String, DateTime, LargeBinary
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, LargeBinary, String
from config.database import Base
class SysNotice(Base):
"""
通知公告表
"""
__tablename__ = 'sys_notice'
notice_id = Column(Integer, primary_key=True, autoincrement=True, comment='公告ID')
notice_title = Column(String(50, collation='utf8_general_ci'), nullable=False, comment='公告标题')
notice_type = Column(String(1, collation='utf8_general_ci'), nullable=False, comment='公告类型1通知 2公告')
notice_title = Column(String(50), nullable=False, comment='公告标题')
notice_type = Column(String(1), nullable=False, comment='公告类型1通知 2公告')
notice_content = Column(LargeBinary, comment='公告内容')
status = Column(String(1, collation='utf8_general_ci'), default='0', comment='公告状态0正常 1关闭')
create_by = Column(String(64, collation='utf8_general_ci'), default='', comment='创建者')
status = Column(String(1), default='0', comment='公告状态0正常 1关闭')
create_by = Column(String(64), default='', comment='创建者')
create_time = Column(DateTime, comment='创建时间', default=datetime.now())
update_by = Column(String(64, collation='utf8_general_ci'), default='', comment='更新者')
update_by = Column(String(64), default='', comment='更新者')
update_time = Column(DateTime, comment='更新时间', default=datetime.now())
remark = Column(String(255, collation='utf8_general_ci'), comment='备注')
remark = Column(String(255), comment='备注')

View File

@@ -1,12 +1,13 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysPost(Base):
"""
岗位信息表
"""
__tablename__ = 'sys_post'
post_id = Column(Integer, primary_key=True, autoincrement=True, comment='岗位ID')
@@ -18,4 +19,4 @@ class SysPost(Base):
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500), nullable=True, default='', comment='备注')
remark = Column(String(500), nullable=True, default=None, comment='备注')

View File

@@ -1,34 +1,40 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysRole(Base):
"""
角色信息表
"""
__tablename__ = 'sys_role'
role_id = Column(Integer, primary_key=True, autoincrement=True, comment='角色ID')
role_name = Column(String(30, collation='utf8_general_ci'), nullable=False, comment='角色名称')
role_key = Column(String(100, collation='utf8_general_ci'), nullable=False, comment='角色权限字符串')
role_name = Column(String(30), nullable=False, comment='角色名称')
role_key = Column(String(100), nullable=False, comment='角色权限字符串')
role_sort = Column(Integer, nullable=False, comment='显示顺序')
data_scope = Column(String(1, collation='utf8_general_ci'), default='1', comment='数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限')
data_scope = Column(
String(1),
default='1',
comment='数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限',
)
menu_check_strictly = Column(Integer, default=1, comment='菜单树选择项是否关联显示')
dept_check_strictly = Column(Integer, default=1, comment='部门树选择项是否关联显示')
status = Column(String(1, collation='utf8_general_ci'), nullable=False, comment='角色状态0正常 1停用')
del_flag = Column(String(1, collation='utf8_general_ci'), default='0', comment='删除标志0代表存在 2代表删除')
create_by = Column(String(64, collation='utf8_general_ci'), default='', comment='创建者')
status = Column(String(1), nullable=False, default='0', comment='角色状态0正常 1停用')
del_flag = Column(String(1), default='0', comment='删除标志0代表存在 2代表删除')
create_by = Column(String(64), default='', comment='创建者')
create_time = Column(DateTime, default=datetime.now(), comment='创建时间')
update_by = Column(String(64, collation='utf8_general_ci'), default='', comment='更新者')
update_by = Column(String(64), default='', comment='更新者')
update_time = Column(DateTime, default=datetime.now(), comment='更新时间')
remark = Column(String(500, collation='utf8_general_ci'), comment='备注')
remark = Column(String(500), default=None, comment='备注')
class SysRoleDept(Base):
"""
角色和部门关联表
"""
__tablename__ = 'sys_role_dept'
role_id = Column(Integer, primary_key=True, nullable=False, comment='角色ID')
@@ -39,6 +45,7 @@ class SysRoleMenu(Base):
"""
角色和菜单关联表
"""
__tablename__ = 'sys_role_menu'
role_id = Column(Integer, primary_key=True, nullable=False, comment='角色ID')

View File

@@ -1,39 +1,41 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysUser(Base):
"""
用户信息表
"""
__tablename__ = 'sys_user'
user_id = Column(Integer, primary_key=True, autoincrement=True, comment='用户ID')
dept_id = Column(Integer, comment='部门ID')
user_name = Column(String(30, collation='utf8_general_ci'), nullable=False, comment='用户账号')
nick_name = Column(String(30, collation='utf8_general_ci'), nullable=False, comment='用户昵称')
user_type = Column(String(2, collation='utf8_general_ci'), default='00', comment='用户类型00系统用户')
email = Column(String(50, collation='utf8_general_ci'), default='', comment='用户邮箱')
phonenumber = Column(String(11, collation='utf8_general_ci'), default='', comment='手机号码')
sex = Column(String(1, collation='utf8_general_ci'), default='0', comment='用户性别0男 1女 2未知')
avatar = Column(String(100, collation='utf8_general_ci'), default='', comment='头像地址')
password = Column(String(100, collation='utf8_general_ci'), default='', comment='密码')
status = Column(String(1, collation='utf8_general_ci'), default='0', comment='帐号状态0正常 1停用')
del_flag = Column(String(1, collation='utf8_general_ci'), default='0', comment='删除标志0代表存在 2代表删除')
login_ip = Column(String(128, collation='utf8_general_ci'), default='', comment='最后登录IP')
dept_id = Column(Integer, default=None, comment='部门ID')
user_name = Column(String(30), nullable=False, comment='用户账号')
nick_name = Column(String(30), nullable=False, comment='用户昵称')
user_type = Column(String(2), default='00', comment='用户类型00系统用户')
email = Column(String(50), default='', comment='用户邮箱')
phonenumber = Column(String(11), default='', comment='手机号码')
sex = Column(String(1), default='0', comment='用户性别0男 1女 2未知')
avatar = Column(String(100), default='', comment='头像地址')
password = Column(String(100), default='', comment='密码')
status = Column(String(1), default='0', comment='帐号状态0正常 1停用')
del_flag = Column(String(1), default='0', comment='删除标志0代表存在 2代表删除')
login_ip = Column(String(128), default='', comment='最后登录IP')
login_date = Column(DateTime, comment='最后登录时间')
create_by = Column(String(64, collation='utf8_general_ci'), default='', comment='创建者')
create_by = Column(String(64), default='', comment='创建者')
create_time = Column(DateTime, comment='创建时间', default=datetime.now())
update_by = Column(String(64, collation='utf8_general_ci'), default='', comment='更新者')
update_by = Column(String(64), default='', comment='更新者')
update_time = Column(DateTime, comment='更新时间', default=datetime.now())
remark = Column(String(500, collation='utf8_general_ci'), comment='备注')
remark = Column(String(500), default=None, comment='备注')
class SysUserRole(Base):
"""
用户和角色关联表
"""
__tablename__ = 'sys_user_role'
user_id = Column(Integer, primary_key=True, nullable=False, comment='用户ID')
@@ -44,6 +46,7 @@ class SysUserPost(Base):
"""
用户与岗位关联表
"""
__tablename__ = 'sys_user_post'
user_id = Column(Integer, primary_key=True, nullable=False, comment='用户ID')

View File

@@ -1,26 +1,28 @@
from pydantic import BaseModel, ConfigDict
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import Optional, List, Any
from typing import Any, List, Optional
class CacheMonitorModel(BaseModel):
"""
缓存监控信息对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
command_stats: Optional[List] = []
db_size: Optional[int] = None
info: Optional[dict] = {}
command_stats: Optional[List] = Field(default=[], description='命令统计')
db_size: Optional[int] = Field(default=None, description='Key数量')
info: Optional[dict] = Field(default={}, description='Redis信息')
class CacheInfoModel(BaseModel):
"""
缓存监控对象对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
cache_key: Optional[str] = None
cache_name: Optional[str] = None
cache_value: Optional[Any] = None
remark: Optional[str] = None
cache_key: Optional[str] = Field(default=None, description='缓存键名')
cache_name: Optional[str] = Field(default=None, description='缓存名称')
cache_value: Optional[Any] = Field(default=None, description='缓存内容')
remark: Optional[str] = Field(default=None, description='备注')

View File

@@ -1,24 +1,26 @@
from pydantic import BaseModel, ConfigDict
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import Optional, Any
from typing import Any, Optional
class CrudResponseModel(BaseModel):
"""
操作响应模型
"""
is_success: bool
message: str
result: Optional[Any] = None
is_success: bool = Field(description='操作是否成功')
message: str = Field(description='响应信息')
result: Optional[Any] = Field(default=None, description='响应结果')
class UploadResponseModel(BaseModel):
"""
上传响应模型
"""
model_config = ConfigDict(alias_generator=to_camel)
file_name: Optional[str] = None
new_file_name: Optional[str] = None
original_filename: Optional[str] = None
url: Optional[str] = None
file_name: Optional[str] = Field(default=None, description='新文件映射路径')
new_file_name: Optional[str] = Field(default=None, description='新文件名称')
original_filename: Optional[str] = Field(default=None, description='原文件名称')
url: Optional[str] = Field(default=None, description='新文件url')

View File

@@ -1,50 +1,74 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Size
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
class ConfigModel(BaseModel):
"""
参数配置表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
config_id: Optional[int] = None
config_name: Optional[str] = None
config_key: Optional[str] = None
config_value: Optional[str] = None
config_type: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
config_id: Optional[int] = Field(default=None, description='参数主键')
config_name: Optional[str] = Field(default=None, description='参数名称')
config_key: Optional[str] = Field(default=None, description='参数键名')
config_value: Optional[str] = Field(default=None, description='参数键值')
config_type: Optional[Literal['Y', 'N']] = Field(default=None, description='系统内置Y是 N否')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
@NotBlank(field_name='config_key', message='参数名称不能为空')
@Size(field_name='config_key', min_length=0, max_length=100, message='参数名称长度不能超过100个字符')
def get_config_key(self):
return self.config_key
@NotBlank(field_name='config_name', message='参数键名不能为空')
@Size(field_name='config_name', min_length=0, max_length=100, message='参数键名长度不能超过100个字符')
def get_config_name(self):
return self.config_name
@NotBlank(field_name='config_value', message='参数键值不能为空')
@Size(field_name='config_value', min_length=0, max_length=500, message='参数键值长度不能超过500个字符')
def get_config_value(self):
return self.config_value
def validate_fields(self):
self.get_config_key()
self.get_config_name()
self.get_config_value()
class ConfigQueryModel(ConfigModel):
"""
参数配置管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class ConfigPageQueryModel(ConfigQueryModel):
"""
参数配置管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeleteConfigModel(BaseModel):
"""
删除参数配置模型
"""
model_config = ConfigDict(alias_generator=to_camel)
config_ids: str
config_ids: str = Field(description='需要删除的参数主键')

View File

@@ -1,7 +1,8 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import Network, NotBlank, Size
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
@@ -9,22 +10,47 @@ class DeptModel(BaseModel):
"""
部门表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
dept_id: Optional[int] = None
parent_id: Optional[int] = None
ancestors: Optional[str] = None
dept_name: Optional[str] = None
order_num: Optional[int] = None
leader: Optional[str] = None
phone: Optional[str] = None
email: Optional[str] = None
status: Optional[str] = None
del_flag: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
dept_id: Optional[int] = Field(default=None, description='部门id')
parent_id: Optional[int] = Field(default=None, description='父部门id')
ancestors: Optional[str] = Field(default=None, description='祖级列表')
dept_name: Optional[str] = Field(default=None, description='部门名称')
order_num: Optional[int] = Field(default=None, description='显示顺序')
leader: Optional[str] = Field(default=None, description='负责人')
phone: Optional[str] = Field(default=None, description='联系电话')
email: Optional[str] = Field(default=None, description='邮箱')
status: Optional[Literal['0', '1']] = Field(default=None, description='部门状态0正常 1停用')
del_flag: Optional[Literal['0', '2']] = Field(default=None, description='删除标志0代表存在 2代表删除')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
@NotBlank(field_name='dept_name', message='部门名称不能为空')
@Size(field_name='dept_name', min_length=0, max_length=30, message='部门名称长度不能超过30个字符')
def get_dept_name(self):
return self.dept_name
@NotBlank(field_name='order_num', message='显示顺序不能为空')
def get_order_num(self):
return self.order_num
@Size(field_name='phone', min_length=0, max_length=11, message='联系电话长度不能超过11个字符')
def get_phone(self):
return self.phone
@Network(field_name='email', field_type='EmailStr', message='邮箱格式不正确')
@Size(field_name='email', min_length=0, max_length=50, message='邮箱长度不能超过50个字符')
def get_email(self):
return self.email
def validate_fields(self):
self.get_dept_name()
self.get_order_num()
self.get_phone()
self.get_email()
@as_query
@@ -32,16 +58,18 @@ class DeptQueryModel(DeptModel):
"""
部门管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
class DeleteDeptModel(BaseModel):
"""
删除部门模型
"""
model_config = ConfigDict(alias_generator=to_camel)
dept_ids: str
update_by: Optional[str] = None
update_time: Optional[str] = None
dept_ids: str = Field(default=None, description='需要删除的部门id')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[str] = Field(default=None, description='更新时间')

View File

@@ -1,98 +1,149 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Pattern, Size
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
class DictTypeModel(BaseModel):
"""
字典类型表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
dict_id: Optional[int] = None
dict_name: Optional[str] = None
dict_type: Optional[str] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
dict_id: Optional[int] = Field(default=None, description='字典主键')
dict_name: Optional[str] = Field(default=None, description='字典名称')
dict_type: Optional[str] = Field(default=None, description='字典类型')
status: Optional[Literal['0', '1']] = Field(default=None, description='状态0正常 1停用')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
@NotBlank(field_name='dict_name', message='字典名称不能为空')
@Size(field_name='dict_name', min_length=0, max_length=100, message='字典类型名称长度不能超过100个字符')
def get_dict_name(self):
return self.dict_name
@NotBlank(field_name='dict_type', message='字典类型不能为空')
@Size(field_name='dict_type', min_length=0, max_length=100, message='字典类型类型长度不能超过100个字符')
@Pattern(
field_name='dict_type',
regexp='^[a-z][a-z0-9_]*$',
message='字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)',
)
def get_dict_type(self):
return self.dict_type
def validate_fields(self):
self.get_dict_name()
self.get_dict_type()
class DictDataModel(BaseModel):
"""
字典数据表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
dict_code: Optional[int] = None
dict_sort: Optional[int] = None
dict_label: Optional[str] = None
dict_value: Optional[str] = None
dict_type: Optional[str] = None
css_class: Optional[str] = None
list_class: Optional[str] = None
is_default: Optional[str] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
dict_code: Optional[int] = Field(default=None, description='字典编码')
dict_sort: Optional[int] = Field(default=None, description='字典排序')
dict_label: Optional[str] = Field(default=None, description='字典标签')
dict_value: Optional[str] = Field(default=None, description='字典键值')
dict_type: Optional[str] = Field(default=None, description='字典类型')
css_class: Optional[str] = Field(default=None, description='样式属性(其他样式扩展)')
list_class: Optional[str] = Field(default=None, description='表格回显样式')
is_default: Optional[Literal['Y', 'N']] = Field(default=None, description='是否默认Y是 N否')
status: Optional[Literal['0', '1']] = Field(default=None, description='状态0正常 1停用')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
@NotBlank(field_name='dict_label', message='字典标签不能为空')
@Size(field_name='dict_label', min_length=0, max_length=100, message='字典标签长度不能超过100个字符')
def get_dict_label(self):
return self.dict_label
@NotBlank(field_name='dict_value', message='字典键值不能为空')
@Size(field_name='dict_value', min_length=0, max_length=100, message='字典键值长度不能超过100个字符')
def get_dict_value(self):
return self.dict_value
@NotBlank(field_name='dict_type', message='字典类型不能为空')
@Size(field_name='dict_type', min_length=0, max_length=100, message='字典类型长度不能超过100个字符')
def get_dict_type(self):
return self.dict_type
@Size(field_name='css_class', min_length=0, max_length=100, message='样式属性长度不能超过100个字符')
def get_css_class(self):
return self.css_class
def validate_fields(self):
self.get_dict_label()
self.get_dict_value()
self.get_dict_type()
self.get_css_class()
class DictTypeQueryModel(DictTypeModel):
"""
字典类型管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class DictTypePageQueryModel(DictTypeQueryModel):
"""
字典类型管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeleteDictTypeModel(BaseModel):
"""
删除字典类型模型
"""
model_config = ConfigDict(alias_generator=to_camel)
dict_ids: str
dict_ids: str = Field(description='需要删除的字典主键')
class DictDataQueryModel(DictDataModel):
"""
字典数据管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class DictDataPageQueryModel(DictDataQueryModel):
"""
字典数据管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeleteDictDataModel(BaseModel):
"""
删除字典数据模型
"""
model_config = ConfigDict(alias_generator=to_camel)
dict_codes: str
dict_codes: str = Field(description='需要删除的字典编码')

View File

@@ -1,110 +1,134 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Size
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
class JobModel(BaseModel):
"""
定时任务调度表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
job_id: Optional[int] = None
job_name: Optional[str] = None
job_group: Optional[str] = None
job_executor: Optional[str] = None
invoke_target: Optional[str] = None
job_args: Optional[str] = None
job_kwargs: Optional[str] = None
cron_expression: Optional[str] = None
misfire_policy: Optional[str] = None
concurrent: Optional[str] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
job_id: Optional[int] = Field(default=None, description='任务ID')
job_name: Optional[str] = Field(default=None, description='任务名称')
job_group: Optional[str] = Field(default=None, description='任务组名')
job_executor: Optional[str] = Field(default=None, description='任务执行器')
invoke_target: Optional[str] = Field(default=None, description='调用目标字符串')
job_args: Optional[str] = Field(default=None, description='位置参数')
job_kwargs: Optional[str] = Field(default=None, description='关键字参数')
cron_expression: Optional[str] = Field(default=None, description='cron执行表达式')
misfire_policy: Optional[Literal['1', '2', '3']] = Field(
default=None, description='计划执行错误策略1立即执行 2执行一次 3放弃执行'
)
concurrent: Optional[Literal['0', '1']] = Field(default=None, description='是否并发执行0允许 1禁止')
status: Optional[Literal['0', '1']] = Field(default=None, description='状态0正常 1暂停')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注信息')
@NotBlank(field_name='invoke_target', message='调用目标字符串不能为空')
@Size(field_name='invoke_target', min_length=0, max_length=500, message='调用目标字符串长度不能超过500个字符')
def get_invoke_target(self):
return self.invoke_target
@NotBlank(field_name='cron_expression', message='Cron执行表达式不能为空')
@Size(field_name='cron_expression', min_length=0, max_length=255, message='Cron执行表达式不能超过255个字符')
def get_cron_expression(self):
return self.cron_expression
def validate_fields(self):
self.get_invoke_target()
self.get_cron_expression()
class JobLogModel(BaseModel):
"""
定时任务调度日志表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
job_log_id: Optional[int] = None
job_name: Optional[str] = None
job_group: Optional[str] = None
job_executor: Optional[str] = None
invoke_target: Optional[str] = None
job_args: Optional[str] = None
job_kwargs: Optional[str] = None
job_trigger: Optional[str] = None
job_message: Optional[str] = None
status: Optional[str] = None
exception_info: Optional[str] = None
create_time: Optional[datetime] = None
job_log_id: Optional[int] = Field(default=None, description='任务日志ID')
job_name: Optional[str] = Field(default=None, description='任务名称')
job_group: Optional[str] = Field(default=None, description='任务组名')
job_executor: Optional[str] = Field(default=None, description='任务执行器')
invoke_target: Optional[str] = Field(default=None, description='调用目标字符串')
job_args: Optional[str] = Field(default=None, description='位置参数')
job_kwargs: Optional[str] = Field(default=None, description='关键字参数')
job_trigger: Optional[str] = Field(default=None, description='任务触发器')
job_message: Optional[str] = Field(default=None, description='日志信息')
status: Optional[Literal['0', '1']] = Field(default=None, description='执行状态0正常 1失败')
exception_info: Optional[str] = Field(default=None, description='异常信息')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
class JobQueryModel(JobModel):
"""
定时任务管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class JobPageQueryModel(JobQueryModel):
"""
定时任务管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class EditJobModel(JobModel):
"""
编辑定时任务模型
"""
type: Optional[str] = None
type: Optional[str] = Field(default=None, description='操作类型')
class DeleteJobModel(BaseModel):
"""
删除定时任务模型
"""
model_config = ConfigDict(alias_generator=to_camel)
job_ids: str
job_ids: str = Field(description='需要删除的定时任务ID')
class JobLogQueryModel(JobLogModel):
"""
定时任务日志不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class JobLogPageQueryModel(JobLogQueryModel):
"""
定时任务日志管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeleteJobLogModel(BaseModel):
"""
删除定时任务日志模型
"""
model_config = ConfigDict(alias_generator=to_camel)
job_log_ids: str
job_log_ids: str = Field(description='需要删除的定时任务日志ID')

View File

@@ -1,115 +1,131 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
class OperLogModel(BaseModel):
"""
操作日志表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
oper_id: Optional[int] = None
title: Optional[str] = None
business_type: Optional[int] = None
method: Optional[str] = None
request_method: Optional[str] = None
operator_type: Optional[int] = None
oper_name: Optional[str] = None
dept_name: Optional[str] = None
oper_url: Optional[str] = None
oper_ip: Optional[str] = None
oper_location: Optional[str] = None
oper_param: Optional[str] = None
json_result: Optional[str] = None
status: Optional[int] = None
error_msg: Optional[str] = None
oper_time: Optional[datetime] = None
cost_time: Optional[int] = None
oper_id: Optional[int] = Field(default=None, description='日志主键')
title: Optional[str] = Field(default=None, description='模块标题')
business_type: Optional[Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']] = (
Field(
default=None, description='业务类型0其它 1新增 2修改 3删除 4授权 5导出 6导入 7强退 8生成代码 9清空数据'
)
)
method: Optional[str] = Field(default=None, description='方法名称')
request_method: Optional[str] = Field(default=None, description='请求方式')
operator_type: Optional[Literal[0, 1, 2]] = Field(
default=None, description='操作类别0其它 1后台用户 2手机端用户'
)
oper_name: Optional[str] = Field(default=None, description='操作人员')
dept_name: Optional[str] = Field(default=None, description='部门名称')
oper_url: Optional[str] = Field(default=None, description='请求URL')
oper_ip: Optional[str] = Field(default=None, description='主机地址')
oper_location: Optional[str] = Field(default=None, description='操作地点')
oper_param: Optional[str] = Field(default=None, description='请求参数')
json_result: Optional[str] = Field(default=None, description='返回参数')
status: Optional[Literal[0, 1, '0', '1']] = Field(default=None, description='操作状态0正常 1异常')
error_msg: Optional[str] = Field(default=None, description='错误消息')
oper_time: Optional[datetime] = Field(default=None, description='操作时间')
cost_time: Optional[int] = Field(default=None, description='消耗时间')
class LogininforModel(BaseModel):
"""
登录日志表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
info_id: Optional[int] = None
user_name: Optional[str] = None
ipaddr: Optional[str] = None
login_location: Optional[str] = None
browser: Optional[str] = None
os: Optional[str] = None
status: Optional[str] = None
msg: Optional[str] = None
login_time: Optional[datetime] = None
info_id: Optional[int] = Field(default=None, description='访问ID')
user_name: Optional[str] = Field(default=None, description='用户账号')
ipaddr: Optional[str] = Field(default=None, description='登录IP地址')
login_location: Optional[str] = Field(default=None, description='登录地点')
browser: Optional[str] = Field(default=None, description='浏览器类型')
os: Optional[str] = Field(default=None, description='操作系统')
status: Optional[Literal['0', '1']] = Field(default=None, description='登录状态0成功 1失败')
msg: Optional[str] = Field(default=None, description='提示消息')
login_time: Optional[datetime] = Field(default=None, description='访问时间')
class OperLogQueryModel(OperLogModel):
"""
操作日志管理不分页查询模型
"""
order_by_column: Optional[str] = None
is_asc: Optional[str] = None
begin_time: Optional[str] = None
end_time: Optional[str] = None
order_by_column: Optional[str] = Field(default=None, description='排序的字段名称')
is_asc: Optional[Literal['ascending', 'descending']] = Field(
default=None, description='排序方式ascending升序 descending降序'
)
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class OperLogPageQueryModel(OperLogQueryModel):
"""
操作日志管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeleteOperLogModel(BaseModel):
"""
删除操作日志模型
"""
model_config = ConfigDict(alias_generator=to_camel)
oper_ids: str
oper_ids: str = Field(description='需要删除的日志主键')
class LoginLogQueryModel(LogininforModel):
"""
登录日志管理不分页查询模型
"""
order_by_column: Optional[str] = None
is_asc: Optional[str] = None
begin_time: Optional[str] = None
end_time: Optional[str] = None
order_by_column: Optional[str] = Field(default=None, description='排序的字段名称')
is_asc: Optional[Literal['ascending', 'descending']] = Field(
default=None, description='排序方式ascending升序 descending降序'
)
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class LoginLogPageQueryModel(LoginLogQueryModel):
"""
登录日志管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeleteLoginLogModel(BaseModel):
"""
删除登录日志模型
"""
model_config = ConfigDict(alias_generator=to_camel)
info_ids: str
info_ids: str = Field(description='需要删除的访问ID')
class UnlockUser(BaseModel):
"""
解锁用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
user_name: str
user_name: str = Field(description='用户名称')

View File

@@ -1,45 +1,87 @@
from pydantic import BaseModel, ConfigDict
import re
from pydantic import BaseModel, ConfigDict, Field, model_validator
from pydantic.alias_generators import to_camel
from typing import Optional
from typing import List, Optional, Union
from exceptions.exception import ModelValidatorException
from module_admin.entity.vo.menu_vo import MenuModel
class UserLogin(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
user_name: str
password: str
code: Optional[str] = None
uuid: Optional[str] = None
login_info: Optional[dict] = None
captcha_enabled: Optional[bool] = None
user_name: str = Field(description='用户名称')
password: str = Field(description='用户密码')
code: Optional[str] = Field(default=None, description='验证码')
uuid: Optional[str] = Field(default=None, description='会话编号')
login_info: Optional[dict] = Field(default=None, description='登录信息,前端无需传递')
captcha_enabled: Optional[bool] = Field(default=None, description='是否启用验证码,前端无需传递')
class UserRegister(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
username: str
password: str
confirm_password: str
code: Optional[str] = None
uuid: Optional[str] = None
username: str = Field(description='用户名称')
password: str = Field(description='用户密码')
confirm_password: str = Field(description='用户二次确认密码')
code: Optional[str] = Field(default=None, description='验证码')
uuid: Optional[str] = Field(default=None, description='会话编号')
@model_validator(mode='after')
def check_password(self) -> 'UserRegister':
pattern = r"""^[^<>"'|\\]+$"""
if self.password is None or re.match(pattern, self.password):
return self
else:
raise ModelValidatorException(message='密码不能包含非法字符:< > " \' \\ |')
class Token(BaseModel):
access_token: str
token_type: str
access_token: str = Field(description='token信息')
token_type: str = Field(description='token类型')
class CaptchaCode(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
captcha_enabled: bool
register_enabled: bool
img: str
uuid: str
captcha_enabled: bool = Field(description='是否启用验证码')
register_enabled: bool = Field(description='是否启用注册')
img: str = Field(description='验证码图片')
uuid: str = Field(description='会话编号')
class SmsCode(BaseModel):
is_success: Optional[bool] = None
sms_code: str
session_id: str
message: Optional[str] = None
is_success: Optional[bool] = Field(default=None, description='操作是否成功')
sms_code: str = Field(description='短信验证码')
session_id: str = Field(description='会话编号')
message: Optional[str] = Field(default=None, description='响应信息')
class MenuTreeModel(MenuModel):
children: Optional[Union[List['MenuTreeModel'], None]] = Field(default=None, description='子菜单')
class MetaModel(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
title: Optional[str] = Field(default=None, description='设置路由在侧边栏和面包屑中展示的名字')
icon: Optional[str] = Field(default=None, description='设置路由的图标')
no_cache: Optional[bool] = Field(default=None, description='设置为true则不会被 <keep-alive>缓存')
link: Optional[str] = Field(default=None, description='内链地址http(s)://开头)')
class RouterModel(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
name: Optional[str] = Field(default=None, description='路由名称')
path: Optional[str] = Field(default=None, description='路由地址')
hidden: Optional[bool] = Field(default=None, description='是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现')
redirect: Optional[str] = Field(
default=None, description='重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击'
)
component: Optional[str] = Field(default=None, description='组件地址')
query: Optional[str] = Field(default=None, description='路由参数:如 {"id": 1, "name": "ry"}')
always_show: Optional[bool] = Field(
default=None, description='当你一个路由下面的children声明的路由大于1个时自动会变成嵌套的模式--如组件页面'
)
meta: Optional[MetaModel] = Field(default=None, description='其他元素')
children: Optional[Union[List['RouterModel'], None]] = Field(default=None, description='子路由')

View File

@@ -1,7 +1,8 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from datetime import datetime
from typing import Union, Optional, List
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Size
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
@@ -9,27 +10,62 @@ class MenuModel(BaseModel):
"""
菜单表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
menu_id: Optional[int] = None
menu_name: Optional[str] = None
parent_id: Optional[int] = None
order_num: Optional[int] = None
path: Optional[str] = None
component: Optional[str] = None
query: Optional[str] = None
is_frame: Optional[int] = None
is_cache: Optional[int] = None
menu_type: Optional[str] = None
visible: Optional[str] = None
status: Optional[str] = None
perms: Optional[str] = None
icon: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
menu_id: Optional[int] = Field(default=None, description='菜单ID')
menu_name: Optional[str] = Field(default=None, description='菜单名称')
parent_id: Optional[int] = Field(default=None, description='父菜单ID')
order_num: Optional[int] = Field(default=None, description='显示顺序')
path: Optional[str] = Field(default=None, description='路由地址')
component: Optional[str] = Field(default=None, description='组件路径')
query: Optional[str] = Field(default=None, description='路由参数')
route_name: Optional[str] = Field(default=None, description='路由名称')
is_frame: Optional[Literal[0, 1]] = Field(default=None, description='是否为外链0是 1否')
is_cache: Optional[Literal[0, 1]] = Field(default=None, description='是否缓存0缓存 1不缓存')
menu_type: Optional[Literal['M', 'C', 'F']] = Field(default=None, description='菜单类型M目录 C菜单 F按钮')
visible: Optional[Literal['0', '1']] = Field(default=None, description='菜单状态0显示 1隐藏')
status: Optional[Literal['0', '1']] = Field(default=None, description='菜单状态0正常 1停用')
perms: Optional[str] = Field(default=None, description='权限标识')
icon: Optional[str] = Field(default=None, description='菜单图标')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
@NotBlank(field_name='menu_name', message='菜单名称不能为空')
@Size(field_name='menu_name', min_length=0, max_length=50, message='菜单名称长度不能超过50个字符')
def get_menu_name(self):
return self.menu_name
@NotBlank(field_name='order_num', message='显示顺序不能为空')
def get_order_num(self):
return self.order_num
@Size(field_name='path', min_length=0, max_length=200, message='路由地址长度不能超过200个字符')
def get_path(self):
return self.path
@Size(field_name='component', min_length=0, max_length=255, message='组件路径长度不能超过255个字符')
def get_component(self):
return self.component
@NotBlank(field_name='menu_type', message='菜单类型不能为空')
def get_menu_type(self):
return self.menu_type
@Size(field_name='perms', min_length=0, max_length=100, message='权限标识长度不能超过100个字符')
def get_perms(self):
return self.perms
def validate_fields(self):
self.get_menu_name()
self.get_order_num()
self.get_path()
self.get_component()
self.get_menu_type()
self.get_perms()
@as_query
@@ -37,14 +73,16 @@ class MenuQueryModel(MenuModel):
"""
菜单管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
class DeleteMenuModel(BaseModel):
"""
删除菜单模型
"""
model_config = ConfigDict(alias_generator=to_camel)
menu_ids: str
menu_ids: str = Field(description='需要删除的菜单ID')

View File

@@ -1,50 +1,63 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Size, Xss
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
class NoticeModel(BaseModel):
"""
通知公告表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
notice_id: Optional[int] = None
notice_title: Optional[str] = None
notice_type: Optional[str] = None
notice_content: Optional[bytes] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
notice_id: Optional[int] = Field(default=None, description='公告ID')
notice_title: Optional[str] = Field(default=None, description='公告标题')
notice_type: Optional[Literal['1', '2']] = Field(default=None, description='公告类型1通知 2公告')
notice_content: Optional[bytes] = Field(default=None, description='公告内容')
status: Optional[Literal['0', '1']] = Field(default=None, description='公告状态0正常 1关闭')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
@Xss(field_name='notice_title', message='公告标题不能包含脚本字符')
@NotBlank(field_name='notice_title', message='公告标题不能为空')
@Size(field_name='notice_title', min_length=0, max_length=50, message='公告标题不能超过50个字符')
def get_notice_title(self):
return self.notice_title
def validate_fields(self):
self.get_notice_title()
class NoticeQueryModel(NoticeModel):
"""
通知公告管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class NoticePageQueryModel(NoticeQueryModel):
"""
通知公告管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeleteNoticeModel(BaseModel):
"""
删除通知公告模型
"""
model_config = ConfigDict(alias_generator=to_camel)
notice_ids: str
notice_ids: str = Field(description='需要删除的公告ID')

View File

@@ -1,7 +1,7 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import Optional
from module_admin.annotation.pydantic_annotation import as_query
@@ -9,16 +9,17 @@ class OnlineModel(BaseModel):
"""
在线用户对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
token_id: Optional[str] = None
user_name: Optional[str] = None
dept_name: Optional[str] = None
ipaddr: Optional[str] = None
login_location: Optional[str] = None
browser: Optional[str] = None
os: Optional[str] = None
login_time: Optional[datetime] = None
token_id: Optional[str] = Field(default=None, description='会话编号')
user_name: Optional[str] = Field(default=None, description='登录名称')
dept_name: Optional[str] = Field(default=None, description='所属部门')
ipaddr: Optional[str] = Field(default=None, description='主机')
login_location: Optional[str] = Field(default=None, description='登录地点')
browser: Optional[str] = Field(default=None, description='浏览器类型')
os: Optional[str] = Field(default=None, description='操作系统')
login_time: Optional[datetime] = Field(default=None, description='登录时间')
@as_query
@@ -26,14 +27,16 @@ class OnlineQueryModel(OnlineModel):
"""
岗位管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
class DeleteOnlineModel(BaseModel):
"""
强退在线用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
token_ids: str
token_ids: str = Field(description='需要强退的会话编号')

View File

@@ -1,50 +1,73 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Size
from typing import Literal, Optional
from module_admin.annotation.pydantic_annotation import as_query
class PostModel(BaseModel):
"""
岗位信息表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
post_id: Optional[int] = None
post_code: Optional[str] = None
post_name: Optional[str] = None
post_sort: Optional[int] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
post_id: Optional[int] = Field(default=None, description='岗位ID')
post_code: Optional[str] = Field(default=None, description='岗位编码')
post_name: Optional[str] = Field(default=None, description='岗位名称')
post_sort: Optional[int] = Field(default=None, description='显示顺序')
status: Optional[Literal['0', '1']] = Field(default=None, description='状态0正常 1停用')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
@NotBlank(field_name='post_code', message='岗位编码不能为空')
@Size(field_name='post_code', min_length=0, max_length=64, message='岗位编码长度不能超过64个字符')
def get_post_code(self):
return self.post_code
@NotBlank(field_name='post_name', message='岗位名称不能为空')
@Size(field_name='post_name', min_length=0, max_length=50, message='岗位名称长度不能超过50个字符')
def get_post_name(self):
return self.post_name
@NotBlank(field_name='post_sort', message='显示顺序不能为空')
def get_post_sort(self):
return self.post_sort
def validate_fields(self):
self.get_post_code()
self.get_post_name()
self.get_post_sort()
class PostQueryModel(PostModel):
"""
岗位管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class PostPageQueryModel(PostQueryModel):
"""
岗位管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class DeletePostModel(BaseModel):
"""
删除岗位模型
"""
model_config = ConfigDict(alias_generator=to_camel)
post_ids: str
post_ids: str = Field(description='需要删除的岗位ID')

View File

@@ -1,31 +1,36 @@
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Size
from typing import List, Literal, Optional, Union
from module_admin.annotation.pydantic_annotation import as_query
class RoleModel(BaseModel):
"""
角色表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
role_id: Optional[int] = None
role_name: Optional[str] = None
role_key: Optional[str] = None
role_sort: Optional[int] = None
data_scope: Optional[str] = None
menu_check_strictly: Optional[Union[int, bool]] = None
dept_check_strictly: Optional[Union[int, bool]] = None
status: Optional[str] = None
del_flag: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
admin: Optional[bool] = False
role_id: Optional[int] = Field(default=None, description='角色ID')
role_name: Optional[str] = Field(default=None, description='角色名称')
role_key: Optional[str] = Field(default=None, description='角色权限字符串')
role_sort: Optional[int] = Field(default=None, description='显示顺序')
data_scope: Optional[Literal['1', '2', '3', '4', '5']] = Field(
default=None,
description='数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限 5仅本人数据权限',
)
menu_check_strictly: Optional[Union[int, bool]] = Field(default=None, description='菜单树选择项是否关联显示')
dept_check_strictly: Optional[Union[int, bool]] = Field(default=None, description='部门树选择项是否关联显示')
status: Optional[Literal['0', '1']] = Field(default=None, description='角色状态0正常 1停用')
del_flag: Optional[Literal['0', '2']] = Field(default=None, description='删除标志0代表存在 2代表删除')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
admin: Optional[bool] = Field(default=False, description='是否为admin')
@field_validator('menu_check_strictly', 'dept_check_strictly')
@classmethod
@@ -48,80 +53,106 @@ class RoleModel(BaseModel):
self.admin = False
return self
@NotBlank(field_name='role_name', message='角色名称不能为空')
@Size(field_name='role_name', min_length=0, max_length=30, message='角色名称长度不能超过30个字符')
def get_role_name(self):
return self.role_name
@NotBlank(field_name='role_key', message='权限字符不能为空')
@Size(field_name='role_key', min_length=0, max_length=100, message='权限字符长度不能超过100个字符')
def get_role_key(self):
return self.role_key
@NotBlank(field_name='role_sort', message='显示顺序不能为空')
def get_role_sort(self):
return self.role_sort
def validate_fields(self):
self.get_role_name()
self.get_role_key()
self.get_role_sort()
class RoleMenuModel(BaseModel):
"""
角色和菜单关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
role_id: Optional[int] = None
menu_id: Optional[int] = None
role_id: Optional[int] = Field(default=None, description='角色ID')
menu_id: Optional[int] = Field(default=None, description='菜单ID')
class RoleDeptModel(BaseModel):
"""
角色和部门关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
role_id: Optional[int] = None
dept_id: Optional[int] = None
role_id: Optional[int] = Field(default=None, description='角色ID')
dept_id: Optional[int] = Field(default=None, description='部门ID')
class RoleQueryModel(RoleModel):
"""
角色管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class RolePageQueryModel(RoleQueryModel):
"""
角色管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class RoleMenuQueryModel(BaseModel):
"""
角色菜单查询模型
"""
model_config = ConfigDict(alias_generator=to_camel)
menus: List = []
checked_keys: List[int] = []
menus: List = Field(default=[], description='菜单信息')
checked_keys: List[int] = Field(default=[], description='已选择的菜单ID信息')
class RoleDeptQueryModel(BaseModel):
"""
角色部门查询模型
"""
model_config = ConfigDict(alias_generator=to_camel)
depts: List = []
checked_keys: List[int] = []
depts: List = Field(default=[], description='部门信息')
checked_keys: List[int] = Field(default=[], description='已选择的部门ID信息')
class AddRoleModel(RoleModel):
"""
新增角色模型
"""
dept_ids: List = []
menu_ids: List = []
type: Optional[str] = None
dept_ids: List = Field(default=[], description='部门ID信息')
menu_ids: List = Field(default=[], description='菜单ID信息')
type: Optional[str] = Field(default=None, description='操作类型')
class DeleteRoleModel(BaseModel):
"""
删除角色模型
"""
model_config = ConfigDict(alias_generator=to_camel)
role_ids: str
update_by: Optional[str] = None
update_time: Optional[datetime] = None
role_ids: str = Field(description='需要删除的菜单ID')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')

View File

@@ -1,66 +1,67 @@
from pydantic import BaseModel, ConfigDict
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import Optional, List
from typing import List, Optional
class CpuInfo(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
cpu_num: Optional[int] = None
used: Optional[float] = None
sys: Optional[float] = None
free: Optional[float] = None
cpu_num: Optional[int] = Field(default=None, description='核心数')
used: Optional[float] = Field(default=None, description='CPU用户使用率')
sys: Optional[float] = Field(default=None, description='CPU系统使用率')
free: Optional[float] = Field(default=None, description='CPU当前空闲率')
class MemoryInfo(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
total: Optional[str] = None
used: Optional[str] = None
free: Optional[str] = None
usage: Optional[float] = None
total: Optional[str] = Field(default=None, description='内存总量')
used: Optional[str] = Field(default=None, description='已用内存')
free: Optional[str] = Field(default=None, description='剩余内存')
usage: Optional[float] = Field(default=None, description='使用率')
class SysInfo(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
computer_ip: Optional[str] = None
computer_name: Optional[str] = None
os_arch: Optional[str] = None
os_name: Optional[str] = None
user_dir: Optional[str] = None
computer_ip: Optional[str] = Field(default=None, description='服务器IP')
computer_name: Optional[str] = Field(default=None, description='服务器名称')
os_arch: Optional[str] = Field(default=None, description='系统架构')
os_name: Optional[str] = Field(default=None, description='操作系统')
user_dir: Optional[str] = Field(default=None, description='项目路径')
class PyInfo(MemoryInfo):
model_config = ConfigDict(alias_generator=to_camel)
name: Optional[str] = None
version: Optional[str] = None
start_time: Optional[str] = None
run_time: Optional[str] = None
home: Optional[str] = None
name: Optional[str] = Field(default=None, description='Python名称')
version: Optional[str] = Field(default=None, description='Python版本')
start_time: Optional[str] = Field(default=None, description='启动时间')
run_time: Optional[str] = Field(default=None, description='运行时长')
home: Optional[str] = Field(default=None, description='安装路径')
class SysFiles(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
dir_name: Optional[str] = None
sys_type_name: Optional[str] = None
type_name: Optional[str] = None
total: Optional[str] = None
used: Optional[str] = None
free: Optional[str] = None
usage: Optional[str] = None
dir_name: Optional[str] = Field(default=None, description='盘符路径')
sys_type_name: Optional[str] = Field(default=None, description='盘符类型')
type_name: Optional[str] = Field(default=None, description='文件类型')
total: Optional[str] = Field(default=None, description='总大小')
used: Optional[str] = Field(default=None, description='已经使用量')
free: Optional[str] = Field(default=None, description='剩余大小')
usage: Optional[str] = Field(default=None, description='资源的使用率')
class ServerMonitorModel(BaseModel):
"""
服务监控对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
cpu: Optional[CpuInfo]
py: Optional[PyInfo]
mem: Optional[MemoryInfo]
sys: Optional[SysInfo]
sys_files: Optional[List[SysFiles]]
cpu: Optional[CpuInfo] = Field(description='CPU相关信息')
py: Optional[PyInfo] = Field(description='Python相关信息')
mem: Optional[MemoryInfo] = Field(description='內存相关信息')
sys: Optional[SysInfo] = Field(description='服务器相关信息')
sys_files: Optional[List[SysFiles]] = Field(description='磁盘相关信息')

View File

@@ -1,46 +1,59 @@
from pydantic import BaseModel, ConfigDict, model_validator
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
import re
from datetime import datetime
from module_admin.entity.vo.role_vo import RoleModel
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 List, Literal, Optional, Union
from exceptions.exception import ModelValidatorException
from module_admin.annotation.pydantic_annotation import 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 module_admin.entity.vo.role_vo import RoleModel
class TokenData(BaseModel):
"""
token解析结果
"""
user_id: Union[int, None] = None
user_id: Union[int, None] = Field(default=None, description='用户ID')
class UserModel(BaseModel):
"""
用户表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
user_id: Optional[int] = None
dept_id: Optional[int] = None
user_name: Optional[str] = None
nick_name: Optional[str] = None
user_type: Optional[str] = None
email: Optional[str] = None
phonenumber: Optional[str] = None
sex: Optional[str] = None
avatar: Optional[str] = None
password: Optional[str] = None
status: Optional[str] = None
del_flag: Optional[str] = None
login_ip: Optional[str] = None
login_date: Optional[datetime] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
admin: Optional[bool] = False
user_id: Optional[int] = Field(default=None, description='用户ID')
dept_id: Optional[int] = Field(default=None, description='部门ID')
user_name: Optional[str] = Field(default=None, description='用户账号')
nick_name: Optional[str] = Field(default=None, description='用户昵称')
user_type: Optional[str] = Field(default=None, description='用户类型00系统用户')
email: Optional[str] = Field(default=None, description='用户邮箱')
phonenumber: Optional[str] = Field(default=None, description='手机号码')
sex: Optional[Literal['0', '1', '2']] = Field(default=None, description='用户性别0男 1女 2未知')
avatar: Optional[str] = Field(default=None, description='头像地址')
password: Optional[str] = Field(default=None, description='密码')
status: Optional[Literal['0', '1']] = Field(default=None, description='帐号状态0正常 1停用')
del_flag: Optional[Literal['0', '2']] = Field(default=None, description='删除标志0代表存在 2代表删除')
login_ip: Optional[str] = Field(default=None, description='最后登录IP')
login_date: Optional[datetime] = Field(default=None, description='最后登录时间')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
admin: Optional[bool] = Field(default=False, description='是否为admin')
@model_validator(mode='after')
def check_password(self) -> 'UserModel':
pattern = r"""^[^<>"'|\\]+$"""
if self.password is None or re.match(pattern, self.password):
return self
else:
raise ModelValidatorException(message='密码不能包含非法字符:< > " \' \\ |')
@model_validator(mode='after')
def check_admin(self) -> 'UserModel':
@@ -50,125 +63,181 @@ class UserModel(BaseModel):
self.admin = False
return self
@Xss(field_name='user_name', message='用户账号不能包含脚本字符')
@NotBlank(field_name='user_name', message='用户账号不能为空')
@Size(field_name='user_name', min_length=0, max_length=30, message='用户账号长度不能超过30个字符')
def get_user_name(self):
return self.user_name
@Xss(field_name='nick_name', message='用户昵称不能包含脚本字符')
@Size(field_name='nick_name', min_length=0, max_length=30, message='用户昵称长度不能超过30个字符')
def get_nick_name(self):
return self.nick_name
@Network(field_name='email', field_type='EmailStr', message='邮箱格式不正确')
@Size(field_name='email', min_length=0, max_length=50, message='邮箱长度不能超过50个字符')
def get_email(self):
return self.email
@Size(field_name='phonenumber', min_length=0, max_length=11, message='手机号码长度不能超过11个字符')
def get_phonenumber(self):
return self.phonenumber
def validate_fields(self):
self.get_user_name()
self.get_nick_name()
self.get_email()
self.get_phonenumber()
class UserRoleModel(BaseModel):
"""
用户和角色关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
user_id: Optional[int] = None
role_id: Optional[int] = None
user_id: Optional[int] = Field(default=None, description='用户ID')
role_id: Optional[int] = Field(default=None, description='角色ID')
class UserPostModel(BaseModel):
"""
用户与岗位关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
user_id: Optional[int] = None
post_id: Optional[int] = None
user_id: Optional[int] = Field(default=None, description='用户ID')
post_id: Optional[int] = Field(default=None, description='岗位ID')
class UserInfoModel(UserModel):
post_ids: Optional[Union[str, None]] = None
role_ids: Optional[Union[str, None]] = None
dept: Optional[Union[DeptModel, None]] = None
role: Optional[List[Union[RoleModel, None]]] = []
post_ids: Optional[Union[str, None]] = Field(default=None, description='岗位ID信息')
role_ids: Optional[Union[str, None]] = Field(default=None, description='角色ID信息')
dept: Optional[Union[DeptModel, None]] = Field(default=None, description='部门信息')
role: Optional[List[Union[RoleModel, None]]] = Field(default=[], description='角色信息')
class CurrentUserModel(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
permissions: List
roles: List
user: Union[UserInfoModel, None]
permissions: List = Field(description='权限信息')
roles: List = Field(description='角色信息')
user: Union[UserInfoModel, None] = Field(description='用户信息')
class UserDetailModel(BaseModel):
"""
获取用户详情信息响应模型
"""
model_config = ConfigDict(alias_generator=to_camel)
data: Optional[Union[UserInfoModel, None]] = None
post_ids: Optional[List] = None
posts: List[Union[PostModel, None]]
role_ids: Optional[List] = None
roles: List[Union[RoleModel, None]]
data: Optional[Union[UserInfoModel, None]] = Field(default=None, description='用户信息')
post_ids: Optional[List] = Field(default=None, description='岗位ID信息')
posts: List[Union[PostModel, None]] = Field(description='岗位信息')
role_ids: Optional[List] = Field(default=None, description='角色ID信息')
roles: List[Union[RoleModel, None]] = Field(description='角色信息')
class UserProfileModel(BaseModel):
"""
获取个人信息响应模型
"""
model_config = ConfigDict(alias_generator=to_camel)
data: Union[UserInfoModel, None]
post_group: Union[str, None]
role_group: Union[str, None]
data: Union[UserInfoModel, None] = Field(description='用户信息')
post_group: Union[str, None] = Field(description='岗位信息')
role_group: Union[str, None] = Field(description='角色信息')
class UserQueryModel(UserModel):
"""
用户管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间')
@as_query
@as_form
class UserPageQueryModel(UserQueryModel):
"""
用户管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class AddUserModel(UserModel):
"""
新增用户模型
"""
role_ids: Optional[List] = []
post_ids: Optional[List] = []
type: Optional[str] = None
role_ids: Optional[List] = Field(default=[], description='角色ID信息')
post_ids: Optional[List] = Field(default=[], description='岗位ID信息')
type: Optional[str] = Field(default=None, description='操作类型')
class EditUserModel(AddUserModel):
"""
编辑用户模型
"""
role: Optional[List] = []
role: Optional[List] = Field(default=[], description='角色信息')
@as_query
class ResetPasswordModel(BaseModel):
"""
重置密码模型
"""
model_config = ConfigDict(alias_generator=to_camel)
old_password: Optional[str] = Field(default=None, description='旧密码')
new_password: Optional[str] = Field(default=None, description='新密码')
@model_validator(mode='after')
def check_new_password(self) -> 'ResetPasswordModel':
pattern = r"""^[^<>"'|\\]+$"""
if self.new_password is None or re.match(pattern, self.new_password):
return self
else:
raise ModelValidatorException(message='密码不能包含非法字符:< > " \' \\ |')
class ResetUserModel(UserModel):
"""
重置用户密码模型
"""
old_password: Optional[str] = None
sms_code: Optional[str] = None
session_id: Optional[str] = None
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')
class DeleteUserModel(BaseModel):
"""
删除用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
user_ids: str
update_by: Optional[str] = None
update_time: Optional[datetime] = None
user_ids: str = Field(description='需要删除的用户ID')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
class UserRoleQueryModel(UserModel):
"""
用户角色关联管理不分页查询模型
"""
role_id: Optional[int] = None
role_id: Optional[int] = Field(default=None, description='角色ID')
@as_query
@@ -176,25 +245,28 @@ class UserRolePageQueryModel(UserRoleQueryModel):
"""
用户角色关联管理分页查询模型
"""
page_num: int = 1
page_size: int = 10
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
class SelectedRoleModel(RoleModel):
"""
是否选择角色模型
"""
flag: Optional[bool] = False
flag: Optional[bool] = Field(default=False, description='选择标识')
class UserRoleResponseModel(BaseModel):
"""
用户角色关联管理列表返回模型
"""
model_config = ConfigDict(alias_generator=to_camel)
roles: List[Union[SelectedRoleModel, None]] = []
user: UserInfoModel
roles: List[Union[SelectedRoleModel, None]] = Field(default=[], description='角色信息')
user: UserInfoModel = Field(description='用户信息')
@as_query
@@ -202,9 +274,10 @@ class CrudUserRoleModel(BaseModel):
"""
新增、删除用户关联角色及角色关联用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
user_id: Optional[int] = None
user_ids: Optional[str] = None
role_id: Optional[int] = None
role_ids: Optional[str] = None
user_id: Optional[int] = Field(default=None, description='用户ID')
user_ids: Optional[str] = Field(default=None, description='用户ID信息')
role_id: Optional[int] = Field(default=None, description='角色ID')
role_ids: Optional[str] = Field(default=None, description='角色ID信息')

View File

@@ -1,9 +1,10 @@
from fastapi import Request
from module_admin.entity.vo.cache_vo import *
from config.env import RedisInitKeyConfig
from config.enums import RedisInitKeyConfig
from config.get_redis import RedisUtil
from module_admin.entity.vo.cache_vo import CacheInfoModel, CacheMonitorModel
from module_admin.entity.vo.common_vo import CrudResponseModel
class CacheService:
"""
缓存监控模块服务层
@@ -13,39 +14,37 @@ class CacheService:
async def get_cache_monitor_statistical_info_services(cls, request: Request):
"""
获取缓存监控信息service
:param request: Request对象
:return: 缓存监控信息
"""
info = await request.app.state.redis.info()
db_size = await request.app.state.redis.dbsize()
command_stats_dict = await request.app.state.redis.info('commandstats')
command_stats = [dict(name=key.split('_')[1], value=str(value.get('calls'))) for key, value in
command_stats_dict.items()]
result = CacheMonitorModel(
commandStats=command_stats,
dbSize=db_size,
info=info
)
command_stats = [
dict(name=key.split('_')[1], value=str(value.get('calls'))) for key, value in command_stats_dict.items()
]
result = CacheMonitorModel(commandStats=command_stats, dbSize=db_size, info=info)
return result
@classmethod
def get_cache_monitor_cache_name_services(cls):
async def get_cache_monitor_cache_name_services(cls):
"""
获取缓存名称列表信息service
:return: 缓存名称列表信息
"""
name_list = []
for attr_name in dir(RedisInitKeyConfig):
if not attr_name.startswith('__') and isinstance(getattr(RedisInitKeyConfig, attr_name), dict):
name_list.append(
CacheInfoModel(
cacheKey="",
cacheName=getattr(RedisInitKeyConfig, attr_name).get('key'),
cacheValue="",
remark=getattr(RedisInitKeyConfig, attr_name).get('remark')
)
for key_config in RedisInitKeyConfig:
name_list.append(
CacheInfoModel(
cacheKey='',
cacheName=key_config.key,
cacheValue='',
remark=key_config.remark,
)
)
return name_list
@@ -53,12 +52,13 @@ class CacheService:
async def get_cache_monitor_cache_key_services(cls, request: Request, cache_name: str):
"""
获取缓存键名列表信息service
:param request: Request对象
:param cache_name: 缓存名称
:return: 缓存键名列表信息
"""
cache_keys = await request.app.state.redis.keys(f"{cache_name}*")
cache_key_list = [key.split(':', 1)[1] for key in cache_keys if key.startswith(f"{cache_name}:")]
cache_keys = await request.app.state.redis.keys(f'{cache_name}*')
cache_key_list = [key.split(':', 1)[1] for key in cache_keys if key.startswith(f'{cache_name}:')]
return cache_key_list
@@ -66,49 +66,51 @@ class CacheService:
async def get_cache_monitor_cache_value_services(cls, request: Request, cache_name: str, cache_key: str):
"""
获取缓存内容信息service
:param request: Request对象
:param cache_name: 缓存名称
:param cache_key: 缓存键名
:return: 缓存内容信息
"""
cache_value = await request.app.state.redis.get(f"{cache_name}:{cache_key}")
cache_value = await request.app.state.redis.get(f'{cache_name}:{cache_key}')
return CacheInfoModel(cacheKey=cache_key, cacheName=cache_name, cacheValue=cache_value, remark="")
return CacheInfoModel(cacheKey=cache_key, cacheName=cache_name, cacheValue=cache_value, remark='')
@classmethod
async def clear_cache_monitor_cache_name_services(cls, request: Request, cache_name: str):
"""
清除缓存名称对应所有键值service
:param request: Request对象
:param cache_name: 缓存名称
:return: 操作缓存响应信息
"""
cache_keys = await request.app.state.redis.keys(f"{cache_name}*")
cache_keys = await request.app.state.redis.keys(f'{cache_name}*')
if cache_keys:
await request.app.state.redis.delete(*cache_keys)
result = dict(is_success=True, message=f"{cache_name}对应键值清除成功")
return CrudResponseModel(**result)
return CrudResponseModel(is_success=True, message=f'{cache_name}对应键值清除成功')
@classmethod
async def clear_cache_monitor_cache_key_services(cls, request: Request, cache_key: str):
"""
清除缓存名称对应所有键值service
:param request: Request对象
:param cache_key: 缓存键名
:return: 操作缓存响应信息
"""
cache_keys = await request.app.state.redis.keys(f"*{cache_key}")
cache_keys = await request.app.state.redis.keys(f'*{cache_key}')
if cache_keys:
await request.app.state.redis.delete(*cache_keys)
result = dict(is_success=True, message=f"{cache_key}清除成功")
return CrudResponseModel(**result)
return CrudResponseModel(is_success=True, message=f'{cache_key}清除成功')
@classmethod
async def clear_cache_monitor_all_services(cls, request: Request):
"""
清除所有缓存service
:param request: Request对象
:return: 操作缓存响应信息
"""
@@ -116,8 +118,7 @@ class CacheService:
if cache_keys:
await request.app.state.redis.delete(*cache_keys)
result = dict(is_success=True, message="所有缓存清除成功")
await RedisUtil.init_sys_dict(request.app.state.redis)
await RedisUtil.init_sys_config(request.app.state.redis)
return CrudResponseModel(**result)
return CrudResponseModel(is_success=True, message='所有缓存清除成功')

View File

@@ -1,8 +1,8 @@
from PIL import Image, ImageDraw, ImageFont
import base64
import io
import os
import random
import base64
from PIL import Image, ImageDraw, ImageFont
class CaptchaService:
@@ -11,7 +11,7 @@ class CaptchaService:
"""
@classmethod
def create_captcha_image_service(cls):
async def create_captcha_image_service(cls):
# 创建空白图像
image = Image.new('RGB', (160, 60), color='#EAEAEA')
@@ -35,7 +35,7 @@ class CaptchaService:
else:
result = num1 * num2
# 绘制文本
text = f"{num1} {operational_character} {num2} = ?"
text = f'{num1} {operational_character} {num2} = ?'
draw.text((25, 15), text, fill='blue', font=font)
# 将图像数据保存到内存中

View File

@@ -1,9 +1,9 @@
from fastapi import Request, BackgroundTasks
import os
from fastapi import UploadFile
from datetime import datetime
from fastapi import BackgroundTasks, Request, UploadFile
from config.env import UploadConfig
from module_admin.entity.vo.common_vo import *
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel, UploadResponseModel
from utils.upload_util import UploadUtil
@@ -13,15 +13,16 @@ class CommonService:
"""
@classmethod
def upload_service(cls, request: Request, file: UploadFile):
async def upload_service(cls, request: Request, file: UploadFile):
"""
通用上传service
:param request: Request对象
:param file: 上传文件对象
:return: 上传结果
"""
if not UploadUtil.check_file_extension(file):
result = dict(is_success=False, message='文件类型不合法')
raise ServiceException(message='文件类型不合法')
else:
relative_path = f'upload/{datetime.now().strftime("%Y")}/{datetime.now().strftime("%m")}/{datetime.now().strftime("%d")}'
dir_path = os.path.join(UploadConfig.UPLOAD_PATH, relative_path)
@@ -36,23 +37,22 @@ class CommonService:
for chunk in iter(lambda: file.file.read(1024 * 1024 * 10), b''):
f.write(chunk)
result = dict(
return CrudResponseModel(
is_success=True,
result=UploadResponseModel(
fileName=f'{UploadConfig.UPLOAD_PREFIX}/{relative_path}/{filename}',
newFileName=filename,
originalFilename=file.filename,
url=f'{request.base_url}{UploadConfig.UPLOAD_PREFIX[1:]}/{relative_path}/{filename}'
url=f'{request.base_url}{UploadConfig.UPLOAD_PREFIX[1:]}/{relative_path}/{filename}',
),
message='上传成功'
message='上传成功',
)
return CrudResponseModel(**result)
@classmethod
def download_services(cls, background_tasks: BackgroundTasks, file_name, delete: bool):
async def download_services(cls, background_tasks: BackgroundTasks, file_name, delete: bool):
"""
下载下载目录文件service
:param background_tasks: 后台任务对象
:param file_name: 下载的文件名称
:param delete: 是否在下载完成后删除文件
@@ -60,28 +60,32 @@ class CommonService:
"""
filepath = os.path.join(UploadConfig.DOWNLOAD_PATH, file_name)
if '..' in file_name:
result = dict(is_success=False, message='文件名称不合法')
raise ServiceException(message='文件名称不合法')
elif not UploadUtil.check_file_exists(filepath):
result = dict(is_success=False, message='文件不存在')
raise ServiceException(message='文件不存在')
else:
result = dict(is_success=True, result=UploadUtil.generate_file(filepath), message='下载成功')
if delete:
background_tasks.add_task(UploadUtil.delete_file, filepath)
return CrudResponseModel(**result)
return CrudResponseModel(is_success=True, result=UploadUtil.generate_file(filepath), message='下载成功')
@classmethod
def download_resource_services(cls, resource: str):
async def download_resource_services(cls, resource: str):
"""
下载上传目录文件service
:param resource: 下载的文件名称
:return: 上传结果
"""
filepath = os.path.join(resource.replace(UploadConfig.UPLOAD_PREFIX, UploadConfig.UPLOAD_PATH))
filename = resource.rsplit("/", 1)[-1]
if '..' in filename or not UploadUtil.check_file_timestamp(filename) or not UploadUtil.check_file_machine(filename) or not UploadUtil.check_file_random_code(filename):
result = dict(is_success=False, message='文件名称不合法')
filename = resource.rsplit('/', 1)[-1]
if (
'..' in filename
or not UploadUtil.check_file_timestamp(filename)
or not UploadUtil.check_file_machine(filename)
or not UploadUtil.check_file_random_code(filename)
):
raise ServiceException(message='文件名称不合法')
elif not UploadUtil.check_file_exists(filepath):
result = dict(is_success=False, message='文件不存在')
raise ServiceException(message='文件不存在')
else:
result = dict(is_success=True, result=UploadUtil.generate_file(filepath), message='下载成功')
return CrudResponseModel(**result)
return CrudResponseModel(is_success=True, result=UploadUtil.generate_file(filepath), message='下载成功')

View File

@@ -1,8 +1,13 @@
from fastapi import Request
from config.env import RedisInitKeyConfig
from module_admin.dao.config_dao import *
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from config.enums import RedisInitKeyConfig
from exceptions.exception import ServiceException
from module_admin.dao.config_dao import ConfigDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
from module_admin.entity.vo.config_vo import ConfigModel, ConfigPageQueryModel, DeleteConfigModel
from utils.common_util import CamelCaseUtil, export_list2excel
class ConfigService:
@@ -11,158 +16,195 @@ class ConfigService:
"""
@classmethod
def get_config_list_services(cls, query_db: Session, query_object: ConfigPageQueryModel, is_page: bool = False):
async def get_config_list_services(
cls, query_db: AsyncSession, query_object: ConfigPageQueryModel, is_page: bool = False
):
"""
获取参数配置列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 参数配置列表信息对象
"""
config_list_result = ConfigDao.get_config_list(query_db, query_object, is_page)
config_list_result = await ConfigDao.get_config_list(query_db, query_object, is_page)
return config_list_result
@classmethod
async def init_cache_sys_config_services(cls, query_db: Session, redis):
async def init_cache_sys_config_services(cls, query_db: AsyncSession, redis):
"""
应用初始化获取所有参数配置对应的键值对信息并缓存service
:param query_db: orm对象
:param redis: redis对象
:return:
"""
# 获取以sys_config:开头的键列表
keys = await redis.keys(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:*")
keys = await redis.keys(f'{RedisInitKeyConfig.SYS_CONFIG.key}:*')
# 删除匹配的键
if keys:
await redis.delete(*keys)
config_all = ConfigDao.get_config_list(query_db, ConfigPageQueryModel(**dict()), is_page=False)
config_all = await ConfigDao.get_config_list(query_db, ConfigPageQueryModel(**dict()), is_page=False)
for config_obj in config_all:
if config_obj.get('configType') == 'Y':
await redis.set(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_obj.get('configKey')}", config_obj.get('configValue'))
await redis.set(
f"{RedisInitKeyConfig.SYS_CONFIG.key}:{config_obj.get('configKey')}",
config_obj.get('configValue'),
)
@classmethod
async def query_config_list_from_cache_services(cls, redis, config_key: str):
"""
从缓存获取参数键名对应值service
:param redis: redis对象
:param config_key: 参数键名
:return: 参数键名对应值
"""
result = await redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_key}")
result = await redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:{config_key}')
return result
@classmethod
async def add_config_services(cls, request: Request, query_db: Session, page_object: ConfigModel):
async def check_config_key_unique_services(cls, query_db: AsyncSession, page_object: ConfigModel):
"""
校验参数键名是否唯一service
:param query_db: orm对象
:param page_object: 参数配置对象
:return: 校验结果
"""
config_id = -1 if page_object.config_id is None else page_object.config_id
config = await ConfigDao.get_config_detail_by_info(query_db, ConfigModel(configKey=page_object.config_key))
if config and config.config_id != config_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_config_services(cls, request: Request, query_db: AsyncSession, page_object: ConfigModel):
"""
新增参数配置信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 新增参数配置对象
:return: 新增参数配置校验结果
"""
config = ConfigDao.get_config_detail_by_info(query_db, ConfigModel(configKey=page_object.config_key))
if config:
result = dict(is_success=False, message='参数键名已存在')
if not await cls.check_config_key_unique_services(query_db, page_object):
raise ServiceException(message=f'新增参数{page_object.config_name}失败,参数键名已存在')
else:
try:
ConfigDao.add_config_dao(query_db, page_object)
query_db.commit()
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='新增成功')
await ConfigDao.add_config_dao(query_db, page_object)
await query_db.commit()
await request.app.state.redis.set(
f'{RedisInitKeyConfig.SYS_CONFIG.key}:{page_object.config_key}', page_object.config_value
)
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def edit_config_services(cls, request: Request, query_db: Session, page_object: ConfigModel):
async def edit_config_services(cls, request: Request, query_db: AsyncSession, page_object: ConfigModel):
"""
编辑参数配置信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 编辑参数配置对象
:return: 编辑参数配置校验结果
"""
edit_config = page_object.model_dump(exclude_unset=True)
config_info = cls.config_detail_services(query_db, edit_config.get('config_id'))
if config_info:
if config_info.config_key != page_object.config_key or config_info.config_value != page_object.config_value:
config = ConfigDao.get_config_detail_by_info(query_db, page_object)
if config:
result = dict(is_success=False, message='参数配置已存在')
return CrudResponseModel(**result)
try:
ConfigDao.edit_config_dao(query_db, edit_config)
query_db.commit()
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
config_info = await cls.config_detail_services(query_db, page_object.config_id)
if config_info.config_id:
if not await cls.check_config_key_unique_services(query_db, page_object):
raise ServiceException(message=f'修改参数{page_object.config_name}失败,参数键名已存在')
else:
try:
await ConfigDao.edit_config_dao(query_db, edit_config)
await query_db.commit()
if config_info.config_key != page_object.config_key:
await request.app.state.redis.delete(
f'{RedisInitKeyConfig.SYS_CONFIG.key}:{config_info.config_key}'
)
await request.app.state.redis.set(
f'{RedisInitKeyConfig.SYS_CONFIG.key}:{page_object.config_key}', page_object.config_value
)
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='参数配置不存在')
return CrudResponseModel(**result)
raise ServiceException(message='参数配置不存在')
@classmethod
async def delete_config_services(cls, request: Request, query_db: Session, page_object: DeleteConfigModel):
async def delete_config_services(cls, request: Request, query_db: AsyncSession, page_object: DeleteConfigModel):
"""
删除参数配置信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 删除参数配置对象
:return: 删除参数配置校验结果
"""
if page_object.config_ids.split(','):
if page_object.config_ids:
config_id_list = page_object.config_ids.split(',')
try:
delete_config_key_list = []
for config_id in config_id_list:
ConfigDao.delete_config_dao(query_db, ConfigModel(configId=config_id))
query_db.commit()
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='删除成功')
config_info = await cls.config_detail_services(query_db, int(config_id))
if config_info.config_type == CommonConstant.YES:
raise ServiceException(message=f'内置参数{config_info.config_key}不能删除')
else:
await ConfigDao.delete_config_dao(query_db, ConfigModel(configId=int(config_id)))
delete_config_key_list.append(f'{RedisInitKeyConfig.SYS_CONFIG.key}:{config_info.config_key}')
await query_db.commit()
if delete_config_key_list:
await request.app.state.redis.delete(*delete_config_key_list)
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入字典数据id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入参数配置id为空')
@classmethod
def config_detail_services(cls, query_db: Session, config_id: int):
async def config_detail_services(cls, query_db: AsyncSession, config_id: int):
"""
获取参数配置详细信息service
:param query_db: orm对象
:param config_id: 参数配置id
:return: 参数配置id对应的信息
"""
config = ConfigDao.get_config_detail_by_id(query_db, config_id=config_id)
result = ConfigModel(**CamelCaseUtil.transform_result(config))
config = await ConfigDao.get_config_detail_by_id(query_db, config_id=config_id)
if config:
result = ConfigModel(**CamelCaseUtil.transform_result(config))
else:
result = ConfigModel(**dict())
return result
@staticmethod
def export_config_list_services(config_list: List):
async def export_config_list_services(config_list: List):
"""
导出参数配置信息service
:param config_list: 参数配置信息列表
:return: 参数配置信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"configId": "参数主键",
"configName": "参数名称",
"configKey": "参数键名",
"configValue": "参数键值",
"configType": "系统内置",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
'configId': '参数主键',
'configName': '参数名称',
'configKey': '参数键名',
'configValue': '参数键值',
'configType': '系统内置',
'createBy': '创建者',
'createTime': '创建时间',
'updateBy': '更新者',
'updateTime': '更新时间',
'remark': '备注',
}
data = config_list
@@ -172,20 +214,22 @@ class ConfigService:
item['configType'] = ''
else:
item['configType'] = ''
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
@classmethod
async def refresh_sys_config_services(cls, request: Request, query_db: Session):
async def refresh_sys_config_services(cls, request: Request, query_db: AsyncSession):
"""
刷新字典缓存信息service
:param request: Request对象
:param query_db: orm对象
:return: 刷新字典缓存校验结果
"""
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='刷新成功')
return CrudResponseModel(**result)
return CrudResponseModel(is_success=True, message='刷新成功')

View File

@@ -1,5 +1,9 @@
from module_admin.dao.dept_dao import *
from sqlalchemy.ext.asyncio import AsyncSession
from config.constant import CommonConstant
from exceptions.exception import ServiceException, ServiceWarning
from module_admin.dao.dept_dao import DeptDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.dept_vo import DeleteDeptModel, DeptModel
from utils.common_util import CamelCaseUtil
@@ -9,152 +13,187 @@ class DeptService:
"""
@classmethod
def get_dept_tree_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str):
async def get_dept_tree_services(cls, query_db: AsyncSession, page_object: DeptModel, data_scope_sql: str):
"""
获取部门树信息service
:param query_db: orm对象
:param page_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门树信息对象
"""
dept_list_result = DeptDao.get_dept_list_for_tree(query_db, page_object, data_scope_sql)
dept_list_result = await DeptDao.get_dept_list_for_tree(query_db, page_object, data_scope_sql)
dept_tree_result = cls.list_to_tree(dept_list_result)
return dept_tree_result
@classmethod
def get_dept_for_edit_option_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str):
async def get_dept_for_edit_option_services(
cls, query_db: AsyncSession, page_object: DeptModel, data_scope_sql: str
):
"""
获取部门编辑部门树信息service
:param query_db: orm对象
:param page_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门树信息对象
"""
dept_list_result = DeptDao.get_dept_info_for_edit_option(query_db, page_object, data_scope_sql)
dept_list_result = await DeptDao.get_dept_info_for_edit_option(query_db, page_object, data_scope_sql)
return CamelCaseUtil.transform_result(dept_list_result)
@classmethod
def get_dept_list_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str):
async def get_dept_list_services(cls, query_db: AsyncSession, page_object: DeptModel, data_scope_sql: str):
"""
获取部门列表信息service
:param query_db: orm对象
:param page_object: 分页查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门列表信息对象
"""
dept_list_result = DeptDao.get_dept_list(query_db, page_object, data_scope_sql)
dept_list_result = await DeptDao.get_dept_list(query_db, page_object, data_scope_sql)
return CamelCaseUtil.transform_result(dept_list_result)
@classmethod
def add_dept_services(cls, query_db: Session, page_object: DeptModel):
async def check_dept_data_scope_services(cls, query_db: AsyncSession, dept_id: int, data_scope_sql: str):
"""
校验部门是否有数据权限service
:param query_db: orm对象
:param dept_id: 部门id
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 校验结果
"""
depts = await DeptDao.get_dept_list(query_db, DeptModel(deptId=dept_id), data_scope_sql)
if depts:
return CrudResponseModel(is_success=True, message='校验通过')
else:
raise ServiceException(message='没有权限访问部门数据')
@classmethod
async def check_dept_name_unique_services(cls, query_db: AsyncSession, page_object: DeptModel):
"""
校验部门名称是否唯一service
:param query_db: orm对象
:param page_object: 部门对象
:return: 校验结果
"""
dept_id = -1 if page_object.dept_id is None else page_object.dept_id
dept = await DeptDao.get_dept_detail_by_info(
query_db, DeptModel(deptName=page_object.dept_name, parentId=page_object.parent_id)
)
if dept and dept.dept_id != dept_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_dept_services(cls, query_db: AsyncSession, page_object: DeptModel):
"""
新增部门信息service
:param query_db: orm对象
:param page_object: 新增部门对象
:return: 新增部门校验结果
"""
parent_info = DeptDao.get_dept_by_id(query_db, page_object.parent_id)
if parent_info:
page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}'
else:
page_object.ancestors = '0'
dept = DeptDao.get_dept_detail_by_info(query_db, DeptModel(parentId=page_object.parent_id,
deptName=page_object.dept_name))
if dept:
result = dict(is_success=False, message='同一部门下不允许存在同名的部门')
else:
try:
DeptDao.add_dept_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
if not await cls.check_dept_name_unique_services(query_db, page_object):
raise ServiceException(message=f'新增部门{page_object.dept_name}失败,部门名称已存在')
parent_info = await DeptDao.get_dept_by_id(query_db, page_object.parent_id)
if parent_info.status != CommonConstant.DEPT_NORMAL:
raise ServiceException(message=f'部门{parent_info.dept_name}停用,不允许新增')
page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}'
try:
await DeptDao.add_dept_dao(query_db, page_object)
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
await query_db.rollback()
raise e
@classmethod
def edit_dept_services(cls, query_db: Session, page_object: DeptModel):
async def edit_dept_services(cls, query_db: AsyncSession, page_object: DeptModel):
"""
编辑部门信息service
:param query_db: orm对象
:param page_object: 编辑部门对象
:return: 编辑部门校验结果
"""
parent_info = DeptDao.get_dept_by_id(query_db, page_object.parent_id)
if parent_info:
page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}'
else:
page_object.ancestors = '0'
edit_dept = page_object.model_dump(exclude_unset=True)
dept_info = cls.dept_detail_services(query_db, edit_dept.get('dept_id'))
if dept_info:
if dept_info.parent_id != page_object.parent_id or dept_info.dept_name != page_object.dept_name:
dept = DeptDao.get_dept_detail_by_info(query_db, DeptModel(parentId=page_object.parent_id,
deptName=page_object.dept_name))
if dept:
result = dict(is_success=False, message='同一部门下不允许存在同名的部门')
return CrudResponseModel(**result)
try:
DeptDao.edit_dept_dao(query_db, edit_dept)
cls.update_children_info(query_db, DeptModel(deptId=page_object.dept_id,
ancestors=page_object.ancestors,
updateBy=page_object.update_by,
updateTime=page_object.update_time
)
)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='部门不存在')
return CrudResponseModel(**result)
if not await cls.check_dept_name_unique_services(query_db, page_object):
raise ServiceException(message=f'修改部门{page_object.dept_name}失败,部门名称已存在')
elif page_object.dept_id == page_object.parent_id:
raise ServiceException(message=f'修改部门{page_object.dept_name}失败,上级部门不能是自己')
elif (
page_object.status == CommonConstant.DEPT_DISABLE
and (await DeptDao.count_normal_children_dept_dao(query_db, page_object.dept_id)) > 0
):
raise ServiceException(message=f'修改部门{page_object.dept_name}失败,该部门包含未停用的子部门')
new_parent_dept = await DeptDao.get_dept_by_id(query_db, page_object.parent_id)
old_dept = await DeptDao.get_dept_by_id(query_db, page_object.dept_id)
try:
if new_parent_dept and old_dept:
new_ancestors = f'{new_parent_dept.ancestors},{new_parent_dept.dept_id}'
old_ancestors = old_dept.ancestors
page_object.ancestors = new_ancestors
await cls.update_dept_children(query_db, page_object.dept_id, new_ancestors, old_ancestors)
edit_dept = page_object.model_dump(exclude_unset=True)
await DeptDao.edit_dept_dao(query_db, edit_dept)
if (
page_object.status == CommonConstant.DEPT_NORMAL
and page_object.ancestors
and page_object.ancestors != 0
):
await cls.update_parent_dept_status_normal(query_db, page_object)
await query_db.commit()
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
await query_db.rollback()
raise e
@classmethod
def delete_dept_services(cls, query_db: Session, page_object: DeleteDeptModel):
async def delete_dept_services(cls, query_db: AsyncSession, page_object: DeleteDeptModel):
"""
删除部门信息service
:param query_db: orm对象
:param page_object: 删除部门对象
:return: 删除部门校验结果
"""
if page_object.dept_ids.split(','):
if page_object.dept_ids:
dept_id_list = page_object.dept_ids.split(',')
ancestors = DeptDao.get_dept_all_ancestors(query_db)
try:
for dept_id in dept_id_list:
for ancestor in ancestors:
if dept_id in ancestor[0]:
result = dict(is_success=False, message='该部门下有子部门,不允许删除')
if (await DeptDao.count_children_dept_dao(query_db, int(dept_id))) > 0:
raise ServiceWarning(message='存在下级部门,不允许删除')
elif (await DeptDao.count_dept_user_dao(query_db, int(dept_id))) > 0:
raise ServiceWarning(message='部门存在用户,不允许删除')
return CrudResponseModel(**result)
DeptDao.delete_dept_dao(query_db, DeptModel(deptId=dept_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
await DeptDao.delete_dept_dao(query_db, DeptModel(deptId=dept_id))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入部门id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入部门id为空')
@classmethod
def dept_detail_services(cls, query_db: Session, dept_id: int):
async def dept_detail_services(cls, query_db: AsyncSession, dept_id: int):
"""
获取部门详细信息service
:param query_db: orm对象
:param dept_id: 部门id
:return: 部门id对应的信息
"""
dept = DeptDao.get_dept_detail_by_id(query_db, dept_id=dept_id)
result = DeptModel(**CamelCaseUtil.transform_result(dept))
dept = await DeptDao.get_dept_detail_by_id(query_db, dept_id=dept_id)
if dept:
result = DeptModel(**CamelCaseUtil.transform_result(dept))
else:
result = DeptModel(**dict())
return result
@@ -162,11 +201,13 @@ class DeptService:
def list_to_tree(cls, permission_list: list) -> list:
"""
工具方法:根据部门列表信息生成树形嵌套数据
:param permission_list: 部门列表信息
:return: 部门树形嵌套数据
"""
permission_list = [dict(id=item.dept_id, label=item.dept_name, parentId=item.parent_id) for item in
permission_list]
permission_list = [
dict(id=item.dept_id, label=item.dept_name, parentId=item.parent_id) for item in permission_list
]
# 转成id为key的字典
mapping: dict = dict(zip([i['id'] for i in permission_list], permission_list))
@@ -188,26 +229,47 @@ class DeptService:
return container
@classmethod
def update_children_info(cls, query_db, page_object):
async def replace_first(cls, original_str: str, old_str: str, new_str: str):
"""
工具方法:递归更新子部门信息
工具方法:替换字符串
:param original_str: 需要替换的原始字符串
:param old_str: 用于匹配的字符串
:param new_str: 替换的字符串
:return: 替换后的字符串
"""
if original_str.startswith(old_str):
return original_str.replace(old_str, new_str, 1)
else:
return original_str
@classmethod
async def update_parent_dept_status_normal(cls, query_db: AsyncSession, dept: DeptModel):
"""
更新父部门状态为正常
:param query_db: orm对象
:param page_object: 编辑部门对象
:param dept: 部门对象
:return:
"""
children_info = DeptDao.get_children_dept(query_db, page_object.dept_id)
if children_info:
for child in children_info:
child.ancestors = f'{page_object.ancestors},{page_object.dept_id}'
DeptDao.edit_dept_dao(query_db,
dict(dept_id=child.dept_id,
ancestors=child.ancestors,
update_by=page_object.update_by,
update_time=page_object.update_time
)
)
cls.update_children_info(query_db, DeptModel(dept_id=child.dept_id,
ancestors=child.ancestors,
update_by=page_object.update_by,
update_time=page_object.update_time
))
dept_id_list = dept.ancestors.split(',')
await DeptDao.update_dept_status_normal_dao(query_db, list(map(int, dept_id_list)))
@classmethod
async def update_dept_children(cls, query_db: AsyncSession, dept_id: int, new_ancestors: str, old_ancestors: str):
"""
更新子部门信息
:param query_db: orm对象
:param dept_id: 部门id
:param new_ancestors: 新的祖先
:param old_ancestors: 旧的祖先
:return:
"""
children = await DeptDao.get_children_dept_dao(query_db, dept_id)
update_children = []
for child in children:
child_ancestors = await cls.replace_first(child.ancestors, old_ancestors, new_ancestors)
update_children.append({'dept_id': child.dept_id, 'ancestors': child_ancestors})
if children:
await DeptDao.update_dept_children_dao(query_db, update_children)

View File

@@ -1,9 +1,21 @@
from fastapi import Request
import json
from config.env import RedisInitKeyConfig
from module_admin.dao.dict_dao import *
from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from config.enums import RedisInitKeyConfig
from exceptions.exception import ServiceException
from module_admin.dao.dict_dao import DictDataDao, DictTypeDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
from module_admin.entity.vo.dict_vo import (
DeleteDictDataModel,
DeleteDictTypeModel,
DictDataModel,
DictDataPageQueryModel,
DictTypeModel,
DictTypePageQueryModel,
)
from utils.common_util import CamelCaseUtil, export_list2excel
class DictTypeService:
@@ -12,133 +24,172 @@ class DictTypeService:
"""
@classmethod
def get_dict_type_list_services(cls, query_db: Session, query_object: DictTypePageQueryModel, is_page: bool = False):
async def get_dict_type_list_services(
cls, query_db: AsyncSession, query_object: DictTypePageQueryModel, is_page: bool = False
):
"""
获取字典类型列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 字典类型列表信息对象
"""
dict_type_list_result = DictTypeDao.get_dict_type_list(query_db, query_object, is_page)
dict_type_list_result = await DictTypeDao.get_dict_type_list(query_db, query_object, is_page)
return dict_type_list_result
@classmethod
async def add_dict_type_services(cls, request: Request, query_db: Session, page_object: DictTypeModel):
async def check_dict_type_unique_services(cls, query_db: AsyncSession, page_object: DictTypeModel):
"""
校验字典类型称是否唯一service
:param query_db: orm对象
:param page_object: 字典类型对象
:return: 校验结果
"""
dict_id = -1 if page_object.dict_id is None else page_object.dict_id
dict_type = await DictTypeDao.get_dict_type_detail_by_info(
query_db, DictTypeModel(dictType=page_object.dict_type)
)
if dict_type and dict_type.dict_id != dict_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_dict_type_services(cls, request: Request, query_db: AsyncSession, page_object: DictTypeModel):
"""
新增字典类型信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 新增岗位对象
:return: 新增字典类型校验结果
"""
dict_type = DictTypeDao.get_dict_type_detail_by_info(query_db, DictTypeModel(dictType=page_object.dict_type))
if dict_type:
result = dict(is_success=False, message='字典类型已存在')
if not await cls.check_dict_type_unique_services(query_db, page_object):
raise ServiceException(message=f'新增字典{page_object.dict_name}失败,字典类型已存在')
else:
try:
DictTypeDao.add_dict_type_dao(query_db, page_object)
query_db.commit()
await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis)
await DictTypeDao.add_dict_type_dao(query_db, page_object)
await query_db.commit()
await request.app.state.redis.set(f'{RedisInitKeyConfig.SYS_DICT.key}:{page_object.dict_type}', '')
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def edit_dict_type_services(cls, request: Request, query_db: Session, page_object: DictTypeModel):
async def edit_dict_type_services(cls, request: Request, query_db: AsyncSession, page_object: DictTypeModel):
"""
编辑字典类型信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 编辑字典类型对象
:return: 编辑字典类型校验结果
"""
edit_dict_type = page_object.model_dump(exclude_unset=True)
dict_type_info = cls.dict_type_detail_services(query_db, edit_dict_type.get('dict_id'))
if dict_type_info:
if dict_type_info.dict_type != page_object.dict_type or dict_type_info.dict_name != page_object.dict_name:
dict_type = DictTypeDao.get_dict_type_detail_by_info(query_db, DictTypeModel(dictType=page_object.dict_type))
if dict_type:
result = dict(is_success=False, message='字典类型已存在')
return CrudResponseModel(**result)
try:
if dict_type_info.dict_type != page_object.dict_type:
query_dict_data = DictDataModel(dictType=dict_type_info.dict_type)
dict_data_list = DictDataDao.get_dict_data_list(query_db, query_dict_data)
for dict_data in dict_data_list:
edit_dict_data = DictDataModel(dictCode=dict_data.dict_code, dictType=page_object.dict_type, updateBy=page_object.update_by).model_dump(exclude_unset=True)
DictDataDao.edit_dict_data_dao(query_db, edit_dict_data)
DictTypeDao.edit_dict_type_dao(query_db, edit_dict_type)
query_db.commit()
await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
dict_type_info = await cls.dict_type_detail_services(query_db, page_object.dict_id)
if dict_type_info.dict_id:
if not await cls.check_dict_type_unique_services(query_db, page_object):
raise ServiceException(message=f'修改字典{page_object.dict_name}失败,字典类型已存在')
else:
try:
query_dict_data = DictDataPageQueryModel(dictType=dict_type_info.dict_type)
dict_data_list = await DictDataDao.get_dict_data_list(query_db, query_dict_data, is_page=False)
if dict_type_info.dict_type != page_object.dict_type:
for dict_data in dict_data_list:
edit_dict_data = DictDataModel(
dictCode=dict_data.dict_code,
dictType=page_object.dict_type,
updateBy=page_object.update_by,
).model_dump(exclude_unset=True)
await DictDataDao.edit_dict_data_dao(query_db, edit_dict_data)
await DictTypeDao.edit_dict_type_dao(query_db, edit_dict_type)
await query_db.commit()
if dict_type_info.dict_type != page_object.dict_type:
dict_data = [CamelCaseUtil.transform_result(row) for row in dict_data_list if row]
await request.app.state.redis.set(
f'{RedisInitKeyConfig.SYS_DICT.key}:{page_object.dict_type}',
json.dumps(dict_data, ensure_ascii=False, default=str),
)
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='字典类型不存在')
return CrudResponseModel(**result)
raise ServiceException(message='字典类型不存在')
@classmethod
async def delete_dict_type_services(cls, request: Request, query_db: Session, page_object: DeleteDictTypeModel):
async def delete_dict_type_services(
cls, request: Request, query_db: AsyncSession, page_object: DeleteDictTypeModel
):
"""
删除字典类型信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 删除字典类型对象
:return: 删除字典类型校验结果
"""
if page_object.dict_ids.split(','):
if page_object.dict_ids:
dict_id_list = page_object.dict_ids.split(',')
try:
delete_dict_type_list = []
for dict_id in dict_id_list:
DictTypeDao.delete_dict_type_dao(query_db, DictTypeModel(dictId=dict_id))
query_db.commit()
await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='删除成功')
dict_type_into = await cls.dict_type_detail_services(query_db, int(dict_id))
if (await DictDataDao.count_dict_data_dao(query_db, dict_type_into.dict_type)) > 0:
raise ServiceException(message=f'{dict_type_into.dict_name}已分配,不能删除')
await DictTypeDao.delete_dict_type_dao(query_db, DictTypeModel(dictId=int(dict_id)))
delete_dict_type_list.append(f'{RedisInitKeyConfig.SYS_DICT.key}:{dict_type_into.dict_type}')
await query_db.commit()
if delete_dict_type_list:
await request.app.state.redis.delete(*delete_dict_type_list)
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入字典类型id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入字典类型id为空')
@classmethod
def dict_type_detail_services(cls, query_db: Session, dict_id: int):
async def dict_type_detail_services(cls, query_db: AsyncSession, dict_id: int):
"""
获取字典类型详细信息service
:param query_db: orm对象
:param dict_id: 字典类型id
:return: 字典类型id对应的信息
"""
dict_type = DictTypeDao.get_dict_type_detail_by_id(query_db, dict_id=dict_id)
result = DictTypeModel(**CamelCaseUtil.transform_result(dict_type))
dict_type = await DictTypeDao.get_dict_type_detail_by_id(query_db, dict_id=dict_id)
if dict_type:
result = DictTypeModel(**CamelCaseUtil.transform_result(dict_type))
else:
result = DictTypeModel(**dict())
return result
@staticmethod
def export_dict_type_list_services(dict_type_list: List):
async def export_dict_type_list_services(dict_type_list: List):
"""
导出字典类型信息service
:param dict_type_list: 字典信息列表
:return: 字典信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"dictId": "字典编号",
"dictName": "字典名称",
"dictType": "字典类型",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
'dictId': '字典编号',
'dictName': '字典名称',
'dictType': '字典类型',
'status': '状态',
'createBy': '创建者',
'createTime': '创建时间',
'updateBy': '更新者',
'updateTime': '更新时间',
'remark': '备注',
}
data = dict_type_list
@@ -148,15 +199,18 @@ class DictTypeService:
item['status'] = '正常'
else:
item['status'] = '停用'
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
@classmethod
async def refresh_sys_dict_services(cls, request: Request, query_db: Session):
async def refresh_sys_dict_services(cls, request: Request, query_db: AsyncSession):
"""
刷新字典缓存信息service
:param request: Request对象
:param query_db: orm对象
:return: 刷新字典缓存校验结果
@@ -173,179 +227,225 @@ class DictDataService:
"""
@classmethod
def get_dict_data_list_services(cls, query_db: Session, query_object: DictDataPageQueryModel, is_page: bool = False):
async def get_dict_data_list_services(
cls, query_db: AsyncSession, query_object: DictDataPageQueryModel, is_page: bool = False
):
"""
获取字典数据列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 字典数据列表信息对象
"""
dict_data_list_result = DictDataDao.get_dict_data_list(query_db, query_object, is_page)
dict_data_list_result = await DictDataDao.get_dict_data_list(query_db, query_object, is_page)
return dict_data_list_result
@classmethod
def query_dict_data_list_services(cls, query_db: Session, dict_type: str):
async def query_dict_data_list_services(cls, query_db: AsyncSession, dict_type: str):
"""
获取字典数据列表信息service
:param query_db: orm对象
:param dict_type: 字典类型
:return: 字典数据列表信息对象
"""
dict_data_list_result = DictDataDao.query_dict_data_list(query_db, dict_type)
dict_data_list_result = await DictDataDao.query_dict_data_list(query_db, dict_type)
return dict_data_list_result
@classmethod
async def init_cache_sys_dict_services(cls, query_db: Session, redis):
async def init_cache_sys_dict_services(cls, query_db: AsyncSession, redis):
"""
应用初始化获取所有字典类型对应的字典数据信息并缓存service
:param query_db: orm对象
:param redis: redis对象
:return:
"""
# 获取以sys_dict:开头的键列表
keys = await redis.keys(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:*")
keys = await redis.keys(f'{RedisInitKeyConfig.SYS_DICT.key}:*')
# 删除匹配的键
if keys:
await redis.delete(*keys)
dict_type_all = DictTypeDao.get_all_dict_type(query_db)
dict_type_all = await DictTypeDao.get_all_dict_type(query_db)
for dict_type_obj in [item for item in dict_type_all if item.status == '0']:
dict_type = dict_type_obj.dict_type
dict_data_list = DictDataDao.query_dict_data_list(query_db, dict_type)
dict_data_list = await DictDataDao.query_dict_data_list(query_db, dict_type)
dict_data = [CamelCaseUtil.transform_result(row) for row in dict_data_list if row]
await redis.set(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:{dict_type}", json.dumps(dict_data, ensure_ascii=False, default=str))
await redis.set(
f'{RedisInitKeyConfig.SYS_DICT.key}:{dict_type}',
json.dumps(dict_data, ensure_ascii=False, default=str),
)
@classmethod
async def query_dict_data_list_from_cache_services(cls, redis, dict_type: str):
"""
从缓存获取字典数据列表信息service
:param redis: redis对象
:param dict_type: 字典类型
:return: 字典数据列表信息对象
"""
result = []
dict_data_list_result = await redis.get(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:{dict_type}")
dict_data_list_result = await redis.get(f'{RedisInitKeyConfig.SYS_DICT.key}:{dict_type}')
if dict_data_list_result:
result = json.loads(dict_data_list_result)
return CamelCaseUtil.transform_result(result)
@classmethod
async def add_dict_data_services(cls, request: Request, query_db: Session, page_object: DictDataModel):
async def check_dict_data_unique_services(cls, query_db: AsyncSession, page_object: DictDataModel):
"""
校验字典数据是否唯一service
:param query_db: orm对象
:param page_object: 字典数据对象
:return: 校验结果
"""
dict_code = -1 if page_object.dict_code is None else page_object.dict_code
dict_data = await DictDataDao.get_dict_data_detail_by_info(query_db, page_object)
if dict_data and dict_data.dict_code != dict_code:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_dict_data_services(cls, request: Request, query_db: AsyncSession, page_object: DictDataModel):
"""
新增字典数据信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 新增岗位对象
:return: 新增字典数据校验结果
"""
dict_data = DictDataDao.get_dict_data_detail_by_info(query_db, page_object)
if dict_data:
result = dict(is_success=False, message='字典数据已存在')
if not await cls.check_dict_data_unique_services(query_db, page_object):
raise ServiceException(
message=f'新增字典数据{page_object.dict_label}失败,{page_object.dict_type}下已存在该字典数据'
)
else:
try:
DictDataDao.add_dict_data_dao(query_db, page_object)
query_db.commit()
await cls.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='新增成功')
await DictDataDao.add_dict_data_dao(query_db, page_object)
await query_db.commit()
dict_data_list = await cls.query_dict_data_list_services(query_db, page_object.dict_type)
await request.app.state.redis.set(
f'{RedisInitKeyConfig.SYS_DICT.key}:{page_object.dict_type}',
json.dumps(CamelCaseUtil.transform_result(dict_data_list), ensure_ascii=False, default=str),
)
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def edit_dict_data_services(cls, request: Request, query_db: Session, page_object: DictDataModel):
async def edit_dict_data_services(cls, request: Request, query_db: AsyncSession, page_object: DictDataModel):
"""
编辑字典数据信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 编辑字典数据对象
:return: 编辑字典数据校验结果
"""
edit_data_type = page_object.model_dump(exclude_unset=True)
dict_data_info = cls.dict_data_detail_services(query_db, edit_data_type.get('dict_code'))
if dict_data_info:
if dict_data_info.dict_type != page_object.dict_type or dict_data_info.dict_label != page_object.dict_label or dict_data_info.dict_value != page_object.dict_value:
dict_data = DictDataDao.get_dict_data_detail_by_info(query_db, page_object)
if dict_data:
result = dict(is_success=False, message='字典数据已存在')
return CrudResponseModel(**result)
try:
DictDataDao.edit_dict_data_dao(query_db, edit_data_type)
query_db.commit()
await cls.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
dict_data_info = await cls.dict_data_detail_services(query_db, page_object.dict_code)
if dict_data_info.dict_code:
if not await cls.check_dict_data_unique_services(query_db, page_object):
raise ServiceException(
message=f'新增字典数据{page_object.dict_label}失败,{page_object.dict_type}下已存在该字典数据'
)
else:
try:
await DictDataDao.edit_dict_data_dao(query_db, edit_data_type)
await query_db.commit()
dict_data_list = await cls.query_dict_data_list_services(query_db, page_object.dict_type)
await request.app.state.redis.set(
f'{RedisInitKeyConfig.SYS_DICT.key}:{page_object.dict_type}',
json.dumps(CamelCaseUtil.transform_result(dict_data_list), ensure_ascii=False, default=str),
)
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='字典数据不存在')
return CrudResponseModel(**result)
raise ServiceException(message='字典数据不存在')
@classmethod
async def delete_dict_data_services(cls, request: Request, query_db: Session, page_object: DeleteDictDataModel):
async def delete_dict_data_services(
cls, request: Request, query_db: AsyncSession, page_object: DeleteDictDataModel
):
"""
删除字典数据信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 删除字典数据对象
:return: 删除字典数据校验结果
"""
if page_object.dict_codes.split(','):
if page_object.dict_codes:
dict_code_list = page_object.dict_codes.split(',')
try:
delete_dict_type_list = []
for dict_code in dict_code_list:
DictDataDao.delete_dict_data_dao(query_db, DictDataModel(dictCode=dict_code))
query_db.commit()
await cls.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='删除成功')
dict_data = await cls.dict_data_detail_services(query_db, int(dict_code))
await DictDataDao.delete_dict_data_dao(query_db, DictDataModel(dictCode=dict_code))
delete_dict_type_list.append(dict_data.dict_type)
await query_db.commit()
for dict_type in list(set(delete_dict_type_list)):
dict_data_list = await cls.query_dict_data_list_services(query_db, dict_type)
await request.app.state.redis.set(
f'{RedisInitKeyConfig.SYS_DICT.key}:{dict_type}',
json.dumps(CamelCaseUtil.transform_result(dict_data_list), ensure_ascii=False, default=str),
)
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入字典数据id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入字典数据id为空')
@classmethod
def dict_data_detail_services(cls, query_db: Session, dict_code: int):
async def dict_data_detail_services(cls, query_db: AsyncSession, dict_code: int):
"""
获取字典数据详细信息service
:param query_db: orm对象
:param dict_code: 字典数据id
:return: 字典数据id对应的信息
"""
dict_data = DictDataDao.get_dict_data_detail_by_id(query_db, dict_code=dict_code)
result = DictDataModel(**CamelCaseUtil.transform_result(dict_data))
dict_data = await DictDataDao.get_dict_data_detail_by_id(query_db, dict_code=dict_code)
if dict_data:
result = DictDataModel(**CamelCaseUtil.transform_result(dict_data))
else:
result = DictDataModel(**dict())
return result
@staticmethod
def export_dict_data_list_services(dict_data_list: List):
async def export_dict_data_list_services(dict_data_list: List):
"""
导出字典数据信息service
:param dict_data_list: 字典数据信息列表
:return: 字典数据信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"dictCode": "字典编码",
"dictSort": "字典标签",
"dictLabel": "字典键值",
"dictValue": "字典排序",
"dictType": "字典类型",
"cssClass": "样式属性",
"listClass": "表格回显样式",
"isDefault": "是否默认",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
'dictCode': '字典编码',
'dictSort': '字典标签',
'dictLabel': '字典键值',
'dictValue': '字典排序',
'dictType': '字典类型',
'cssClass': '样式属性',
'listClass': '表格回显样式',
'isDefault': '是否默认',
'status': '状态',
'createBy': '创建者',
'createTime': '创建时间',
'updateBy': '更新者',
'updateTime': '更新时间',
'remark': '备注',
}
data = dict_data_list
@@ -359,7 +459,9 @@ class DictDataService:
item['isDefault'] = ''
else:
item['isDefault'] = ''
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

View File

@@ -1,6 +1,11 @@
from module_admin.dao.job_log_dao import *
from module_admin.service.dict_service import Request, DictDataService
from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session
from typing import List
from module_admin.dao.job_log_dao import JobLogDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.job_vo import DeleteJobLogModel, JobLogModel, JobLogPageQueryModel
from module_admin.service.dict_service import DictDataService
from utils.common_util import export_list2excel
@@ -10,15 +15,18 @@ class JobLogService:
"""
@classmethod
def get_job_log_list_services(cls, query_db: Session, query_object: JobLogPageQueryModel, is_page: bool = False):
async def get_job_log_list_services(
cls, query_db: AsyncSession, query_object: JobLogPageQueryModel, is_page: bool = False
):
"""
获取定时任务日志列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 定时任务日志列表信息对象
"""
job_log_list_result = JobLogDao.get_job_log_list(query_db, query_object, is_page)
job_log_list_result = await JobLogDao.get_job_log_list(query_db, query_object, is_page)
return job_log_list_result
@@ -26,6 +34,7 @@ class JobLogService:
def add_job_log_services(cls, query_db: Session, page_object: JobLogModel):
"""
新增定时任务日志信息service
:param query_db: orm对象
:param page_object: 新增定时任务日志对象
:return: 新增定时任务日志校验结果
@@ -41,40 +50,42 @@ class JobLogService:
return CrudResponseModel(**result)
@classmethod
def delete_job_log_services(cls, query_db: Session, page_object: DeleteJobLogModel):
async def delete_job_log_services(cls, query_db: AsyncSession, page_object: DeleteJobLogModel):
"""
删除定时任务日志信息service
:param query_db: orm对象
:param page_object: 删除定时任务日志对象
:return: 删除定时任务日志校验结果
"""
if page_object.job_log_ids.split(','):
if page_object.job_log_ids:
job_log_id_list = page_object.job_log_ids.split(',')
try:
for job_log_id in job_log_id_list:
JobLogDao.delete_job_log_dao(query_db, JobLogModel(jobLogId=job_log_id))
query_db.commit()
await JobLogDao.delete_job_log_dao(query_db, JobLogModel(jobLogId=job_log_id))
await query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入定时任务日志id为空')
return CrudResponseModel(**result)
@classmethod
def clear_job_log_services(cls, query_db: Session):
async def clear_job_log_services(cls, query_db: AsyncSession):
"""
清除定时任务日志信息service
:param query_db: orm对象
:return: 清除定时任务日志校验结果
"""
try:
JobLogDao.clear_job_log_dao(query_db)
query_db.commit()
await JobLogDao.clear_job_log_dao(query_db)
await query_db.commit()
result = dict(is_success=True, message='清除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@@ -83,32 +94,39 @@ class JobLogService:
async def export_job_log_list_services(request: Request, job_log_list: List):
"""
导出定时任务日志信息service
:param request: Request对象
:param job_log_list: 定时任务日志信息列表
:return: 定时任务日志信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"jobLogId": "任务日志编码",
"jobName": "任务名称",
"jobGroup": "任务组名",
"jobExecutor": "任务执行器",
"invokeTarget": "调用目标字符串",
"jobArgs": "位置参数",
"jobKwargs": "关键字参数",
"jobTrigger": "任务触发器",
"jobMessage": "日志信息",
"status": "执行状态",
"exceptionInfo": "异常信息",
"createTime": "创建时间",
'jobLogId': '任务日志编码',
'jobName': '任务名称',
'jobGroup': '任务组名',
'jobExecutor': '任务执行器',
'invokeTarget': '调用目标字符串',
'jobArgs': '位置参数',
'jobKwargs': '关键字参数',
'jobTrigger': '任务触发器',
'jobMessage': '日志信息',
'status': '执行状态',
'exceptionInfo': '异常信息',
'createTime': '创建时间',
}
data = job_log_list
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group')
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(
request.app.state.redis, dict_type='sys_job_group'
)
job_group_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_group_list]
job_group_option_dict = {item.get('value'): item for item in job_group_option}
job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_executor')
job_executor_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list]
job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(
request.app.state.redis, dict_type='sys_job_executor'
)
job_executor_option = [
dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list
]
job_executor_option_dict = {item.get('value'): item for item in job_executor_option}
for item in data:
@@ -120,8 +138,9 @@ class JobLogService:
item['jobGroup'] = job_group_option_dict.get(str(item.get('jobGroup'))).get('label')
if str(item.get('jobExecutor')) in job_executor_option_dict.keys():
item['jobExecutor'] = job_executor_option_dict.get(str(item.get('jobExecutor'))).get('label')
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

View File

@@ -1,8 +1,16 @@
from module_admin.dao.job_dao import *
from module_admin.service.dict_service import Request, DictDataService
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant, JobConstant
from config.get_scheduler import SchedulerUtil
from exceptions.exception import ServiceException
from module_admin.dao.job_dao import JobDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.job_vo import DeleteJobModel, EditJobModel, JobModel, JobPageQueryModel
from module_admin.service.dict_service import DictDataService
from utils.common_util import CamelCaseUtil, export_list2excel
from utils.cron_util import CronUtil
from utils.string_util import StringUtil
class JobService:
@@ -11,47 +19,82 @@ class JobService:
"""
@classmethod
def get_job_list_services(cls, query_db: Session, query_object: JobPageQueryModel, is_page: bool = False):
async def get_job_list_services(
cls, query_db: AsyncSession, query_object: JobPageQueryModel, is_page: bool = False
):
"""
获取定时任务列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 定时任务列表信息对象
"""
job_list_result = JobDao.get_job_list(query_db, query_object, is_page)
job_list_result = await JobDao.get_job_list(query_db, query_object, is_page)
return job_list_result
@classmethod
def add_job_services(cls, query_db: Session, page_object: JobModel):
async def check_job_unique_services(cls, query_db: AsyncSession, page_object: JobModel):
"""
校验定时任务是否存在service
:param query_db: orm对象
:param page_object: 定时任务对象
:return: 校验结果
"""
job_id = -1 if page_object.job_id is None else page_object.job_id
job = await JobDao.get_job_detail_by_info(query_db, page_object)
if job and job.job_id != job_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_job_services(cls, query_db: AsyncSession, page_object: JobModel):
"""
新增定时任务信息service
:param query_db: orm对象
:param page_object: 新增定时任务对象
:return: 新增定时任务校验结果
"""
job = JobDao.get_job_detail_by_info(query_db, page_object)
if job:
result = dict(is_success=False, message='定时任务已存在')
if not CronUtil.validate_cron_expression(page_object.cron_expression):
raise ServiceException(message=f'新增定时任务{page_object.job_name}失败Cron表达式不正确')
elif StringUtil.contains_ignore_case(page_object.invoke_target, CommonConstant.LOOKUP_RMI):
raise ServiceException(message=f'新增定时任务{page_object.job_name}失败目标字符串不允许rmi调用')
elif StringUtil.contains_any_ignore_case(
page_object.invoke_target, [CommonConstant.LOOKUP_LDAP, CommonConstant.LOOKUP_LDAPS]
):
raise ServiceException(message=f'新增定时任务{page_object.job_name}失败目标字符串不允许ldap(s)调用')
elif StringUtil.contains_any_ignore_case(
page_object.invoke_target, [CommonConstant.HTTP, CommonConstant.HTTPS]
):
raise ServiceException(message=f'新增定时任务{page_object.job_name}失败目标字符串不允许http(s)调用')
elif StringUtil.startswith_any_case(page_object.invoke_target, JobConstant.JOB_ERROR_LIST):
raise ServiceException(message=f'新增定时任务{page_object.job_name}失败,目标字符串存在违规')
elif not StringUtil.startswith_any_case(page_object.invoke_target, JobConstant.JOB_WHITE_LIST):
raise ServiceException(message=f'新增定时任务{page_object.job_name}失败,目标字符串不在白名单内')
elif not await cls.check_job_unique_services(query_db, page_object):
raise ServiceException(message=f'新增定时任务{page_object.job_name}失败,定时任务已存在')
else:
try:
JobDao.add_job_dao(query_db, page_object)
job_info = JobDao.get_job_detail_by_info(query_db, page_object)
add_job = await JobDao.add_job_dao(query_db, page_object)
job_info = await cls.job_detail_services(query_db, add_job.job_id)
if job_info.status == '0':
SchedulerUtil.add_scheduler_job(job_info=job_info)
query_db.commit()
await query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_job_services(cls, query_db: Session, page_object: EditJobModel):
async def edit_job_services(cls, query_db: AsyncSession, page_object: EditJobModel):
"""
编辑定时任务信息service
:param query_db: orm对象
:param page_object: 编辑定时任务对象
:return: 编辑定时任务校验结果
@@ -59,82 +102,99 @@ class JobService:
edit_job = page_object.model_dump(exclude_unset=True)
if page_object.type == 'status':
del edit_job['type']
job_info = cls.job_detail_services(query_db, edit_job.get('job_id'))
job_info = await cls.job_detail_services(query_db, page_object.job_id)
if job_info:
if page_object.type != 'status' and (job_info.job_name != page_object.job_name or job_info.job_group != page_object.job_group or job_info.invoke_target != page_object.invoke_target or job_info.cron_expression != page_object.cron_expression):
job = JobDao.get_job_detail_by_info(query_db, page_object)
if job:
result = dict(is_success=False, message='定时任务已存在')
return CrudResponseModel(**result)
if page_object.type != 'status':
if not CronUtil.validate_cron_expression(page_object.cron_expression):
raise ServiceException(message=f'修改定时任务{page_object.job_name}失败Cron表达式不正确')
elif StringUtil.contains_ignore_case(page_object.invoke_target, CommonConstant.LOOKUP_RMI):
raise ServiceException(message=f'修改定时任务{page_object.job_name}失败目标字符串不允许rmi调用')
elif StringUtil.contains_any_ignore_case(
page_object.invoke_target, [CommonConstant.LOOKUP_LDAP, CommonConstant.LOOKUP_LDAPS]
):
raise ServiceException(
message=f'修改定时任务{page_object.job_name}失败目标字符串不允许ldap(s)调用'
)
elif StringUtil.contains_any_ignore_case(
page_object.invoke_target, [CommonConstant.HTTP, CommonConstant.HTTPS]
):
raise ServiceException(
message=f'修改定时任务{page_object.job_name}失败目标字符串不允许http(s)调用'
)
elif StringUtil.startswith_any_case(page_object.invoke_target, JobConstant.JOB_ERROR_LIST):
raise ServiceException(message=f'修改定时任务{page_object.job_name}失败,目标字符串存在违规')
elif not StringUtil.startswith_any_case(page_object.invoke_target, JobConstant.JOB_WHITE_LIST):
raise ServiceException(message=f'修改定时任务{page_object.job_name}失败,目标字符串不在白名单内')
elif not await cls.check_job_unique_services(query_db, page_object):
raise ServiceException(message=f'修改定时任务{page_object.job_name}失败,定时任务已存在')
try:
JobDao.edit_job_dao(query_db, edit_job)
query_job = SchedulerUtil.get_scheduler_job(job_id=edit_job.get('job_id'))
if query_job:
SchedulerUtil.remove_scheduler_job(job_id=edit_job.get('job_id'))
await JobDao.edit_job_dao(query_db, edit_job)
SchedulerUtil.remove_scheduler_job(job_id=edit_job.get('job_id'))
if edit_job.get('status') == '0':
job_info = await cls.job_detail_services(query_db, edit_job.get('job_id'))
SchedulerUtil.add_scheduler_job(job_info=job_info)
query_db.commit()
result = dict(is_success=True, message='更新成功')
await query_db.commit()
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='定时任务不存在')
return CrudResponseModel(**result)
raise ServiceException(message='定时任务不存在')
@classmethod
def execute_job_once_services(cls, query_db: Session, page_object: JobModel):
async def execute_job_once_services(cls, query_db: AsyncSession, page_object: JobModel):
"""
执行一次定时任务service
:param query_db: orm对象
:param page_object: 定时任务对象
:return: 执行一次定时任务结果
"""
query_job = SchedulerUtil.get_scheduler_job(job_id=page_object.job_id)
if query_job:
SchedulerUtil.remove_scheduler_job(job_id=page_object.job_id)
job_info = cls.job_detail_services(query_db, page_object.job_id)
SchedulerUtil.remove_scheduler_job(job_id=page_object.job_id)
job_info = await cls.job_detail_services(query_db, page_object.job_id)
if job_info:
SchedulerUtil.execute_scheduler_job_once(job_info=job_info)
result = dict(is_success=True, message='执行成功')
return CrudResponseModel(is_success=True, message='执行成功')
else:
result = dict(is_success=False, message='定时任务不存在')
return CrudResponseModel(**result)
raise ServiceException(message='定时任务不存在')
@classmethod
def delete_job_services(cls, query_db: Session, page_object: DeleteJobModel):
async def delete_job_services(cls, query_db: AsyncSession, page_object: DeleteJobModel):
"""
删除定时任务信息service
:param query_db: orm对象
:param page_object: 删除定时任务对象
:return: 删除定时任务校验结果
"""
if page_object.job_ids.split(','):
if page_object.job_ids:
job_id_list = page_object.job_ids.split(',')
try:
for job_id in job_id_list:
JobDao.delete_job_dao(query_db, JobModel(jobId=job_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
await JobDao.delete_job_dao(query_db, JobModel(jobId=job_id))
SchedulerUtil.remove_scheduler_job(job_id=job_id)
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入定时任务id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入定时任务id为空')
@classmethod
def job_detail_services(cls, query_db: Session, job_id: int):
async def job_detail_services(cls, query_db: AsyncSession, job_id: int):
"""
获取定时任务详细信息service
:param query_db: orm对象
:param job_id: 定时任务id
:return: 定时任务id对应的信息
"""
job = JobDao.get_job_detail_by_id(query_db, job_id=job_id)
result = JobModel(**CamelCaseUtil.transform_result(job))
job = await JobDao.get_job_detail_by_id(query_db, job_id=job_id)
if job:
result = JobModel(**CamelCaseUtil.transform_result(job))
else:
result = JobModel(**dict())
return result
@@ -142,36 +202,43 @@ class JobService:
async def export_job_list_services(request: Request, job_list: List):
"""
导出定时任务信息service
:param request: Request对象
:param job_list: 定时任务信息列表
:return: 定时任务信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"jobId": "任务编码",
"jobName": "任务名称",
"jobGroup": "任务组名",
"jobExecutor": "任务执行器",
"invokeTarget": "调用目标字符串",
"jobArgs": "位置参数",
"jobKwargs": "关键字参数",
"cronExpression": "cron执行表达式",
"misfirePolicy": "计划执行错误策略",
"concurrent": "是否并发执行",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
'jobId': '任务编码',
'jobName': '任务名称',
'jobGroup': '任务组名',
'jobExecutor': '任务执行器',
'invokeTarget': '调用目标字符串',
'jobArgs': '位置参数',
'jobKwargs': '关键字参数',
'cronExpression': 'cron执行表达式',
'misfirePolicy': '计划执行错误策略',
'concurrent': '是否并发执行',
'status': '状态',
'createBy': '创建者',
'createTime': '创建时间',
'updateBy': '更新者',
'updateTime': '更新时间',
'remark': '备注',
}
data = job_list
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group')
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(
request.app.state.redis, dict_type='sys_job_group'
)
job_group_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_group_list]
job_group_option_dict = {item.get('value'): item for item in job_group_option}
job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_executor')
job_executor_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list]
job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(
request.app.state.redis, dict_type='sys_job_executor'
)
job_executor_option = [
dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list
]
job_executor_option_dict = {item.get('value'): item for item in job_executor_option}
for item in data:
@@ -193,7 +260,9 @@ class JobService:
item['concurrent'] = '允许'
else:
item['concurrent'] = '禁止'
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

View File

@@ -1,7 +1,20 @@
from module_admin.dao.log_dao import *
from module_admin.service.dict_service import Request, DictDataService
from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from exceptions.exception import ServiceException
from module_admin.dao.log_dao import LoginLogDao, OperationLogDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
from module_admin.entity.vo.log_vo import (
DeleteLoginLogModel,
DeleteOperLogModel,
LogininforModel,
LoginLogPageQueryModel,
OperLogModel,
OperLogPageQueryModel,
UnlockUser,
)
from module_admin.service.dict_service import DictDataService
from utils.common_util import export_list2excel
class OperationLogService:
@@ -10,106 +23,112 @@ class OperationLogService:
"""
@classmethod
def get_operation_log_list_services(cls, query_db: Session, query_object: OperLogPageQueryModel, is_page: bool = False):
async def get_operation_log_list_services(
cls, query_db: AsyncSession, query_object: OperLogPageQueryModel, is_page: bool = False
):
"""
获取操作日志列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 操作日志列表信息对象
"""
operation_log_list_result = OperationLogDao.get_operation_log_list(query_db, query_object, is_page)
operation_log_list_result = await OperationLogDao.get_operation_log_list(query_db, query_object, is_page)
return operation_log_list_result
@classmethod
def add_operation_log_services(cls, query_db: Session, page_object: OperLogModel):
async def add_operation_log_services(cls, query_db: AsyncSession, page_object: OperLogModel):
"""
新增操作日志service
:param query_db: orm对象
:param page_object: 新增操作日志对象
:return: 新增操作日志校验结果
"""
try:
OperationLogDao.add_operation_log_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
await OperationLogDao.add_operation_log_dao(query_db, page_object)
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
result = dict(is_success=False, message=str(e))
return CrudResponseModel(**result)
await query_db.rollback()
raise e
@classmethod
def delete_operation_log_services(cls, query_db: Session, page_object: DeleteOperLogModel):
async def delete_operation_log_services(cls, query_db: AsyncSession, page_object: DeleteOperLogModel):
"""
删除操作日志信息service
:param query_db: orm对象
:param page_object: 删除操作日志对象
:return: 删除操作日志校验结果
"""
if page_object.oper_ids.split(','):
if page_object.oper_ids:
oper_id_list = page_object.oper_ids.split(',')
try:
for oper_id in oper_id_list:
OperationLogDao.delete_operation_log_dao(query_db, OperLogModel(operId=oper_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
await OperationLogDao.delete_operation_log_dao(query_db, OperLogModel(operId=oper_id))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入操作日志id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入操作日志id为空')
@classmethod
def clear_operation_log_services(cls, query_db: Session):
async def clear_operation_log_services(cls, query_db: AsyncSession):
"""
清除操作日志信息service
:param query_db: orm对象
:return: 清除操作日志校验结果
"""
try:
OperationLogDao.clear_operation_log_dao(query_db)
query_db.commit()
result = dict(is_success=True, message='清除成功')
await OperationLogDao.clear_operation_log_dao(query_db)
await query_db.commit()
return CrudResponseModel(is_success=True, message='清除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def export_operation_log_list_services(cls, request: Request, operation_log_list: List):
"""
导出操作日志信息service
:param request: Request对象
:param operation_log_list: 操作日志信息列表
:return: 操作日志信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"operId": "日志编号",
"title": "系统模块",
"businessType": "操作类型",
"method": "方法名称",
"requestMethod": "请求方式",
"operName": "操作人员",
"deptName": "部门名称",
"operUrl": "请求URL",
"operIp": "操作地址",
"operLocation": "操作地点",
"operParam": "请求参数",
"jsonResult": "返回参数",
"status": "操作状态",
"error_msg": "错误消息",
"operTime": "操作日期",
"costTime": "消耗时间(毫秒)"
'operId': '日志编号',
'title': '系统模块',
'businessType': '操作类型',
'method': '方法名称',
'requestMethod': '请求方式',
'operName': '操作人员',
'deptName': '部门名称',
'operUrl': '请求URL',
'operIp': '操作地址',
'operLocation': '操作地点',
'operParam': '请求参数',
'jsonResult': '返回参数',
'status': '操作状态',
'error_msg': '错误消息',
'operTime': '操作日期',
'costTime': '消耗时间(毫秒)',
}
data = operation_log_list
operation_type_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_oper_type')
operation_type_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in operation_type_list]
operation_type_list = await DictDataService.query_dict_data_list_from_cache_services(
request.app.state.redis, dict_type='sys_oper_type'
)
operation_type_option = [
dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in operation_type_list
]
operation_type_option_dict = {item.get('value'): item for item in operation_type_option}
for item in data:
@@ -120,7 +139,9 @@ class OperationLogService:
if str(item.get('businessType')) in operation_type_option_dict.keys():
item['businessType'] = operation_type_option_dict.get(str(item.get('businessType'))).get('label')
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
@@ -132,103 +153,104 @@ class LoginLogService:
"""
@classmethod
def get_login_log_list_services(cls, query_db: Session, query_object: LoginLogPageQueryModel, is_page: bool = False):
async def get_login_log_list_services(
cls, query_db: AsyncSession, query_object: LoginLogPageQueryModel, is_page: bool = False
):
"""
获取登录日志列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 登录日志列表信息对象
"""
operation_log_list_result = LoginLogDao.get_login_log_list(query_db, query_object, is_page)
operation_log_list_result = await LoginLogDao.get_login_log_list(query_db, query_object, is_page)
return operation_log_list_result
@classmethod
def add_login_log_services(cls, query_db: Session, page_object: LogininforModel):
async def add_login_log_services(cls, query_db: AsyncSession, page_object: LogininforModel):
"""
新增登录日志service
:param query_db: orm对象
:param page_object: 新增登录日志对象
:return: 新增登录日志校验结果
"""
try:
LoginLogDao.add_login_log_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
await LoginLogDao.add_login_log_dao(query_db, page_object)
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
result = dict(is_success=False, message=str(e))
return CrudResponseModel(**result)
await query_db.rollback()
raise e
@classmethod
def delete_login_log_services(cls, query_db: Session, page_object: DeleteLoginLogModel):
async def delete_login_log_services(cls, query_db: AsyncSession, page_object: DeleteLoginLogModel):
"""
删除操作日志信息service
:param query_db: orm对象
:param page_object: 删除操作日志对象
:return: 删除操作日志校验结果
"""
if page_object.info_ids.split(','):
if page_object.info_ids:
info_id_list = page_object.info_ids.split(',')
try:
for info_id in info_id_list:
LoginLogDao.delete_login_log_dao(query_db, LogininforModel(infoId=info_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
await LoginLogDao.delete_login_log_dao(query_db, LogininforModel(infoId=info_id))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入登录日志id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入登录日志id为空')
@classmethod
def clear_login_log_services(cls, query_db: Session):
async def clear_login_log_services(cls, query_db: AsyncSession):
"""
清除操作日志信息service
:param query_db: orm对象
:return: 清除操作日志校验结果
"""
try:
LoginLogDao.clear_login_log_dao(query_db)
query_db.commit()
result = dict(is_success=True, message='清除成功')
await LoginLogDao.clear_login_log_dao(query_db)
await query_db.commit()
return CrudResponseModel(is_success=True, message='清除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def unlock_user_services(cls, request: Request, unlock_user: UnlockUser):
locked_user = await request.app.state.redis.get(f"account_lock:{unlock_user.user_name}")
locked_user = await request.app.state.redis.get(f'account_lock:{unlock_user.user_name}')
if locked_user:
await request.app.state.redis.delete(f"account_lock:{unlock_user.user_name}")
result = dict(is_success=True, message='解锁成功')
await request.app.state.redis.delete(f'account_lock:{unlock_user.user_name}')
return CrudResponseModel(is_success=True, message='解锁成功')
else:
result = dict(is_success=False, message='该用户未锁定')
return CrudResponseModel(**result)
raise ServiceException(message='该用户未锁定')
@staticmethod
def export_login_log_list_services(login_log_list: List):
async def export_login_log_list_services(login_log_list: List):
"""
导出登录日志信息service
:param login_log_list: 登录日志信息列表
:return: 登录日志信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"infoId": "访问编号",
"userName": "用户名称",
"ipaddr": "登录地址",
"loginLocation": "登录地点",
"browser": "浏览器",
"os": "操作系统",
"status": "登录状态",
"msg": "操作信息",
"loginTime": "登录日期"
'infoId': '访问编号',
'userName': '用户名称',
'ipaddr': '登录地址',
'loginLocation': '登录地点',
'browser': '浏览器',
'os': '操作系统',
'status': '登录状态',
'msg': '操作信息',
'loginTime': '登录日期',
}
data = login_log_list
@@ -238,7 +260,9 @@ class LoginLogService:
item['status'] = '成功'
else:
item['status'] = '失败'
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

View File

@@ -1,43 +1,57 @@
from fastapi import Request, Form
from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
import jwt
import random
import uuid
from datetime import timedelta
from module_admin.service.user_service import *
from module_admin.entity.vo.login_vo import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.dao.login_dao import *
from exceptions.exception import LoginException, AuthException
from config.env import AppConfig, JwtConfig, RedisInitKeyConfig
from datetime import datetime, timedelta, timezone
from fastapi import Depends, Form, Request
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jwt.exceptions import InvalidTokenError
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Dict, List, Optional, Union
from config.constant import CommonConstant, MenuConstant
from config.enums import RedisInitKeyConfig
from config.env import AppConfig, JwtConfig
from config.get_db import get_db
from exceptions.exception import LoginException, AuthException, ServiceException
from module_admin.dao.login_dao import login_by_account
from module_admin.dao.user_dao import UserDao
from module_admin.entity.do.menu_do import SysMenu
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.login_vo import MenuTreeModel, MetaModel, RouterModel, SmsCode, UserLogin, UserRegister
from module_admin.entity.vo.user_vo import AddUserModel, CurrentUserModel, ResetUserModel, TokenData, UserInfoModel
from module_admin.service.user_service import UserService
from utils.common_util import CamelCaseUtil
from utils.pwd_util import *
from utils.response_util import *
from utils.message_util import *
from utils.log_util import logger
from utils.message_util import message_service
from utils.pwd_util import PwdUtil
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='login')
class CustomOAuth2PasswordRequestForm(OAuth2PasswordRequestForm):
"""
自定义OAuth2PasswordRequestForm类增加验证码及会话编号参数
"""
def __init__(
self,
grant_type: str = Form(default=None, regex="password"),
username: str = Form(),
password: str = Form(),
scope: str = Form(default=""),
client_id: Optional[str] = Form(default=None),
client_secret: Optional[str] = Form(default=None),
code: Optional[str] = Form(default=""),
uuid: Optional[str] = Form(default=""),
login_info: Optional[Dict[str, str]] = Form(default=None)
self,
grant_type: str = Form(default=None, regex='password'),
username: str = Form(),
password: str = Form(),
scope: str = Form(default=''),
client_id: Optional[str] = Form(default=None),
client_secret: Optional[str] = Form(default=None),
code: Optional[str] = Form(default=''),
uuid: Optional[str] = Form(default=''),
login_info: Optional[Dict[str, str]] = Form(default=None),
):
super().__init__(grant_type=grant_type, username=username, password=password,
scope=scope, client_id=client_id, client_secret=client_secret)
super().__init__(
grant_type=grant_type,
username=username,
password=password,
scope=scope,
client_id=client_id,
client_secret=client_secret,
)
self.code = code
self.uuid = uuid
self.login_info = login_info
@@ -47,10 +61,12 @@ class LoginService:
"""
登录模块服务层
"""
@classmethod
async def authenticate_user(cls, request: Request, query_db: Session, login_user: UserLogin):
async def authenticate_user(cls, request: Request, query_db: AsyncSession, login_user: UserLogin):
"""
根据用户名密码校验用户登录
:param request: Request对象
:param query_db: orm对象
:param login_user: 登录用户对象
@@ -58,104 +74,119 @@ class LoginService:
"""
await cls.__check_login_ip(request)
account_lock = await request.app.state.redis.get(
f"{RedisInitKeyConfig.ACCOUNT_LOCK.get('key')}:{login_user.user_name}")
f'{RedisInitKeyConfig.ACCOUNT_LOCK.key}:{login_user.user_name}'
)
if login_user.user_name == account_lock:
logger.warning("账号已锁定,请稍后再试")
raise LoginException(data="", message="账号已锁定,请稍后再试")
logger.warning('账号已锁定,请稍后再试')
raise LoginException(data='', message='账号已锁定,请稍后再试')
# 判断请求是否来自于api文档如果是返回指定格式的结果用于修复api文档认证成功后token显示undefined的bug
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
request_from_swagger = (
request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
)
request_from_redoc = (
request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
)
# 判断是否开启验证码开启则验证否则不验证dev模式下来自API文档的登录请求不检验
if not login_user.captcha_enabled or ((request_from_swagger or request_from_redoc) and AppConfig.app_env == 'dev'):
if not login_user.captcha_enabled or (
(request_from_swagger or request_from_redoc) and AppConfig.app_env == 'dev'
):
pass
else:
await cls.__check_login_captcha(request, login_user)
user = login_by_account(query_db, login_user.user_name)
user = await login_by_account(query_db, login_user.user_name)
if not user:
logger.warning("用户不存在")
raise LoginException(data="", message="用户不存在")
logger.warning('用户不存在')
raise LoginException(data='', message='用户不存在')
if not PwdUtil.verify_password(login_user.password, user[0].password):
cache_password_error_count = await request.app.state.redis.get(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}")
f'{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.key}:{login_user.user_name}'
)
password_error_counted = 0
if cache_password_error_count:
password_error_counted = cache_password_error_count
password_error_count = int(password_error_counted) + 1
await request.app.state.redis.set(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}", password_error_count,
ex=timedelta(minutes=10))
f'{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.key}:{login_user.user_name}',
password_error_count,
ex=timedelta(minutes=10),
)
if password_error_count > 5:
await request.app.state.redis.delete(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}")
f'{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.key}:{login_user.user_name}'
)
await request.app.state.redis.set(
f"{RedisInitKeyConfig.ACCOUNT_LOCK.get('key')}:{login_user.user_name}", login_user.user_name,
ex=timedelta(minutes=10))
logger.warning("10分钟内密码已输错超过5次账号已锁定请10分钟后再试")
raise LoginException(data="", message="10分钟内密码已输错超过5次账号已锁定请10分钟后再试")
logger.warning("密码错误")
raise LoginException(data="", message="密码错误")
f'{RedisInitKeyConfig.ACCOUNT_LOCK.key}:{login_user.user_name}',
login_user.user_name,
ex=timedelta(minutes=10),
)
logger.warning('10分钟内密码已输错超过5次账号已锁定请10分钟后再试')
raise LoginException(data='', message='10分钟内密码已输错超过5次账号已锁定请10分钟后再试')
logger.warning('密码错误')
raise LoginException(data='', message='密码错误')
if user[0].status == '1':
logger.warning("用户已停用")
raise LoginException(data="", message="用户已停用")
await request.app.state.redis.delete(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}")
logger.warning('用户已停用')
raise LoginException(data='', message='用户已停用')
await request.app.state.redis.delete(f'{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.key}:{login_user.user_name}')
return user
@classmethod
async def __check_login_ip(cls, request: Request):
"""
校验用户登录ip是否在黑名单内
:param request: Request对象
:return: 校验结果
"""
black_ip_value = await request.app.state.redis.get(
f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.login.blackIPList")
black_ip_value = await request.app.state.redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:sys.login.blackIPList')
black_ip_list = black_ip_value.split(',') if black_ip_value else []
if request.headers.get('X-Forwarded-For') in black_ip_list:
logger.warning("当前IP禁止登录")
raise LoginException(data="", message="当前IP禁止登录")
logger.warning('当前IP禁止登录')
raise LoginException(data='', message='当前IP禁止登录')
return True
@classmethod
async def __check_login_captcha(cls, request: Request, login_user: UserLogin):
"""
校验用户登录验证码
:param request: Request对象
:param login_user: 登录用户对象
:return: 校验结果
"""
captcha_value = await request.app.state.redis.get(
f"{RedisInitKeyConfig.CAPTCHA_CODES.get('key')}:{login_user.uuid}")
captcha_value = await request.app.state.redis.get(f'{RedisInitKeyConfig.CAPTCHA_CODES.key}:{login_user.uuid}')
if not captcha_value:
logger.warning("验证码已失效")
raise LoginException(data="", message="验证码已失效")
logger.warning('验证码已失效')
raise LoginException(data='', message='验证码已失效')
if login_user.code != str(captcha_value):
logger.warning("验证码错误")
raise LoginException(data="", message="验证码错误")
logger.warning('验证码错误')
raise LoginException(data='', message='验证码错误')
return True
@classmethod
def create_access_token(cls, data: dict, expires_delta: Union[timedelta, None] = None):
async def create_access_token(cls, data: dict, expires_delta: Union[timedelta, None] = None):
"""
根据登录信息创建当前用户token
:param data: 登录信息
:param expires_delta: token有效期
:return: token
"""
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
expire = datetime.now(timezone.utc) + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=30)
to_encode.update({"exp": expire})
expire = datetime.now(timezone.utc) + timedelta(minutes=30)
to_encode.update({'exp': expire})
encoded_jwt = jwt.encode(to_encode, JwtConfig.jwt_secret_key, algorithm=JwtConfig.jwt_algorithm)
return encoded_jwt
@classmethod
async def get_current_user(cls, request: Request = Request, token: str = Depends(oauth2_scheme),
query_db: Session = Depends(get_db)):
async def get_current_user(
cls, request: Request = Request, token: str = Depends(oauth2_scheme), query_db: AsyncSession = Depends(get_db)
):
"""
根据token获取当前用户信息
:param request: Request对象
:param token: 用户token
:param query_db: orm对象
@@ -169,31 +200,39 @@ class LoginService:
if token.startswith('Bearer'):
token = token.split(' ')[1]
payload = jwt.decode(token, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm])
user_id: str = payload.get("user_id")
session_id: str = payload.get("session_id")
if user_id is None:
logger.warning("用户token不合法")
raise AuthException(data="", message="用户token不合法")
user_id: str = payload.get('user_id')
session_id: str = payload.get('session_id')
if not user_id:
logger.warning('用户token不合法')
raise AuthException(data='', message='用户token不合法')
token_data = TokenData(user_id=int(user_id))
except JWTError:
logger.warning("用户token已失效请重新登录")
raise AuthException(data="", message="用户token已失效请重新登录")
query_user = UserDao.get_user_by_id(query_db, user_id=token_data.user_id)
except InvalidTokenError:
logger.warning('用户token已失效请重新登录')
raise AuthException(data='', message='用户token已失效请重新登录')
query_user = await UserDao.get_user_by_id(query_db, user_id=token_data.user_id)
if query_user.get('user_basic_info') is None:
logger.warning("用户token不合法")
raise AuthException(data="", message="用户token不合法")
logger.warning('用户token不合法')
raise AuthException(data='', message='用户token不合法')
if AppConfig.app_same_time_login:
redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}")
redis_token = await request.app.state.redis.get(f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{session_id}')
else:
# 此方法可实现同一账号同一时间只能登录一次
redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{query_user.get('user_basic_info').user_id}")
redis_token = await request.app.state.redis.get(
f"{RedisInitKeyConfig.ACCESS_TOKEN.key}:{query_user.get('user_basic_info').user_id}"
)
if token == redis_token:
if AppConfig.app_same_time_login:
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", redis_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes))
await request.app.state.redis.set(
f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{session_id}',
redis_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes),
)
else:
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{query_user.get('user_basic_info').user_id}", redis_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes))
await request.app.state.redis.set(
f"{RedisInitKeyConfig.ACCESS_TOKEN.key}:{query_user.get('user_basic_info').user_id}",
redis_token,
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes),
)
role_id_list = [item.role_id for item in query_user.get('user_role_info')]
if 1 in role_id_list:
@@ -212,134 +251,187 @@ class LoginService:
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')),
),
)
return current_user
else:
logger.warning("用户token已失效请重新登录")
raise AuthException(data="", message="用户token已失效请重新登录")
logger.warning('用户token已失效请重新登录')
raise AuthException(data='', message='用户token已失效请重新登录')
@classmethod
async def get_current_user_routers(cls, user_id: int, query_db: Session):
async def get_current_user_routers(cls, user_id: int, query_db: AsyncSession):
"""
根据用户id获取当前用户路由信息
:param user_id: 用户id
:param query_db: orm对象
:return: 当前用户路由信息对象
"""
query_user = UserDao.get_user_by_id(query_db, user_id=user_id)
user_router_menu = [row for row in query_user.get('user_menu_info') if row.menu_type in ['M', 'C']]
user_router = cls.__generate_user_router_menu(0, user_router_menu)
return user_router
query_user = await UserDao.get_user_by_id(query_db, user_id=user_id)
user_router_menu = sorted(
[
row
for row in query_user.get('user_menu_info')
if row.menu_type in [MenuConstant.TYPE_DIR, MenuConstant.TYPE_MENU]
],
key=lambda x: x.order_num,
)
menus = cls.__generate_menus(0, user_router_menu)
user_router = cls.__generate_user_router_menu(menus)
return [router.model_dump(exclude_unset=True, by_alias=True) for router in user_router]
@classmethod
def __generate_user_router_menu(cls, pid: int, permission_list):
def __generate_menus(cls, pid: int, permission_list: List[SysMenu]):
"""
工具方法:根据菜单信息生成路由信息树形嵌套数据
工具方法:根据菜单信息生成菜单信息树形嵌套数据
:param pid: 菜单id
:param permission_list: 菜单列表信息
:return: 路由信息树形嵌套数据
:return: 菜单信息树形嵌套数据
"""
router_list = []
menu_list: List[MenuTreeModel] = []
for permission in permission_list:
if permission.parent_id == pid:
children = cls.__generate_user_router_menu(permission.menu_id, permission_list)
router_list_data = {}
if permission.menu_type == 'M':
router_list_data['name'] = permission.path.capitalize()
router_list_data['hidden'] = False if permission.visible == '0' else True
if permission.parent_id == 0:
router_list_data['component'] = 'Layout'
router_list_data['path'] = f'/{permission.path}'
else:
router_list_data['component'] = 'ParentView'
router_list_data['path'] = permission.path
if permission.is_frame == 1:
router_list_data['redirect'] = 'noRedirect'
else:
router_list_data['path'] = permission.path
if children:
router_list_data['alwaysShow'] = True
router_list_data['children'] = children
router_list_data['meta'] = {
'title': permission.menu_name,
'icon': permission.icon,
'noCache': False if permission.is_cache == '0' else True,
'link': permission.path if permission.is_frame == 0 else None
}
elif permission.menu_type == 'C':
router_list_data['name'] = permission.path.capitalize()
router_list_data['path'] = permission.path
router_list_data['hidden'] = False if permission.visible == '0' else True
router_list_data['component'] = permission.component
router_list_data['meta'] = {
'title': permission.menu_name,
'icon': permission.icon,
'noCache': False if permission.is_cache == '0' else True,
'link': permission.path if permission.is_frame == 0 else None
}
router_list.append(router_list_data)
children = cls.__generate_menus(permission.menu_id, permission_list)
menu_list_data = MenuTreeModel(**CamelCaseUtil.transform_result(permission))
if children:
menu_list_data.children = children
menu_list.append(menu_list_data)
return menu_list
@classmethod
def __generate_user_router_menu(cls, permission_list: List[MenuTreeModel]):
"""
工具方法:根据菜单树信息生成路由信息树形嵌套数据
:param permission_list: 菜单树列表信息
:return: 路由信息树形嵌套数据
"""
router_list: List[RouterModel] = []
for permission in permission_list:
router = RouterModel(
hidden=True if permission.visible == '1' else False,
name=RouterUtil.get_router_name(permission),
path=RouterUtil.get_router_path(permission),
component=RouterUtil.get_component(permission),
query=permission.query,
meta=MetaModel(
title=permission.menu_name,
icon=permission.icon,
noCache=True if permission.is_cache == 1 else False,
link=permission.path if RouterUtil.is_http(permission.path) else None,
),
)
c_menus = permission.children
if c_menus and permission.menu_type == MenuConstant.TYPE_DIR:
router.always_show = True
router.redirect = 'noRedirect'
router.children = cls.__generate_user_router_menu(c_menus)
elif RouterUtil.is_menu_frame(permission):
router.meta = None
children_list: List[RouterModel] = []
children = RouterModel(
path=permission.path,
component=permission.component,
name=RouterUtil.get_route_name(permission.route_name, permission.path),
meta=MetaModel(
title=permission.menu_name,
icon=permission.icon,
noCache=True if permission.is_cache == 1 else False,
link=permission.path if RouterUtil.is_http(permission.path) else None,
),
query=permission.query,
)
children_list.append(children)
router.children = children_list
elif permission.parent_id == 0 and RouterUtil.is_inner_link(permission):
router.meta = MetaModel(title=permission.menu_name, icon=permission.icon)
router.path = '/'
children_list: List[RouterModel] = []
router_path = RouterUtil.inner_link_replace_each(permission.path)
children = RouterModel(
path=router_path,
component=MenuConstant.INNER_LINK,
name=RouterUtil.get_route_name(permission.route_name, permission.path),
meta=MetaModel(
title=permission.menu_name,
icon=permission.icon,
link=permission.path if RouterUtil.is_http(permission.path) else None,
),
)
children_list.append(children)
router.children = children_list
router_list.append(router)
return router_list
@classmethod
async def register_user_services(cls, request: Request, query_db: Session, user_register: UserRegister):
async def register_user_services(cls, request: Request, query_db: AsyncSession, user_register: UserRegister):
"""
用户注册services
:param request: Request对象
:param query_db: orm对象
:param user_register: 注册用户对象
:return: 注册结果
"""
register_enabled = True if await request.app.state.redis.get(
f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.registerUser") == 'true' else False
captcha_enabled = True if await request.app.state.redis.get(
f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.captchaEnabled") == 'true' else False
register_enabled = (
True
if await request.app.state.redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:sys.account.registerUser')
== 'true'
else False
)
captcha_enabled = (
True
if await request.app.state.redis.get(f'{RedisInitKeyConfig.SYS_CONFIG.key}:sys.account.captchaEnabled')
== 'true'
else False
)
if user_register.password == user_register.confirm_password:
if register_enabled:
if captcha_enabled:
captcha_value = await request.app.state.redis.get(
f"{RedisInitKeyConfig.CAPTCHA_CODES.get('key')}:{user_register.uuid}")
f'{RedisInitKeyConfig.CAPTCHA_CODES.key}:{user_register.uuid}'
)
if not captcha_value:
logger.warning("验证码已失效")
return CrudResponseModel(is_success=False, message='验证码已失效')
raise ServiceException(message='验证码已失效')
elif user_register.code != str(captcha_value):
logger.warning("验证码错误")
return CrudResponseModel(is_success=False, message='验证码错误')
raise ServiceException(message='验证码错误')
add_user = AddUserModel(
userName=user_register.username,
nickName=user_register.username,
password=PwdUtil.get_password_hash(user_register.password)
password=PwdUtil.get_password_hash(user_register.password),
)
result = UserService.add_user_services(query_db, add_user)
result = await UserService.add_user_services(query_db, add_user)
return result
else:
result = dict(is_success=False, message='注册程序已关闭,禁止注册')
raise ServiceException(message='注册程序已关闭,禁止注册')
else:
result = dict(is_success=False, message='两次输入的密码不一致')
return CrudResponseModel(**result)
raise ServiceException(message='两次输入的密码不一致')
@classmethod
async def get_sms_code_services(cls, request: Request, query_db: Session, user: ResetUserModel):
async def get_sms_code_services(cls, request: Request, query_db: AsyncSession, user: ResetUserModel):
"""
获取短信验证码service
:param request: Request对象
:param query_db: orm对象
:param user: 用户对象
:return: 短信验证码对象
"""
redis_sms_result = await request.app.state.redis.get(
f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{user.session_id}")
redis_sms_result = await request.app.state.redis.get(f'{RedisInitKeyConfig.SMS_CODE.key}:{user.session_id}')
if redis_sms_result:
return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='短信验证码仍在有效期内'))
is_user = UserDao.get_user_by_name(query_db, user.user_name)
is_user = await UserDao.get_user_by_name(query_db, user.user_name)
if is_user:
sms_code = str(random.randint(100000, 999999))
session_id = str(uuid.uuid4())
await request.app.state.redis.set(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{session_id}", sms_code,
ex=timedelta(minutes=2))
await request.app.state.redis.set(
f'{RedisInitKeyConfig.SMS_CODE.key}:{session_id}', sms_code, ex=timedelta(minutes=2)
)
# 此处模拟调用短信服务
message_service(sms_code)
@@ -348,25 +440,27 @@ class LoginService:
return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='用户不存在'))
@classmethod
async def forget_user_services(cls, request: Request, query_db: Session, forget_user: ResetUserModel):
async def forget_user_services(cls, request: Request, query_db: AsyncSession, forget_user: ResetUserModel):
"""
用户忘记密码services
:param request: Request对象
:param query_db: orm对象
:param forget_user: 重置用户对象
:return: 重置结果
"""
redis_sms_result = await request.app.state.redis.get(
f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}")
f'{RedisInitKeyConfig.SMS_CODE.key}:{forget_user.session_id}'
)
if forget_user.sms_code == redis_sms_result:
forget_user.password = PwdUtil.get_password_hash(forget_user.password)
forget_user.user_id = UserDao.get_user_by_name(query_db, forget_user.user_name).user_id
edit_result = UserService.reset_user_services(query_db, forget_user)
forget_user.user_id = (await UserDao.get_user_by_name(query_db, forget_user.user_name)).user_id
edit_result = await UserService.reset_user_services(query_db, forget_user)
result = edit_result.dict()
elif not redis_sms_result:
result = dict(is_success=False, message='短信验证码已过期')
else:
await request.app.state.redis.delete(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}")
await request.app.state.redis.delete(f'{RedisInitKeyConfig.SMS_CODE.key}:{forget_user.session_id}')
result = dict(is_success=False, message='短信验证码不正确')
return CrudResponseModel(**result)
@@ -375,12 +469,138 @@ class LoginService:
async def logout_services(cls, request: Request, session_id: str):
"""
退出登录services
:param request: Request对象
:param session_id: 会话编号
:return: 退出登录结果
"""
await request.app.state.redis.delete(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}")
await request.app.state.redis.delete(f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{session_id}')
# await request.app.state.redis.delete(f'{current_user.user.user_id}_access_token')
# await request.app.state.redis.delete(f'{current_user.user.user_id}_session_id')
return True
class RouterUtil:
"""
路由处理工具类
"""
@classmethod
def get_router_name(cls, menu: MenuTreeModel):
"""
获取路由名称
:param menu: 菜单数对象
:return: 路由名称
"""
# 非外链并且是一级目录(类型为目录)
if cls.is_menu_frame(menu):
return ''
return cls.get_route_name(menu.route_name, menu.path)
@classmethod
def get_route_name(cls, name: str, path: str):
"""
获取路由名称,如没有配置路由名称则取路由地址
:param name: 路由名称
:param path: 路由地址
:return: 路由名称(驼峰格式)
"""
router_name = name if name else path
return router_name.capitalize()
@classmethod
def get_router_path(cls, menu: MenuTreeModel):
"""
获取路由地址
:param menu: 菜单数对象
:return: 路由地址
"""
# 内链打开外网方式
router_path = menu.path
if menu.parent_id != 0 and cls.is_inner_link(menu):
router_path = cls.inner_link_replace_each(router_path)
# 非外链并且是一级目录(类型为目录)
if menu.parent_id == 0 and menu.menu_type == MenuConstant.TYPE_DIR and menu.is_frame == MenuConstant.NO_FRAME:
router_path = f'/{menu.path}'
# 非外链并且是一级目录(类型为菜单)
elif cls.is_menu_frame(menu):
router_path = '/'
return router_path
@classmethod
def get_component(cls, menu: MenuTreeModel):
"""
获取组件信息
:param menu: 菜单数对象
:return: 组件信息
"""
component = MenuConstant.LAYOUT
if menu.component and not cls.is_menu_frame(menu):
component = menu.component
elif (menu.component is None or menu.component == '') and menu.parent_id != 0 and cls.is_inner_link(menu):
component = MenuConstant.INNER_LINK
elif (menu.component is None or menu.component == '') and cls.is_parent_view(menu):
component = MenuConstant.PARENT_VIEW
return component
@classmethod
def is_menu_frame(cls, menu: MenuTreeModel):
"""
判断是否为菜单内部跳转
:param menu: 菜单数对象
:return: 是否为菜单内部跳转
"""
return (
menu.parent_id == 0 and menu.menu_type == MenuConstant.TYPE_MENU and menu.is_frame == MenuConstant.NO_FRAME
)
@classmethod
def is_inner_link(cls, menu: MenuTreeModel):
"""
判断是否为内链组件
:param menu: 菜单数对象
:return: 是否为内链组件
"""
return menu.is_frame == MenuConstant.NO_FRAME and cls.is_http(menu.path)
@classmethod
def is_parent_view(cls, menu: MenuTreeModel):
"""
判断是否为parent_view组件
:param menu: 菜单数对象
:return: 是否为parent_view组件
"""
return menu.parent_id != 0 and menu.menu_type == MenuConstant.TYPE_DIR
@classmethod
def is_http(cls, link: str):
"""
判断是否为http(s)://开头
:param link: 链接
:return: 是否为http(s)://开头
"""
return link.startswith(CommonConstant.HTTP) or link.startswith(CommonConstant.HTTPS)
@classmethod
def inner_link_replace_each(cls, path: str):
"""
内链域名特殊字符替换
:param path: 内链域名
:return: 替换后的内链域名
"""
old_values = [CommonConstant.HTTP, CommonConstant.HTTPS, CommonConstant.WWW, '.', ':']
new_values = ['', '', '', '/', '/']
for old, new in zip(old_values, new_values):
path = path.replace(old, new)
return path

View File

@@ -1,9 +1,15 @@
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.entity.vo.role_vo import RoleMenuQueryModel
from module_admin.entity.vo.common_vo import CrudResponseModel
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Optional
from config.constant import CommonConstant, MenuConstant
from exceptions.exception import ServiceException, ServiceWarning
from module_admin.dao.menu_dao import MenuDao
from module_admin.dao.role_dao import RoleDao
from module_admin.dao.menu_dao import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.menu_vo import DeleteMenuModel, MenuQueryModel, MenuModel
from module_admin.entity.vo.role_vo import RoleMenuQueryModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from utils.common_util import CamelCaseUtil
from utils.string_util import StringUtil
class MenuService:
@@ -12,133 +18,168 @@ class MenuService:
"""
@classmethod
def get_menu_tree_services(cls, query_db: Session, current_user: Optional[CurrentUserModel] = None):
async def get_menu_tree_services(cls, query_db: AsyncSession, current_user: Optional[CurrentUserModel] = None):
"""
获取菜单树信息service
:param query_db: orm对象
:param current_user: 当前用户对象
:return: 菜单树信息对象
"""
menu_list_result = MenuDao.get_menu_list_for_tree(query_db, current_user.user.user_id, current_user.user.role)
menu_list_result = await MenuDao.get_menu_list_for_tree(
query_db, current_user.user.user_id, current_user.user.role
)
menu_tree_result = cls.list_to_tree(menu_list_result)
return menu_tree_result
@classmethod
def get_role_menu_tree_services(cls, query_db: Session, role_id: int, current_user: Optional[CurrentUserModel] = None):
async def get_role_menu_tree_services(
cls, query_db: AsyncSession, role_id: int, current_user: Optional[CurrentUserModel] = None
):
"""
根据角色id获取菜单树信息service
:param query_db: orm对象
:param role_id: 角色id
:param current_user: 当前用户对象
:return: 当前角色id的菜单树信息对象
"""
menu_list_result = MenuDao.get_menu_list_for_tree(query_db, current_user.user.user_id, current_user.user.role)
menu_tree_result = cls.list_to_tree(menu_list_result)
role_menu_list = RoleDao.get_role_menu_dao(query_db, role_id)
checked_keys = [row.menu_id for row in role_menu_list]
result = RoleMenuQueryModel(
menus=menu_tree_result,
checkedKeys=checked_keys
menu_list_result = await MenuDao.get_menu_list_for_tree(
query_db, current_user.user.user_id, current_user.user.role
)
menu_tree_result = cls.list_to_tree(menu_list_result)
role = await RoleDao.get_role_detail_by_id(query_db, role_id)
role_menu_list = await RoleDao.get_role_menu_dao(query_db, role)
checked_keys = [row.menu_id for row in role_menu_list]
result = RoleMenuQueryModel(menus=menu_tree_result, checkedKeys=checked_keys)
return result
@classmethod
def get_menu_list_services(cls, query_db: Session, page_object: MenuQueryModel, current_user: Optional[CurrentUserModel] = None):
async def get_menu_list_services(
cls, query_db: AsyncSession, page_object: MenuQueryModel, current_user: Optional[CurrentUserModel] = None
):
"""
获取菜单列表信息service
:param query_db: orm对象
:param page_object: 分页查询参数对象
:param current_user: 当前用户对象
:return: 菜单列表信息对象
"""
menu_list_result = MenuDao.get_menu_list(query_db, page_object, current_user.user.user_id, current_user.user.role)
menu_list_result = await MenuDao.get_menu_list(
query_db, page_object, current_user.user.user_id, current_user.user.role
)
return CamelCaseUtil.transform_result(menu_list_result)
@classmethod
def add_menu_services(cls, query_db: Session, page_object: MenuModel):
async def check_menu_name_unique_services(cls, query_db: AsyncSession, page_object: MenuModel):
"""
校验菜单名称是否唯一service
:param query_db: orm对象
:param page_object: 菜单对象
:return: 校验结果
"""
menu_id = -1 if page_object.menu_id is None else page_object.menu_id
menu = await MenuDao.get_menu_detail_by_info(query_db, MenuModel(menuName=page_object.menu_name))
if menu and menu.menu_id != menu_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_menu_services(cls, query_db: AsyncSession, page_object: MenuModel):
"""
新增菜单信息service
:param query_db: orm对象
:param page_object: 新增菜单对象
:return: 新增菜单校验结果
"""
menu = MenuDao.get_menu_detail_by_info(query_db, MenuModel(parentId=page_object.parent_id, menuName=page_object.menu_name, menuType=page_object.menu_type))
if menu:
result = dict(is_success=False, message='同一目录下不允许存在同名同类型的菜单')
if not await cls.check_menu_name_unique_services(query_db, page_object):
raise ServiceException(message=f'新增菜单{page_object.menu_name}失败,菜单名称已存在')
elif page_object.is_frame == MenuConstant.YES_FRAME and not StringUtil.is_http(page_object.path):
raise ServiceException(message=f'新增菜单{page_object.menu_name}失败地址必须以http(s)://开头')
else:
try:
MenuDao.add_menu_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
await MenuDao.add_menu_dao(query_db, page_object)
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_menu_services(cls, query_db: Session, page_object: MenuModel):
async def edit_menu_services(cls, query_db: AsyncSession, page_object: MenuModel):
"""
编辑菜单信息service
:param query_db: orm对象
:param page_object: 编辑部门对象
:return: 编辑菜单校验结果
"""
edit_menu = page_object.model_dump(exclude_unset=True)
menu_info = cls.menu_detail_services(query_db, edit_menu.get('menu_id'))
if menu_info:
if menu_info.parent_id != page_object.parent_id or menu_info.menu_name != page_object.menu_name or menu_info.menu_type != page_object.menu_type:
menu = MenuDao.get_menu_detail_by_info(query_db, MenuModel(parentId=page_object.parent_id, menuName=page_object.menu_name, menuType=page_object.menu_type))
if menu:
result = dict(is_success=False, message='同一目录下不允许存在同名同类型的菜单')
return CrudResponseModel(**result)
try:
MenuDao.edit_menu_dao(query_db, edit_menu)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
menu_info = await cls.menu_detail_services(query_db, page_object.menu_id)
if menu_info.menu_id:
if not await cls.check_menu_name_unique_services(query_db, page_object):
raise ServiceException(message=f'修改菜单{page_object.menu_name}失败,菜单名称已存在')
elif page_object.is_frame == MenuConstant.YES_FRAME and not StringUtil.is_http(page_object.path):
raise ServiceException(message=f'修改菜单{page_object.menu_name}失败地址必须以http(s)://开头')
elif page_object.menu_id == page_object.parent_id:
raise ServiceException(message=f'修改菜单{page_object.menu_name}失败,上级菜单不能选择自己')
else:
try:
await MenuDao.edit_menu_dao(query_db, edit_menu)
await query_db.commit()
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='菜单不存在')
return CrudResponseModel(**result)
raise ServiceException(message='菜单不存在')
@classmethod
def delete_menu_services(cls, query_db: Session, page_object: DeleteMenuModel):
async def delete_menu_services(cls, query_db: AsyncSession, page_object: DeleteMenuModel):
"""
删除菜单信息service
:param query_db: orm对象
:param page_object: 删除菜单对象
:return: 删除菜单校验结果
"""
if page_object.menu_ids.split(','):
if page_object.menu_ids:
menu_id_list = page_object.menu_ids.split(',')
try:
for menu_id in menu_id_list:
MenuDao.delete_menu_dao(query_db, MenuModel(menuId=menu_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
if (await MenuDao.has_child_by_menu_id_dao(query_db, int(menu_id))) > 0:
raise ServiceWarning(message='存在子菜单,不允许删除')
elif (await MenuDao.check_menu_exist_role_dao(query_db, int(menu_id))) > 0:
raise ServiceWarning(message='菜单已分配,不允许删除')
await MenuDao.delete_menu_dao(query_db, MenuModel(menuId=menu_id))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入菜单id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入菜单id为空')
@classmethod
def menu_detail_services(cls, query_db: Session, menu_id: int):
async def menu_detail_services(cls, query_db: AsyncSession, menu_id: int):
"""
获取菜单详细信息service
:param query_db: orm对象
:param menu_id: 菜单id
:return: 菜单id对应的信息
"""
menu = MenuDao.get_menu_detail_by_id(query_db, menu_id=menu_id)
result = MenuModel(**CamelCaseUtil.transform_result(menu))
menu = await MenuDao.get_menu_detail_by_id(query_db, menu_id=menu_id)
if menu:
result = MenuModel(**CamelCaseUtil.transform_result(menu))
else:
result = MenuModel(**dict())
return result
@@ -146,10 +187,13 @@ class MenuService:
def list_to_tree(cls, permission_list: list) -> list:
"""
工具方法:根据菜单列表信息生成树形嵌套数据
:param permission_list: 菜单列表信息
:return: 菜单树形嵌套数据
"""
permission_list = [dict(id=item.menu_id, label=item.menu_name, parentId=item.parent_id) for item in permission_list]
permission_list = [
dict(id=item.menu_id, label=item.menu_name, parentId=item.parent_id) for item in permission_list
]
# 转成id为key的字典
mapping: dict = dict(zip([i['id'] for i in permission_list], permission_list))

View File

@@ -1,6 +1,10 @@
from module_admin.dao.notice_dao import *
from sqlalchemy.ext.asyncio import AsyncSession
from config.constant import CommonConstant
from exceptions.exception import ServiceException
from module_admin.dao.notice_dao import NoticeDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
from module_admin.entity.vo.notice_vo import DeleteNoticeModel, NoticeModel, NoticePageQueryModel
from utils.common_util import CamelCaseUtil
class NoticeService:
@@ -9,99 +13,116 @@ class NoticeService:
"""
@classmethod
def get_notice_list_services(cls, query_db: Session, query_object: NoticePageQueryModel, is_page: bool = True):
async def get_notice_list_services(
cls, query_db: AsyncSession, query_object: NoticePageQueryModel, is_page: bool = True
):
"""
获取通知公告列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 通知公告列表信息对象
"""
notice_list_result = NoticeDao.get_notice_list(query_db, query_object, is_page)
notice_list_result = await NoticeDao.get_notice_list(query_db, query_object, is_page)
return notice_list_result
@classmethod
def add_notice_services(cls, query_db: Session, page_object: NoticeModel):
async def check_notice_unique_services(cls, query_db: AsyncSession, page_object: NoticeModel):
"""
校验通知公告是否存在service
:param query_db: orm对象
:param page_object: 通知公告对象
:return: 校验结果
"""
notice_id = -1 if page_object.notice_id is None else page_object.notice_id
notice = await NoticeDao.get_notice_detail_by_info(query_db, page_object)
if notice and notice.notice_id != notice_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_notice_services(cls, query_db: AsyncSession, page_object: NoticeModel):
"""
新增通知公告信息service
:param query_db: orm对象
:param page_object: 新增通知公告对象
:return: 新增通知公告校验结果
"""
notice = NoticeDao.get_notice_detail_by_info(query_db, page_object)
if notice:
result = dict(is_success=False, message='通知公告已存在')
if not await cls.check_notice_unique_services(query_db, page_object):
raise ServiceException(message=f'新增通知公告{page_object.notice_title}失败,通知公告已存在')
else:
try:
NoticeDao.add_notice_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
await NoticeDao.add_notice_dao(query_db, page_object)
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_notice_services(cls, query_db: Session, page_object: NoticeModel):
async def edit_notice_services(cls, query_db: AsyncSession, page_object: NoticeModel):
"""
编辑通知公告信息service
:param query_db: orm对象
:param page_object: 编辑通知公告对象
:return: 编辑通知公告校验结果
"""
edit_notice = page_object.model_dump(exclude_unset=True)
notice_info = cls.notice_detail_services(query_db, edit_notice.get('notice_id'))
if notice_info:
if notice_info.notice_title != page_object.notice_title or notice_info.notice_type != page_object.notice_type or notice_info.notice_content != page_object.notice_content:
notice = NoticeDao.get_notice_detail_by_info(query_db, page_object)
if notice:
result = dict(is_success=False, message='通知公告已存在')
return CrudResponseModel(**result)
try:
NoticeDao.edit_notice_dao(query_db, edit_notice)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
notice_info = await cls.notice_detail_services(query_db, page_object.notice_id)
if notice_info.notice_id:
if not await cls.check_notice_unique_services(query_db, page_object):
raise ServiceException(message=f'修改通知公告{page_object.notice_title}失败,通知公告已存在')
else:
try:
await NoticeDao.edit_notice_dao(query_db, edit_notice)
await query_db.commit()
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='通知公告不存在')
return CrudResponseModel(**result)
raise ServiceException(message='通知公告不存在')
@classmethod
def delete_notice_services(cls, query_db: Session, page_object: DeleteNoticeModel):
async def delete_notice_services(cls, query_db: AsyncSession, page_object: DeleteNoticeModel):
"""
删除通知公告信息service
:param query_db: orm对象
:param page_object: 删除通知公告对象
:return: 删除通知公告校验结果
"""
if page_object.notice_ids.split(','):
if page_object.notice_ids:
notice_id_list = page_object.notice_ids.split(',')
try:
for notice_id in notice_id_list:
NoticeDao.delete_notice_dao(query_db, NoticeModel(noticeId=notice_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
await NoticeDao.delete_notice_dao(query_db, NoticeModel(noticeId=notice_id))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入通知公告id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入通知公告id为空')
@classmethod
def notice_detail_services(cls, query_db: Session, notice_id: int):
async def notice_detail_services(cls, query_db: AsyncSession, notice_id: int):
"""
获取通知公告详细信息service
:param query_db: orm对象
:param notice_id: 通知公告id
:return: 通知公告id对应的信息
"""
notice = NoticeDao.get_notice_detail_by_id(query_db, notice_id=notice_id)
result = NoticeModel(**CamelCaseUtil.transform_result(notice))
notice = await NoticeDao.get_notice_detail_by_id(query_db, notice_id=notice_id)
if notice:
result = NoticeModel(**CamelCaseUtil.transform_result(notice))
else:
result = NoticeModel(**dict())
return result

View File

@@ -1,8 +1,10 @@
import jwt
from fastapi import Request
from jose import jwt
from config.env import JwtConfig, RedisInitKeyConfig
from module_admin.entity.vo.online_vo import *
from config.enums import RedisInitKeyConfig
from config.env import JwtConfig
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.online_vo import DeleteOnlineModel, OnlineQueryModel
from utils.common_util import CamelCaseUtil
@@ -15,11 +17,12 @@ class OnlineService:
async def get_online_list_services(cls, request: Request, query_object: OnlineQueryModel):
"""
获取在线用户表信息service
:param request: Request对象
:param query_object: 查询参数对象
:return: 在线用户列表信息
"""
access_token_keys = await request.app.state.redis.keys(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}*")
access_token_keys = await request.app.state.redis.keys(f'{RedisInitKeyConfig.ACCESS_TOKEN.key}*')
if not access_token_keys:
access_token_keys = []
access_token_values_list = [await request.app.state.redis.get(key) for key in access_token_keys]
@@ -34,18 +37,20 @@ class OnlineService:
login_location=payload.get('login_info').get('loginLocation'),
browser=payload.get('login_info').get('browser'),
os=payload.get('login_info').get('os'),
login_time=payload.get('login_info').get('loginTime')
login_time=payload.get('login_info').get('loginTime'),
)
if query_object.user_name and not query_object.ipaddr:
if query_object.user_name == payload.get('login_info').get('ipaddr'):
if query_object.user_name == payload.get('user_name'):
online_info_list = [online_dict]
break
elif not query_object.user_name and query_object.ipaddr:
if query_object.ipaddr == payload.get('ipaddr'):
if query_object.ipaddr == payload.get('login_info').get('ipaddr'):
online_info_list = [online_dict]
break
elif query_object.user_name and query_object.ipaddr:
if query_object.user_name == payload.get('user_name') and query_object.ipaddr == payload.get('login_info').get('ipaddr'):
if query_object.user_name == payload.get('user_name') and query_object.ipaddr == payload.get(
'login_info'
).get('ipaddr'):
online_info_list = [online_dict]
break
else:
@@ -57,15 +62,15 @@ class OnlineService:
async def delete_online_services(cls, request: Request, page_object: DeleteOnlineModel):
"""
强退在线用户信息service
:param request: Request对象
:param page_object: 强退在线用户对象
:return: 强退在线用户校验结果
"""
if page_object.token_ids.split(','):
if page_object.token_ids:
token_id_list = page_object.token_ids.split(',')
for token_id in token_id_list:
await request.app.state.redis.delete(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{token_id}")
result = dict(is_success=True, message='强退成功')
await request.app.state.redis.delete(f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{token_id}')
return CrudResponseModel(is_success=True, message='强退成功')
else:
result = dict(is_success=False, message='传入session_id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入session_id为空')

View File

@@ -1,129 +1,175 @@
from module_admin.dao.post_dao import *
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from exceptions.exception import ServiceException
from module_admin.dao.post_dao import PostDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
from module_admin.entity.vo.post_vo import DeletePostModel, PostModel, PostPageQueryModel
from utils.common_util import CamelCaseUtil, export_list2excel
class PostService:
"""
岗位管理模块服务层
"""
@classmethod
def get_post_list_services(cls, query_db: Session, query_object: PostPageQueryModel, is_page: bool = False):
async def get_post_list_services(
cls, query_db: AsyncSession, query_object: PostPageQueryModel, is_page: bool = False
):
"""
获取岗位列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: 岗位列表信息对象
"""
post_list_result = PostDao.get_post_list(query_db, query_object, is_page)
post_list_result = await PostDao.get_post_list(query_db, query_object, is_page)
return post_list_result
@classmethod
def add_post_services(cls, query_db: Session, page_object: PostModel):
async def check_post_name_unique_services(cls, query_db: AsyncSession, page_object: PostModel):
"""
检查岗位名称是否唯一service
:param query_db: orm对象
:param page_object: 岗位对象
:return: 校验结果
"""
post_id = -1 if page_object.post_id is None else page_object.post_id
post = await PostDao.get_post_detail_by_info(query_db, PostModel(postName=page_object.post_name))
if post and post.post_id != post_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def check_post_code_unique_services(cls, query_db: AsyncSession, page_object: PostModel):
"""
检查岗位编码是否唯一service
:param query_db: orm对象
:param page_object: 岗位对象
:return: 校验结果
"""
post_id = -1 if page_object.post_id is None else page_object.post_id
post = await PostDao.get_post_detail_by_info(query_db, PostModel(postCode=page_object.post_code))
if post and post.post_id != post_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_post_services(cls, query_db: AsyncSession, page_object: PostModel):
"""
新增岗位信息service
:param query_db: orm对象
:param page_object: 新增岗位对象
:return: 新增岗位校验结果
"""
post = PostDao.get_post_detail_by_info(query_db, PostModel(postName=page_object.post_name))
if post:
result = dict(is_success=False, message='岗位名称已存在')
if not await cls.check_post_name_unique_services(query_db, page_object):
raise ServiceException(message=f'新增岗位{page_object.post_name}失败,岗位名称已存在')
elif not await cls.check_post_code_unique_services(query_db, page_object):
raise ServiceException(message=f'新增岗位{page_object.post_name}失败,岗位编码已存在')
else:
try:
PostDao.add_post_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
await PostDao.add_post_dao(query_db, page_object)
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_post_services(cls, query_db: Session, page_object: PostModel):
async def edit_post_services(cls, query_db: AsyncSession, page_object: PostModel):
"""
编辑岗位信息service
:param query_db: orm对象
:param page_object: 编辑岗位对象
:return: 编辑岗位校验结果
"""
edit_post = page_object.model_dump(exclude_unset=True)
post_info = cls.post_detail_services(query_db, edit_post.get('post_id'))
if post_info:
if post_info.post_name != page_object.post_name:
post = PostDao.get_post_detail_by_info(query_db, PostModel(postName=page_object.post_name))
if post:
result = dict(is_success=False, message='岗位名称已存在')
return CrudResponseModel(**result)
try:
PostDao.edit_post_dao(query_db, edit_post)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
post_info = await cls.post_detail_services(query_db, page_object.post_id)
if post_info.post_id:
if not await cls.check_post_name_unique_services(query_db, page_object):
raise ServiceException(message=f'修改岗位{page_object.post_name}失败,岗位名称已存在')
elif not await cls.check_post_code_unique_services(query_db, page_object):
raise ServiceException(message=f'修改岗位{page_object.post_name}失败,岗位编码已存在')
else:
try:
await PostDao.edit_post_dao(query_db, edit_post)
await query_db.commit()
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='岗位不存在')
return CrudResponseModel(**result)
raise ServiceException(message='岗位不存在')
@classmethod
def delete_post_services(cls, query_db: Session, page_object: DeletePostModel):
async def delete_post_services(cls, query_db: AsyncSession, page_object: DeletePostModel):
"""
删除岗位信息service
:param query_db: orm对象
:param page_object: 删除岗位对象
:return: 删除岗位校验结果
"""
if page_object.post_ids.split(','):
if page_object.post_ids:
post_id_list = page_object.post_ids.split(',')
try:
for post_id in post_id_list:
PostDao.delete_post_dao(query_db, PostModel(postId=post_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
post = await cls.post_detail_services(query_db, int(post_id))
if (await PostDao.count_user_post_dao(query_db, int(post_id))) > 0:
raise ServiceException(message=f'{post.post_name}已分配,不能删除')
await PostDao.delete_post_dao(query_db, PostModel(postId=post_id))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入岗位id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入岗位id为空')
@classmethod
def post_detail_services(cls, query_db: Session, post_id: int):
async def post_detail_services(cls, query_db: AsyncSession, post_id: int):
"""
获取岗位详细信息service
:param query_db: orm对象
:param post_id: 岗位id
:return: 岗位id对应的信息
"""
post = PostDao.get_post_detail_by_id(query_db, post_id=post_id)
result = PostModel(**CamelCaseUtil.transform_result(post))
post = await PostDao.get_post_detail_by_id(query_db, post_id=post_id)
if post:
result = PostModel(**CamelCaseUtil.transform_result(post))
else:
result = PostModel(**dict())
return result
@staticmethod
def export_post_list_services(post_list: List):
async def export_post_list_services(post_list: List):
"""
导出岗位信息service
:param post_list: 岗位信息列表
:return: 岗位信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"postId": "岗位编号",
"postCode": "岗位编码",
"postName": "岗位名称",
"postSort": "显示顺序",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
'postId': '岗位编号',
'postCode': '岗位编码',
'postName': '岗位名称',
'postSort': '显示顺序',
'status': '状态',
'createBy': '创建者',
'createTime': '创建时间',
'updateBy': '更新者',
'updateTime': '更新时间',
'remark': '备注',
}
data = post_list
@@ -133,7 +179,9 @@ class PostService:
item['status'] = '正常'
else:
item['status'] = '停用'
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

View File

@@ -1,9 +1,22 @@
from module_admin.entity.vo.user_vo import UserInfoModel, UserRolePageQueryModel
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.role_vo import (
AddRoleModel,
DeleteRoleModel,
RoleDeptModel,
RoleDeptQueryModel,
RoleMenuModel,
RoleModel,
RolePageQueryModel,
)
from module_admin.entity.vo.user_vo import UserInfoModel, UserRolePageQueryModel
from module_admin.dao.role_dao import RoleDao
from module_admin.dao.user_dao import UserDao
from module_admin.dao.role_dao import *
from utils.common_util import CamelCaseUtil, export_list2excel
from utils.page_util import PageResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
class RoleService:
@@ -12,79 +25,146 @@ class RoleService:
"""
@classmethod
def get_role_select_option_services(cls, query_db: Session):
async def get_role_select_option_services(cls, query_db: AsyncSession):
"""
获取角色列表不分页信息service
:param query_db: orm对象
:return: 角色列表不分页信息对象
"""
role_list_result = RoleDao.get_role_select_option_dao(query_db)
role_list_result = await RoleDao.get_role_select_option_dao(query_db)
return CamelCaseUtil.transform_result(role_list_result)
@classmethod
def get_role_dept_tree_services(cls, query_db: Session, role_id: int):
async def get_role_dept_tree_services(cls, query_db: AsyncSession, role_id: int):
"""
根据角色id获取部门树信息service
:param query_db: orm对象
:param role_id: 角色id
:return: 当前角色id的部门树信息对象
"""
role_dept_list = RoleDao.get_role_dept_dao(query_db, role_id)
role = await cls.role_detail_services(query_db, role_id)
role_dept_list = await RoleDao.get_role_dept_dao(query_db, role)
checked_keys = [row.dept_id for row in role_dept_list]
result = RoleDeptQueryModel(
checkedKeys=checked_keys
)
result = RoleDeptQueryModel(checkedKeys=checked_keys)
return result
@classmethod
def get_role_list_services(cls, query_db: Session, query_object: RolePageQueryModel, is_page: bool = False):
async def get_role_list_services(
cls, query_db: AsyncSession, query_object: RolePageQueryModel, 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: 角色列表信息对象
"""
role_list_result = RoleDao.get_role_list(query_db, query_object, is_page)
role_list_result = await RoleDao.get_role_list(query_db, query_object, data_scope_sql, is_page)
return role_list_result
@classmethod
def add_role_services(cls, query_db: Session, page_object: AddRoleModel):
async def check_role_allowed_services(cls, check_role: RoleModel):
"""
校验角色是否允许操作service
:param check_role: 角色信息
:return: 校验结果
"""
if check_role.admin:
raise ServiceException(message='不允许操作超级管理员角色')
else:
return CrudResponseModel(is_success=True, message='校验通过')
@classmethod
async def check_role_data_scope_services(cls, query_db: AsyncSession, role_ids: str, data_scope_sql: str):
"""
校验角色是否有数据权限service
:param query_db: orm对象
:param role_ids: 角色id
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 校验结果
"""
role_id_list = role_ids.split(',') if role_ids else []
if role_id_list:
for role_id in role_id_list:
roles = await RoleDao.get_role_list(
query_db, RolePageQueryModel(roleId=int(role_id)), data_scope_sql, is_page=False
)
if roles:
continue
else:
raise ServiceException(message='没有权限访问角色数据')
@classmethod
async def check_role_name_unique_services(cls, query_db: AsyncSession, page_object: RoleModel):
"""
校验角色名称是否唯一service
:param query_db: orm对象
:param page_object: 角色对象
:return: 校验结果
"""
role_id = -1 if page_object.role_id is None else page_object.role_id
role = await RoleDao.get_role_by_info(query_db, RoleModel(roleName=page_object.role_name))
if role and role.role_id != role_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def check_role_key_unique_services(cls, query_db: AsyncSession, page_object: RoleModel):
"""
校验角色权限字符是否唯一service
:param query_db: orm对象
:param page_object: 角色对象
:return: 校验结果
"""
role_id = -1 if page_object.role_id is None else page_object.role_id
role = await RoleDao.get_role_by_info(query_db, RoleModel(roleKey=page_object.role_key))
if role and role.role_id != role_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_role_services(cls, query_db: AsyncSession, page_object: AddRoleModel):
"""
新增角色信息service
:param query_db: orm对象
:param page_object: 新增角色对象
:return: 新增角色校验结果
"""
add_role = RoleModel(**page_object.model_dump(by_alias=True))
role_name = RoleDao.get_role_by_info(query_db, RoleModel(roleName=page_object.role_name))
role_key = RoleDao.get_role_by_info(query_db, RoleModel(roleKey=page_object.role_key))
if role_name:
result = dict(is_success=False, message='角色名称已存在')
elif role_key:
result = dict(is_success=False, message='权限字符已存在')
if not await cls.check_role_name_unique_services(query_db, page_object):
raise ServiceException(message=f'新增角色{page_object.role_name}失败,角色名称已存在')
elif not await cls.check_role_key_unique_services(query_db, page_object):
raise ServiceException(message=f'新增角色{page_object.role_name}失败,角色权限已存在')
else:
try:
add_result = RoleDao.add_role_dao(query_db, add_role)
add_result = await RoleDao.add_role_dao(query_db, add_role)
role_id = add_result.role_id
if page_object.menu_ids:
for menu in page_object.menu_ids:
RoleDao.add_role_menu_dao(query_db, RoleMenuModel(roleId=role_id, menuId=menu))
query_db.commit()
result = dict(is_success=True, message='新增成功')
await RoleDao.add_role_menu_dao(query_db, RoleMenuModel(roleId=role_id, menuId=menu))
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_role_services(cls, query_db: Session, page_object: AddRoleModel):
async def edit_role_services(cls, query_db: AsyncSession, page_object: AddRoleModel):
"""
编辑角色信息service
:param query_db: orm对象
:param page_object: 编辑角色对象
:return: 编辑角色校验结果
@@ -94,129 +174,125 @@ class RoleService:
del edit_role['menu_ids']
if page_object.type == 'status':
del edit_role['type']
role_info = cls.role_detail_services(query_db, edit_role.get('role_id'))
role_info = await cls.role_detail_services(query_db, edit_role.get('role_id'))
if role_info:
if page_object.type != 'status' and role_info.role_name != page_object.role_name:
role_name = RoleDao.get_role_by_info(query_db, RoleModel(roleName=page_object.role_name))
if role_name:
result = dict(is_success=False, message='角色名称已存在')
return CrudResponseModel(**result)
elif page_object.type != 'status' and role_info.role_key != page_object.role_key:
role_key = RoleDao.get_role_by_info(query_db, RoleModel(roleKey=page_object.role_key))
if role_key:
result = dict(is_success=False, message='权限字符已存在')
return CrudResponseModel(**result)
if page_object.type != 'status':
if not await cls.check_role_name_unique_services(query_db, page_object):
raise ServiceException(message=f'修改角色{page_object.role_name}失败,角色名称已存在')
elif not await cls.check_role_key_unique_services(query_db, page_object):
raise ServiceException(message=f'修改角色{page_object.role_name}失败,角色权限已存在')
try:
RoleDao.edit_role_dao(query_db, edit_role)
await RoleDao.edit_role_dao(query_db, edit_role)
if page_object.type != 'status':
RoleDao.delete_role_menu_dao(query_db, RoleMenuModel(roleId=page_object.role_id))
await RoleDao.delete_role_menu_dao(query_db, RoleMenuModel(roleId=page_object.role_id))
if page_object.menu_ids:
for menu in page_object.menu_ids:
RoleDao.add_role_menu_dao(query_db, RoleMenuModel(roleId=page_object.role_id, menuId=menu))
query_db.commit()
result = dict(is_success=True, message='更新成功')
await RoleDao.add_role_menu_dao(
query_db, RoleMenuModel(roleId=page_object.role_id, menuId=menu)
)
await query_db.commit()
return CrudResponseModel(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='角色不存在')
return CrudResponseModel(**result)
raise ServiceException(message='角色不存在')
@classmethod
def role_datascope_services(cls, query_db: Session, page_object: AddRoleModel):
async def role_datascope_services(cls, query_db: AsyncSession, page_object: AddRoleModel):
"""
分配角色数据权限service
:param query_db: orm对象
:param page_object: 角色数据权限对象
:return: 分配角色数据权限结果
"""
edit_role = page_object.model_dump(exclude_unset=True)
del edit_role['dept_ids']
role_info = cls.role_detail_services(query_db, edit_role.get('role_id'))
if role_info:
if role_info.role_name != page_object.role_name:
role_name = RoleDao.get_role_by_info(query_db, RoleModel(roleName=page_object.role_name))
if role_name:
result = dict(is_success=False, message='角色名称已存在')
return CrudResponseModel(**result)
elif role_info.role_key != page_object.role_key:
role_key = RoleDao.get_role_by_info(query_db, RoleModel(roleKey=page_object.role_key))
if role_key:
result = dict(is_success=False, message='权限字符已存在')
return CrudResponseModel(**result)
edit_role = page_object.model_dump(exclude_unset=True, exclude={'admin', 'dept_ids'})
role_info = await cls.role_detail_services(query_db, page_object.role_id)
if role_info.role_id:
try:
RoleDao.edit_role_dao(query_db, edit_role)
RoleDao.delete_role_dept_dao(query_db, RoleDeptModel(roleId=page_object.role_id))
await RoleDao.edit_role_dao(query_db, edit_role)
await RoleDao.delete_role_dept_dao(query_db, RoleDeptModel(roleId=page_object.role_id))
if page_object.dept_ids and page_object.data_scope == '2':
for dept in page_object.dept_ids:
RoleDao.add_role_dept_dao(query_db, RoleDeptModel(roleId=page_object.role_id, deptId=dept))
query_db.commit()
result = dict(is_success=True, message='分配成功')
await RoleDao.add_role_dept_dao(
query_db, RoleDeptModel(roleId=page_object.role_id, deptId=dept)
)
await query_db.commit()
return CrudResponseModel(is_success=True, message='分配成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='角色不存在')
return CrudResponseModel(**result)
raise ServiceException(message='角色不存在')
@classmethod
def delete_role_services(cls, query_db: Session, page_object: DeleteRoleModel):
async def delete_role_services(cls, query_db: AsyncSession, page_object: DeleteRoleModel):
"""
删除角色信息service
:param query_db: orm对象
:param page_object: 删除角色对象
:return: 删除角色校验结果
"""
if page_object.role_ids.split(','):
if page_object.role_ids:
role_id_list = page_object.role_ids.split(',')
try:
for role_id in role_id_list:
role_id_dict = dict(roleId=role_id, updateBy=page_object.update_by, updateTime=page_object.update_time)
RoleDao.delete_role_menu_dao(query_db, RoleMenuModel(**role_id_dict))
RoleDao.delete_role_dao(query_db, RoleModel(**role_id_dict))
query_db.commit()
result = dict(is_success=True, message='删除成功')
role = await cls.role_detail_services(query_db, int(role_id))
if (await RoleDao.count_user_role_dao(query_db, int(role_id))) > 0:
raise ServiceException(message=f'角色{role.role_name}已分配,不能删除')
role_id_dict = dict(
roleId=role_id, updateBy=page_object.update_by, updateTime=page_object.update_time
)
await RoleDao.delete_role_menu_dao(query_db, RoleMenuModel(**role_id_dict))
await RoleDao.delete_role_dept_dao(query_db, RoleDeptModel(**role_id_dict))
await RoleDao.delete_role_dao(query_db, RoleModel(**role_id_dict))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入角色id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入角色id为空')
@classmethod
def role_detail_services(cls, query_db: Session, role_id: int):
async def role_detail_services(cls, query_db: AsyncSession, role_id: int):
"""
获取角色详细信息service
:param query_db: orm对象
:param role_id: 角色id
:return: 角色id对应的信息
"""
role = RoleDao.get_role_detail_by_id(query_db, role_id=role_id)
result = RoleModel(**CamelCaseUtil.transform_result(role))
role = await RoleDao.get_role_detail_by_id(query_db, role_id=role_id)
if role:
result = RoleModel(**CamelCaseUtil.transform_result(role))
else:
result = RoleModel(**dict())
return result
@staticmethod
def export_role_list_services(role_list: List):
async def export_role_list_services(role_list: List):
"""
导出角色列表信息service
:param role_list: 角色信息列表
:return: 角色列表信息对象
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"roleId": "角色编号",
"roleName": "角色名称",
"roleKey": "权限字符",
"roleSort": "显示顺序",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
'roleId': '角色编号',
'roleName': '角色名称',
'roleKey': '权限字符',
'roleSort': '显示顺序',
'status': '状态',
'createBy': '创建者',
'createTime': '创建时间',
'updateBy': '更新者',
'updateTime': '更新时间',
'remark': '备注',
}
data = role_list
@@ -226,44 +302,58 @@ class RoleService:
item['status'] = '正常'
else:
item['status'] = '停用'
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
@classmethod
def get_role_user_allocated_list_services(cls, query_db: Session, page_object: UserRolePageQueryModel, is_page: bool = False):
async def get_role_user_allocated_list_services(
cls, query_db: AsyncSession, page_object: UserRolePageQueryModel, data_scope_sql: str, is_page: bool = False
):
"""
根据角色id获取已分配用户列表
:param query_db: orm对象
:param page_object: 用户关联角色对象
:param data_scope_sql: 数据权限对应的查询sql语句
:param is_page: 是否开启分页
:return: 已分配用户列表
"""
query_user_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object, is_page)
query_user_list = await UserDao.get_user_role_allocated_list_by_role_id(
query_db, page_object, data_scope_sql, is_page
)
allocated_list = PageResponseModel(
**{
**query_user_list.model_dump(by_alias=True),
'rows': [UserInfoModel(**row) for row in query_user_list.rows]
'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: UserRolePageQueryModel, is_page: bool = False):
async def get_role_user_unallocated_list_services(
cls, query_db: AsyncSession, page_object: UserRolePageQueryModel, data_scope_sql: str, is_page: bool = False
):
"""
根据角色id获取未分配用户列表
:param query_db: orm对象
:param page_object: 用户关联角色对象
:param data_scope_sql: 数据权限对应的查询sql语句
:param is_page: 是否开启分页
:return: 未分配用户列表
"""
query_user_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object, is_page)
query_user_list = await UserDao.get_user_role_unallocated_list_by_role_id(
query_db, page_object, data_scope_sql, is_page
)
unallocated_list = PageResponseModel(
**{
**query_user_list.model_dump(by_alias=True),
'rows': [UserInfoModel(**row) for row in query_user_list.rows]
'rows': [UserInfoModel(**row) for row in query_user_list.rows],
}
)

View File

@@ -1,10 +1,10 @@
import psutil
from utils.common_util import bytes2human
import platform
import socket
import os
import platform
import psutil
import socket
import time
from module_admin.entity.vo.server_vo import *
from module_admin.entity.vo.server_vo import CpuInfo, MemoryInfo, PyInfo, ServerMonitorModel, SysFiles, SysInfo
from utils.common_util import bytes2human
class ServerService:
@@ -13,7 +13,7 @@ class ServerService:
"""
@staticmethod
def get_server_monitor_info():
async def get_server_monitor_info():
# CPU信息
# 获取CPU总核心数
cpu_num = psutil.cpu_count(logical=True)
@@ -40,7 +40,9 @@ class ServerService:
computer_name = platform.node()
os_arch = platform.machine()
user_dir = os.path.abspath(os.getcwd())
sys = SysInfo(computerIp=computer_ip, computerName=computer_name, osArch=os_arch, osName=os_name, userDir=user_dir)
sys = SysInfo(
computerIp=computer_ip, computerName=computer_name, osArch=os_arch, osName=os_name, userDir=user_dir
)
# python解释器信息
current_pid = os.getpid()
@@ -49,14 +51,14 @@ class ServerService:
python_version = platform.python_version()
python_home = current_process.exe()
start_time_stamp = current_process.create_time()
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start_time_stamp))
start_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(start_time_stamp))
current_time_stamp = time.time()
difference = current_time_stamp - start_time_stamp
# 将时间差转换为天、小时和分钟数
days = int(difference // (24 * 60 * 60)) # 每天的秒数
hours = int((difference % (24 * 60 * 60)) // (60 * 60)) # 每小时的秒数
minutes = int((difference % (60 * 60)) // 60) # 每分钟的秒数
run_time = f"{days}{hours}小时{minutes}分钟"
run_time = f'{days}{hours}小时{minutes}分钟'
# 获取当前Python程序的pid
pid = os.getpid()
# 获取该进程的内存信息
@@ -70,7 +72,7 @@ class ServerService:
total=bytes2human(memory_info.available),
used=bytes2human(current_process_memory_info.rss),
free=bytes2human(memory_info.available - current_process_memory_info.rss),
usage=round((current_process_memory_info.rss / memory_info.available) * 100, 2)
usage=round((current_process_memory_info.rss / memory_info.available) * 100, 2),
)
# 磁盘信息
@@ -81,11 +83,11 @@ class ServerService:
disk_data = SysFiles(
dirName=i.device,
sysTypeName=i.fstype,
typeName="本地固定磁盘(" + i.mountpoint.replace('\\', '') + "",
typeName='本地固定磁盘(' + i.mountpoint.replace('\\', '') + '',
total=bytes2human(o.total),
used=bytes2human(o.used),
free=bytes2human(o.free),
usage=f'{psutil.disk_usage(i.device).percent}%'
usage=f'{psutil.disk_usage(i.device).percent}%',
)
sys_files.append(disk_data)

View File

@@ -1,11 +1,39 @@
from fastapi import UploadFile
from module_admin.service.role_service import RoleService
from module_admin.service.post_service import PostService, PostPageQueryModel
import io
import pandas as pd
from datetime import datetime
from fastapi import Request, UploadFile
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.dao.user_dao import *
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:
@@ -14,21 +42,24 @@ class UserService:
"""
@classmethod
def get_user_list_services(cls, query_db: Session, 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对象
: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, is_page)
query_result = await 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]
'rows': [{**row[0], 'dept': row[1]} for row in query_result.rows],
}
)
else:
@@ -39,39 +70,116 @@ class UserService:
return user_list_result
@classmethod
def add_user_services(cls, query_db: Session, page_object: AddUserModel):
async def check_user_allowed_services(cls, check_user: UserModel):
"""
校验用户是否允许操作service
:param check_user: 用户信息
:return: 校验结果
"""
if check_user.admin:
raise ServiceException(message='不允许操作超级管理员用户')
else:
return CrudResponseModel(is_success=True, message='校验通过')
@classmethod
async def check_user_data_scope_services(cls, query_db: AsyncSession, user_id: int, data_scope_sql: str):
"""
校验用户数据权限service
:param query_db: orm对象
:param user_id: 用户id
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 校验结果
"""
users = await UserDao.get_user_list(query_db, UserPageQueryModel(userId=user_id), data_scope_sql, is_page=False)
if users:
return CrudResponseModel(is_success=True, message='校验通过')
else:
raise ServiceException(message='没有权限访问用户数据')
@classmethod
async def check_user_name_unique_services(cls, query_db: AsyncSession, page_object: UserModel):
"""
校验用户名是否唯一service
:param query_db: orm对象
:param page_object: 用户对象
:return: 校验结果
"""
user_id = -1 if page_object.user_id is None else page_object.user_id
user = await UserDao.get_user_by_info(query_db, UserModel(userName=page_object.user_name))
if user and user.user_id != user_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def check_phonenumber_unique_services(cls, query_db: AsyncSession, page_object: UserModel):
"""
校验用户手机号是否唯一service
:param query_db: orm对象
:param page_object: 用户对象
:return: 校验结果
"""
user_id = -1 if page_object.user_id is None else page_object.user_id
user = await UserDao.get_user_by_info(query_db, UserModel(phonenumber=page_object.phonenumber))
if user and user.user_id != user_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def check_email_unique_services(cls, query_db: AsyncSession, page_object: UserModel):
"""
校验用户邮箱是否唯一service
:param query_db: orm对象
:param page_object: 用户对象
:return: 校验结果
"""
user_id = -1 if page_object.user_id is None else page_object.user_id
user = await UserDao.get_user_by_info(query_db, UserModel(email=page_object.email))
if user and user.user_id != user_id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE
@classmethod
async def add_user_services(cls, query_db: AsyncSession, page_object: AddUserModel):
"""
新增用户信息service
:param query_db: orm对象
:param page_object: 新增用户对象
:return: 新增用户校验结果
"""
add_user = UserModel(**page_object.model_dump(by_alias=True))
user = UserDao.get_user_by_info(query_db, UserModel(userName=page_object.user_name))
if user:
result = dict(is_success=False, message='用户名已存在')
if not await cls.check_user_name_unique_services(query_db, page_object):
raise ServiceException(message=f'新增用户{page_object.user_name}失败,登录账号已存在')
elif page_object.phonenumber and not await cls.check_phonenumber_unique_services(query_db, page_object):
raise ServiceException(message=f'新增用户{page_object.user_name}失败,手机号码已存在')
elif page_object.email and not await cls.check_email_unique_services(query_db, page_object):
raise ServiceException(message=f'新增用户{page_object.user_name}失败,邮箱账号已存在')
else:
try:
add_result = UserDao.add_user_dao(query_db, add_user)
add_result = await UserDao.add_user_dao(query_db, add_user)
user_id = add_result.user_id
if page_object.role_ids:
for role in page_object.role_ids:
UserDao.add_user_role_dao(query_db, UserRoleModel(userId=user_id, roleId=role))
await UserDao.add_user_role_dao(query_db, UserRoleModel(userId=user_id, roleId=role))
if page_object.post_ids:
for post in page_object.post_ids:
UserDao.add_user_post_dao(query_db, UserPostModel(userId=user_id, postId=post))
query_db.commit()
result = dict(is_success=True, message='新增成功')
await UserDao.add_user_post_dao(query_db, UserPostModel(userId=user_id, postId=post))
await query_db.commit()
return CrudResponseModel(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_user_services(cls, query_db: Session, page_object: EditUserModel):
async def edit_user_services(cls, query_db: AsyncSession, page_object: EditUserModel):
"""
编辑用户信息service
:param query_db: orm对象
:param page_object: 编辑用户对象
:return: 编辑用户校验结果
@@ -83,71 +191,78 @@ class UserService:
del edit_user['role']
if page_object.type == 'status' or page_object.type == 'avatar' or page_object.type == 'pwd':
del edit_user['type']
user_info = cls.user_detail_services(query_db, edit_user.get('user_id'))
if user_info:
if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type == 'pwd' and user_info.data.user_name != page_object.user_name:
user = UserDao.get_user_by_info(query_db, UserModel(userName=page_object.user_name))
if user:
result = dict(is_success=False, message='用户名已存在')
return CrudResponseModel(**result)
user_info = await cls.user_detail_services(query_db, edit_user.get('user_id'))
if user_info.data and user_info.data.user_id:
if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type != 'pwd':
if not await cls.check_user_name_unique_services(query_db, page_object):
raise ServiceException(message=f'修改用户{page_object.user_name}失败,登录账号已存在')
elif page_object.phonenumber and not await cls.check_phonenumber_unique_services(query_db, page_object):
raise ServiceException(message=f'修改用户{page_object.user_name}失败,手机号码已存在')
elif page_object.email and not await cls.check_email_unique_services(query_db, page_object):
raise ServiceException(message=f'修改用户{page_object.user_name}失败,邮箱账号已存在')
try:
UserDao.edit_user_dao(query_db, edit_user)
if page_object.type != 'status' and page_object.type != 'avatar':
UserDao.delete_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
UserDao.delete_user_post_dao(query_db, UserPostModel(userId=page_object.user_id))
await UserDao.edit_user_dao(query_db, edit_user)
if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type != 'pwd':
await UserDao.delete_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
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:
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:
UserDao.add_user_post_dao(query_db, UserPostModel(userId=page_object.user_id, postId=post))
query_db.commit()
result = dict(is_success=True, message='更新成功')
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:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='用户不存在')
return CrudResponseModel(**result)
raise ServiceException(message='用户不存在')
@classmethod
def delete_user_services(cls, query_db: Session, page_object: DeleteUserModel):
async def delete_user_services(cls, query_db: AsyncSession, page_object: DeleteUserModel):
"""
删除用户信息service
:param query_db: orm对象
:param page_object: 删除用户对象
:return: 删除用户校验结果
"""
if page_object.user_ids.split(','):
if page_object.user_ids:
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)
UserDao.delete_user_role_dao(query_db, UserRoleModel(**user_id_dict))
UserDao.delete_user_post_dao(query_db, UserPostModel(**user_id_dict))
UserDao.delete_user_dao(query_db, UserModel(**user_id_dict))
query_db.commit()
result = dict(is_success=True, message='删除成功')
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))
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入用户id为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入用户id为空')
@classmethod
def user_detail_services(cls, query_db: Session, user_id: Union[int, str]):
async def user_detail_services(cls, query_db: AsyncSession, user_id: Union[int, str]):
"""
获取用户详细信息service
:param query_db: orm对象
:param user_id: 用户id
:return: 用户id对应的信息
"""
posts = PostService.get_post_list_services(query_db, PostPageQueryModel(**{}), is_page=False)
roles = RoleService.get_role_select_option_services(query_db)
posts = await PostService.get_post_list_services(query_db, PostPageQueryModel(**{}), is_page=False)
roles = await RoleService.get_role_select_option_services(query_db)
if user_id != '':
query_user = UserDao.get_user_detail_by_id(query_db, user_id=user_id)
query_user = await UserDao.get_user_detail_by_id(query_db, user_id=user_id)
post_ids = ','.join([str(row.post_id) for row in query_user.get('user_post_info')])
post_ids_list = [row.post_id for row in query_user.get('user_post_info')]
role_ids = ','.join([str(row.role_id) for row in query_user.get('user_role_info')])
@@ -159,28 +274,26 @@ 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
def user_profile_services(cls, query_db: Session, user_id: int):
async def user_profile_services(cls, query_db: AsyncSession, user_id: int):
"""
获取用户详细信息service
获取用户个人详细信息service
:param query_db: orm对象
:param user_id: 用户id
:return: 用户id对应的信息
"""
query_user = UserDao.get_user_detail_by_id(query_db, user_id=user_id)
query_user = await UserDao.get_user_detail_by_id(query_db, user_id=user_id)
post_ids = ','.join([str(row.post_id) for row in query_user.get('user_post_info')])
post_group = ','.join([row.post_name for row in query_user.get('user_post_info')])
role_ids = ','.join([str(row.role_id) for row in query_user.get('user_role_info')])
@@ -192,59 +305,73 @@ 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
def reset_user_services(cls, query_db: Session, page_object: ResetUserModel):
async def reset_user_services(cls, query_db: AsyncSession, page_object: ResetUserModel):
"""
重置用户密码service
:param query_db: orm对象
:param page_object: 重置用户对象
:return: 重置用户校验结果
"""
reset_user = page_object.model_dump(exclude_unset=True)
reset_user = page_object.model_dump(exclude_unset=True, exclude={'admin'})
if page_object.old_password:
user = UserDao.get_user_detail_by_id(query_db, user_id=page_object.user_id).get('user_basic_info')
user = (await UserDao.get_user_detail_by_id(query_db, user_id=page_object.user_id)).get('user_basic_info')
if not PwdUtil.verify_password(page_object.old_password, user.password):
result = dict(is_success=False, message='旧密码不正确')
return CrudResponseModel(**result)
raise ServiceException(message='修改密码失败,旧密码错误')
elif PwdUtil.verify_password(page_object.password, user.password):
raise ServiceException(message='新密码不能与旧密码相同')
else:
del reset_user['old_password']
if page_object.sms_code and page_object.session_id:
del reset_user['sms_code']
del reset_user['session_id']
try:
UserDao.edit_user_dao(query_db, reset_user)
query_db.commit()
result = dict(is_success=True, message='重置成功')
reset_user['password'] = PwdUtil.get_password_hash(page_object.password)
await UserDao.edit_user_dao(query_db, reset_user)
await query_db.commit()
return CrudResponseModel(is_success=True, message='重置成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def batch_import_user_services(cls, query_db: Session, file: UploadFile, update_support: bool, current_user: CurrentUserModel):
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对象
:param query_db: orm对象
:param file: 用户导入文件对象
:param update_support: 用户存在时是否更新
:param current_user: 当前用户对象
:param user_data_scope_sql: 用户数据权限sql
:param dept_data_scope_sql: 部门数据权限sql
: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))
@@ -268,19 +395,25 @@ class UserService:
add_user = UserModel(
deptId=row['dept_id'],
userName=row['user_name'],
password=PwdUtil.get_password_hash('123456'),
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']),
sex=row['sex'],
status=row['status'],
createBy=current_user.user.user_name,
updateBy=current_user.user.user_name
createTime=datetime.now(),
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
)
user_info = UserDao.get_user_by_info(query_db, UserModel(userName=row['user_name']))
user_info = await UserDao.get_user_by_info(query_db, UserModel(userName=row['user_name']))
if user_info:
if update_support:
edit_user = UserModel(
edit_user_model = UserModel(
userId=user_info.user_id,
deptId=row['dept_id'],
userName=row['user_name'],
@@ -289,56 +422,74 @@ class UserService:
phonenumber=str(row['phonenumber']),
sex=row['sex'],
status=row['status'],
updateBy=current_user.user.user_name
).model_dump(exclude_unset=True)
UserDao.edit_user_dao(query_db, edit_user)
updateBy=current_user.user.user_name,
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
)
edit_user = edit_user_model.model_dump(exclude_unset=True)
await UserDao.edit_user_dao(query_db, edit_user)
else:
add_error_result.append(f"{count}.用户账号{row['user_name']}已存在")
else:
UserDao.add_user_dao(query_db, add_user)
query_db.commit()
result = dict(is_success=True, message='\n'.join(add_error_result))
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 UserDao.add_user_dao(query_db, add_user)
await query_db.commit()
return CrudResponseModel(is_success=True, message='\n'.join(add_error_result))
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
return CrudResponseModel(**result)
@staticmethod
def get_user_import_template_services():
async def get_user_import_template_services():
"""
获取用户导入模板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
@staticmethod
def export_user_list_services(user_list: List):
async def export_user_list_services(user_list: List):
"""
导出用户信息service
:param user_list: 用户信息列表
:return: 用户信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
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
@@ -354,20 +505,23 @@ 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
@classmethod
def get_user_role_allocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel):
async def get_user_role_allocated_list_services(cls, query_db: AsyncSession, page_object: UserRoleQueryModel):
"""
根据用户id获取已分配角色列表
:param query_db: orm对象
:param page_object: 用户关联角色对象
:return: 已分配角色列表
"""
query_user = UserDao.get_user_detail_by_id(query_db, page_object.user_id)
query_user = await UserDao.get_user_detail_by_id(query_db, page_object.user_id)
post_ids = ','.join([str(row.post_id) for row in query_user.get('user_post_info')])
role_ids = ','.join([str(row.role_id) for row in query_user.get('user_role_info')])
user = UserInfoModel(
@@ -375,24 +529,24 @@ 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 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
@classmethod
def add_user_role_services(cls, query_db: Session, page_object: CrudUserRoleModel):
async def add_user_role_services(cls, query_db: AsyncSession, page_object: CrudUserRoleModel):
"""
新增用户关联角色信息service
:param query_db: orm对象
:param page_object: 新增用户关联角色对象
:return: 新增用户关联角色校验结果
@@ -400,48 +554,48 @@ class UserService:
if page_object.user_id and page_object.role_ids:
role_id_list = page_object.role_ids.split(',')
try:
await UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
for role_id in role_id_list:
user_role = cls.detail_user_role_services(query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id))
if user_role:
continue
else:
UserDao.add_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id))
query_db.commit()
result = dict(is_success=True, message='分配成功')
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:
query_db.rollback()
await query_db.rollback()
raise e
elif page_object.user_id and not page_object.role_ids:
try:
UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
query_db.commit()
result = dict(is_success=True, message='分配成功')
await UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
await query_db.commit()
return CrudResponseModel(is_success=True, message='分配成功')
except Exception as e:
query_db.rollback()
await query_db.rollback()
raise e
elif page_object.user_ids and page_object.role_id:
user_id_list = page_object.user_ids.split(',')
try:
for user_id in user_id_list:
user_role = 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:
UserDao.add_user_role_dao(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id))
query_db.commit()
result = dict(is_success=True, message='新增成功')
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:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='不满足新增条件')
return CrudResponseModel(**result)
raise ServiceException(message='不满足新增条件')
@classmethod
def delete_user_role_services(cls, query_db: Session, page_object: CrudUserRoleModel):
async def delete_user_role_services(cls, query_db: AsyncSession, page_object: CrudUserRoleModel):
"""
删除用户关联角色信息service
:param query_db: orm对象
:param page_object: 删除用户关联角色对象
:return: 删除用户关联角色校验结果
@@ -449,37 +603,40 @@ 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:
UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=page_object.role_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
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:
query_db.rollback()
await query_db.rollback()
raise e
elif page_object.user_ids and page_object.role_id:
user_id_list = page_object.user_ids.split(',')
try:
for user_id in user_id_list:
UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
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:
query_db.rollback()
await query_db.rollback()
raise e
else:
result = dict(is_success=False, message='不满足删除条件')
raise ServiceException(message='不满足删除条件')
else:
result = dict(is_success=False, message='传入用户角色关联信息为空')
return CrudResponseModel(**result)
raise ServiceException(message='传入用户角色关联信息为空')
@classmethod
def detail_user_role_services(cls, query_db: Session, page_object: UserRoleModel):
async def detail_user_role_services(cls, query_db: AsyncSession, page_object: UserRoleModel):
"""
获取用户关联角色详细信息service
:param query_db: orm对象
:param page_object: 用户关联角色对象
:return: 用户关联角色详细信息
"""
user_role = UserDao.get_user_role_detail(query_db, page_object)
user_role = await UserDao.get_user_role_detail(query_db, page_object)
return user_role

View File

@@ -1 +1 @@
from . import scheduler_test
from . import scheduler_test # noqa: F401

View File

@@ -2,6 +2,18 @@ from datetime import datetime
def job(*args, **kwargs):
"""
定时任务执行同步函数示例
"""
print(args)
print(kwargs)
print(f"{datetime.now()}执行了")
print(f'{datetime.now()}同步函数执行了')
async def async_job(*args, **kwargs):
"""
定时任务执行异步函数示例
"""
print(args)
print(kwargs)
print(f'{datetime.now()}异步函数执行了')

View File

@@ -0,0 +1,17 @@
APScheduler==3.10.4
asyncpg==0.30.0
DateTime==5.5
fastapi[all]==0.115.0
loguru==0.7.2
openpyxl==3.1.5
pandas==2.2.2
passlib[bcrypt]==1.7.4
Pillow==10.4.0
psutil==6.0.0
pydantic-validation-decorator==0.1.4
PyJWT[crypto]==2.8.0
psycopg2==2.9.10
redis==5.0.7
requests==2.32.3
SQLAlchemy[asyncio]==2.0.31
user-agents==2.2.0

View File

@@ -1,15 +1,17 @@
APScheduler==3.10.4
DateTime==5.4
fastapi[all]==0.109.1
asyncmy==0.2.9
DateTime==5.5
fastapi[all]==0.115.0
loguru==0.7.2
openpyxl==3.1.2
pandas==2.1.4
openpyxl==3.1.5
pandas==2.2.2
passlib[bcrypt]==1.7.4
Pillow==10.2.0
psutil==5.9.7
PyMySQL==1.1.0
python-jose[cryptography]==3.3.0
redis==5.0.1
requests==2.31.0
SQLAlchemy==2.0.25
Pillow==10.4.0
psutil==6.0.0
pydantic-validation-decorator==0.1.4
PyJWT[crypto]==2.8.0
PyMySQL==1.1.1
redis==5.0.7
requests==2.32.3
SQLAlchemy[asyncio]==2.0.31
user-agents==2.2.0

View File

@@ -0,0 +1,4 @@
line-length = 120
[format]
quote-style = "single"

View File

@@ -1,43 +1,43 @@
from fastapi import FastAPI
from contextlib import asynccontextmanager
from sub_applications.handle import handle_sub_applications
from middlewares.handle import handle_middleware
from exceptions.handle import handle_exception
from module_admin.controller.login_controller import loginController
from module_admin.controller.captcha_controller import captchaController
from module_admin.controller.user_controller import userController
from module_admin.controller.menu_controller import menuController
from module_admin.controller.dept_controller import deptController
from module_admin.controller.role_controller import roleController
from module_admin.controller.post_controler import postController
from module_admin.controller.dict_controller import dictController
from module_admin.controller.config_controller import configController
from module_admin.controller.notice_controller import noticeController
from module_admin.controller.log_controller import logController
from module_admin.controller.online_controller import onlineController
from module_admin.controller.job_controller import jobController
from module_admin.controller.server_controller import serverController
from module_admin.controller.cache_controller import cacheController
from module_admin.controller.common_controller import commonController
from fastapi import FastAPI
from config.env import AppConfig
from config.get_redis import RedisUtil
from config.get_db import init_create_table
from config.get_redis import RedisUtil
from config.get_scheduler import SchedulerUtil
from utils.log_util import logger
from exceptions.handle import handle_exception
from middlewares.handle import handle_middleware
from module_admin.controller.cache_controller import cacheController
from module_admin.controller.captcha_controller import captchaController
from module_admin.controller.common_controller import commonController
from module_admin.controller.config_controller import configController
from module_admin.controller.dept_controller import deptController
from module_admin.controller.dict_controller import dictController
from module_admin.controller.log_controller import logController
from module_admin.controller.login_controller import loginController
from module_admin.controller.job_controller import jobController
from module_admin.controller.menu_controller import menuController
from module_admin.controller.notice_controller import noticeController
from module_admin.controller.online_controller import onlineController
from module_admin.controller.post_controler import postController
from module_admin.controller.role_controller import roleController
from module_admin.controller.server_controller import serverController
from module_admin.controller.user_controller import userController
from sub_applications.handle import handle_sub_applications
from utils.common_util import worship
from utils.log_util import logger
# 生命周期事件
@asynccontextmanager
async def lifespan(app: FastAPI):
logger.info(f"{AppConfig.app_name}开始启动")
logger.info(f'{AppConfig.app_name}开始启动')
worship()
await init_create_table()
app.state.redis = await RedisUtil.create_redis_pool()
await RedisUtil.init_sys_dict(app.state.redis)
await RedisUtil.init_sys_config(app.state.redis)
await SchedulerUtil.init_system_scheduler()
logger.info(f"{AppConfig.app_name}启动成功")
logger.info(f'{AppConfig.app_name}启动成功')
yield
await RedisUtil.close_redis_pool(app)
await SchedulerUtil.close_system_scheduler()
@@ -48,7 +48,7 @@ app = FastAPI(
title=AppConfig.app_name,
description=f'{AppConfig.app_name}接口文档',
version=AppConfig.app_version,
lifespan=lifespan
lifespan=lifespan,
)
# 挂载子应用
@@ -76,7 +76,7 @@ controller_list = [
{'router': jobController, 'tags': ['系统监控-定时任务']},
{'router': serverController, 'tags': ['系统监控-菜单管理']},
{'router': cacheController, 'tags': ['系统监控-缓存监控']},
{'router': commonController, 'tags': ['通用模块']}
{'router': commonController, 'tags': ['通用模块']},
]
for controller in controller_list:

View File

@@ -0,0 +1,977 @@
-- ----------------------------
-- 1、部门表
-- ----------------------------
drop table if exists sys_dept;
create table sys_dept (
dept_id bigserial,
parent_id bigint default 0,
ancestors varchar(50) default '',
dept_name varchar(30) default '',
order_num int4 default 0,
leader varchar(20) default null,
phone varchar(11) default null,
email varchar(50) default null,
status char(1) default '0',
del_flag char(1) default '0',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
primary key (dept_id)
);
alter sequence sys_dept_dept_id_seq restart 200;
comment on column sys_dept.dept_id is '部门id';
comment on column sys_dept.parent_id is '父部门id';
comment on column sys_dept.ancestors is '祖级列表';
comment on column sys_dept.dept_name is '部门名称';
comment on column sys_dept.order_num is '显示顺序';
comment on column sys_dept.leader is '负责人';
comment on column sys_dept.phone is '联系电话';
comment on column sys_dept.email is '邮箱';
comment on column sys_dept.status is '部门状态0正常 1停用';
comment on column sys_dept.del_flag is '删除标志0代表存在 2代表删除';
comment on column sys_dept.create_by is '创建者';
comment on column sys_dept.create_time is '创建时间';
comment on column sys_dept.update_by is '更新者';
comment on column sys_dept.update_time is '更新时间';
comment on table sys_dept is '部门表';
-- ----------------------------
-- 初始化-部门表数据
-- ----------------------------
insert into sys_dept values(100, 0, '0', '集团总公司', 0, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(101, 100, '0,100', '深圳分公司', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', current_timestamp, '', null);
-- ----------------------------
-- 2、用户信息表
-- ----------------------------
drop table if exists sys_user;
create table sys_user (
user_id bigserial not null,
dept_id bigint default null,
user_name varchar(30) not null,
nick_name varchar(30) not null,
user_type varchar(2) default '00',
email varchar(50) default '',
phonenumber varchar(11) default '',
sex char(1) default '0',
avatar varchar(100) default '',
password varchar(100) default '',
status char(1) default '0',
del_flag char(1) default '0',
login_ip varchar(128) default '',
login_date timestamp(0),
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default null,
primary key (user_id)
);
alter sequence sys_user_user_id_seq restart 100;
comment on column sys_user.user_id is '用户ID';
comment on column sys_user.dept_id is '部门ID';
comment on column sys_user.user_name is '用户账号';
comment on column sys_user.nick_name is '用户昵称';
comment on column sys_user.user_type is '用户类型00系统用户';
comment on column sys_user.email is '用户邮箱';
comment on column sys_user.phonenumber is '手机号码';
comment on column sys_user.sex is '用户性别0男 1女 2未知';
comment on column sys_user.avatar is '头像地址';
comment on column sys_user.password is '密码';
comment on column sys_user.status is '帐号状态0正常 1停用';
comment on column sys_user.del_flag is '删除标志0代表存在 2代表删除';
comment on column sys_user.login_ip is '最后登录IP';
comment on column sys_user.login_date is '最后登录时间';
comment on column sys_user.create_by is '创建者';
comment on column sys_user.create_time is '创建时间';
comment on column sys_user.update_by is '更新者';
comment on column sys_user.update_time is '更新时间';
comment on column sys_user.remark is '备注';
comment on table sys_user is '用户信息表';
-- ----------------------------
-- 3、岗位信息表
-- ----------------------------
drop table if exists sys_post;
create table sys_post (
post_id bigserial not null,
post_code varchar(64) not null,
post_name varchar(50) not null,
post_sort int4 not null,
status char(1) not null,
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default null,
primary key (post_id)
);
alter sequence sys_post_post_id_seq restart 5;
comment on column sys_post.post_id is '岗位ID';
comment on column sys_post.post_code is '岗位编码';
comment on column sys_post.post_name is '岗位名称';
comment on column sys_post.post_sort is '显示顺序';
comment on column sys_post.status is '状态0正常 1停用';
comment on column sys_post.create_by is '创建者';
comment on column sys_post.create_time is '创建时间';
comment on column sys_post.update_by is '更新者';
comment on column sys_post.update_time is '更新时间';
comment on column sys_post.remark is '备注';
comment on table sys_post is '岗位信息表';
-- ----------------------------
-- 初始化-岗位信息表数据
-- ----------------------------
insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', current_timestamp, '', null, '');
insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', current_timestamp, '', null, '');
insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', current_timestamp, '', null, '');
insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', current_timestamp, '', null, '');
-- ----------------------------
-- 初始化-用户信息表数据
-- ----------------------------
insert into sys_user values(1, 103, 'admin', '超级管理员', '00', 'niangao@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', current_timestamp, 'admin', current_timestamp, '', null, '管理员');
insert into sys_user values(2, 105, 'niangao', '年糕', '00', 'niangao@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', current_timestamp, 'admin', current_timestamp, '', null, '测试员');
-- ----------------------------
-- 4、角色信息表
-- ----------------------------
drop table if exists sys_role;
create table sys_role (
role_id bigserial not null,
role_name varchar(30) not null,
role_key varchar(100) not null,
role_sort int4 not null,
data_scope char(1) default '1',
menu_check_strictly smallint default 1,
dept_check_strictly smallint default 1,
status char(1) not null,
del_flag char(1) default '0',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default null,
primary key (role_id)
);
alter sequence sys_role_role_id_seq restart 3;
comment on column sys_role.role_id is '角色ID';
comment on column sys_role.role_name is '角色名称';
comment on column sys_role.role_key is '角色权限字符串';
comment on column sys_role.role_sort is '显示顺序';
comment on column sys_role.data_scope is '数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限';
comment on column sys_role.menu_check_strictly is '菜单树选择项是否关联显示';
comment on column sys_role.dept_check_strictly is '部门树选择项是否关联显示';
comment on column sys_role.status is '角色状态0正常 1停用';
comment on column sys_role.del_flag is '删除标志0代表存在 2代表删除';
comment on column sys_role.create_by is '创建者';
comment on column sys_role.create_time is '创建时间';
comment on column sys_role.update_by is '更新者';
comment on column sys_role.update_time is '更新时间';
comment on column sys_role.remark is '备注';
comment on table sys_role is '角色信息表';
-- ----------------------------
-- 初始化-角色信息表数据
-- ----------------------------
insert into sys_role values(1, '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', current_timestamp, '', null, '超级管理员');
insert into sys_role values(2, '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', current_timestamp, '', null, '普通角色');
-- ----------------------------
-- 5、菜单权限表
-- ----------------------------
drop table if exists sys_menu;
create table sys_menu (
menu_id bigserial not null,
menu_name varchar(50) not null,
parent_id bigint default 0,
order_num int4 default 0,
path varchar(200) default '',
component varchar(255) default null,
query varchar(255) default null,
route_name varchar(50) default '',
is_frame int4 default 1,
is_cache int4 default 0,
menu_type char(1) default '',
visible char(1) default '0',
status char(1) default '0',
perms varchar(100) default null,
icon varchar(100) default '#',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default '',
primary key (menu_id)
);
alter sequence sys_menu_menu_id_seq restart 2000;
comment on column sys_menu.menu_id is '菜单ID';
comment on column sys_menu.menu_name is '菜单名称';
comment on column sys_menu.parent_id is '父菜单ID';
comment on column sys_menu.order_num is '显示顺序';
comment on column sys_menu.path is '路由地址';
comment on column sys_menu.component is '组件路径';
comment on column sys_menu.query is '路由参数';
comment on column sys_menu.route_name is '路由名称';
comment on column sys_menu.is_frame is '是否为外链0是 1否';
comment on column sys_menu.is_cache is '是否缓存0缓存 1不缓存';
comment on column sys_menu.menu_type is '菜单类型M目录 C菜单 F按钮';
comment on column sys_menu.visible is '菜单状态0显示 1隐藏';
comment on column sys_menu.status is '菜单状态0正常 1停用';
comment on column sys_menu.perms is '权限标识';
comment on column sys_menu.icon is '菜单图标';
comment on column sys_menu.create_by is '创建者';
comment on column sys_menu.create_time is '创建时间';
comment on column sys_menu.update_by is '更新者';
comment on column sys_menu.update_time is '更新时间';
comment on column sys_menu.remark is '备注';
comment on table sys_menu is '菜单权限表';
-- ----------------------------
-- 初始化-菜单信息表数据
-- ----------------------------
-- 一级菜单
insert into sys_menu values(1, '系统管理', 0, '1', 'system', null, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', current_timestamp, '', null, '系统管理目录');
insert into sys_menu values(2, '系统监控', 0, '2', 'monitor', null, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', current_timestamp, '', null, '系统监控目录');
insert into sys_menu values(3, '系统工具', 0, '3', 'tool', null, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', current_timestamp, '', null, '系统工具目录');
insert into sys_menu values(4, '若依官网', 0, '4', 'http://ruoyi.vip', null, '', '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', current_timestamp, '', null, '若依官网地址');
-- 二级菜单
insert into sys_menu values(100, '用户管理', 1, '1', 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', current_timestamp, '', null, '用户管理菜单');
insert into sys_menu values(101, '角色管理', 1, '2', 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', current_timestamp, '', null, '角色管理菜单');
insert into sys_menu values(102, '菜单管理', 1, '3', 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', current_timestamp, '', null, '菜单管理菜单');
insert into sys_menu values(103, '部门管理', 1, '4', 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', current_timestamp, '', null, '部门管理菜单');
insert into sys_menu values(104, '岗位管理', 1, '5', 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', current_timestamp, '', null, '岗位管理菜单');
insert into sys_menu values(105, '字典管理', 1, '6', 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', current_timestamp, '', null, '字典管理菜单');
insert into sys_menu values(106, '参数设置', 1, '7', 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', current_timestamp, '', null, '参数设置菜单');
insert into sys_menu values(107, '通知公告', 1, '8', 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', current_timestamp, '', null, '通知公告菜单');
insert into sys_menu values(108, '日志管理', 1, '9', 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', current_timestamp, '', null, '日志管理菜单');
insert into sys_menu values(109, '在线用户', 2, '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', current_timestamp, '', null, '在线用户菜单');
insert into sys_menu values(110, '定时任务', 2, '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', current_timestamp, '', null, '定时任务菜单');
insert into sys_menu values(111, '数据监控', 2, '3', 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', current_timestamp, '', null, '数据监控菜单');
insert into sys_menu values(112, '服务监控', 2, '4', 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', current_timestamp, '', null, '服务监控菜单');
insert into sys_menu values(113, '缓存监控', 2, '5', 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', current_timestamp, '', null, '缓存监控菜单');
insert into sys_menu values(114, '缓存列表', 2, '6', 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', current_timestamp, '', null, '缓存列表菜单');
insert into sys_menu values(115, '表单构建', 3, '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', current_timestamp, '', null, '表单构建菜单');
insert into sys_menu values(116, '代码生成', 3, '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', current_timestamp, '', null, '代码生成菜单');
insert into sys_menu values(117, '系统接口', 3, '3', 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', current_timestamp, '', null, '系统接口菜单');
-- 三级菜单
insert into sys_menu values(500, '操作日志', 108, '1', 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', current_timestamp, '', null, '操作日志菜单');
insert into sys_menu values(501, '登录日志', 108, '2', 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', current_timestamp, '', null, '登录日志菜单');
-- 用户管理按钮
insert into sys_menu values(1000, '用户查询', 100, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1001, '用户新增', 100, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1002, '用户修改', 100, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1003, '用户删除', 100, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1004, '用户导出', 100, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1005, '用户导入', 100, '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1006, '重置密码', 100, '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', current_timestamp, '', null, '');
-- 角色管理按钮
insert into sys_menu values(1007, '角色查询', 101, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1008, '角色新增', 101, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1009, '角色修改', 101, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1010, '角色删除', 101, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1011, '角色导出', 101, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', current_timestamp, '', null, '');
-- 菜单管理按钮
insert into sys_menu values(1012, '菜单查询', 102, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1013, '菜单新增', 102, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1014, '菜单修改', 102, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1015, '菜单删除', 102, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', current_timestamp, '', null, '');
-- 部门管理按钮
insert into sys_menu values(1016, '部门查询', 103, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1017, '部门新增', 103, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1018, '部门修改', 103, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1019, '部门删除', 103, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', current_timestamp, '', null, '');
-- 岗位管理按钮
insert into sys_menu values(1020, '岗位查询', 104, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1021, '岗位新增', 104, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1022, '岗位修改', 104, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1023, '岗位删除', 104, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1024, '岗位导出', 104, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', current_timestamp, '', null, '');
-- 字典管理按钮
insert into sys_menu values(1025, '字典查询', 105, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1026, '字典新增', 105, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1027, '字典修改', 105, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1028, '字典删除', 105, '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1029, '字典导出', 105, '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', current_timestamp, '', null, '');
-- 参数设置按钮
insert into sys_menu values(1030, '参数查询', 106, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1031, '参数新增', 106, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1032, '参数修改', 106, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1033, '参数删除', 106, '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1034, '参数导出', 106, '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', current_timestamp, '', null, '');
-- 通知公告按钮
insert into sys_menu values(1035, '公告查询', 107, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1036, '公告新增', 107, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1037, '公告修改', 107, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1038, '公告删除', 107, '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', current_timestamp, '', null, '');
-- 操作日志按钮
insert into sys_menu values(1039, '操作查询', 500, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1040, '操作删除', 500, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1041, '日志导出', 500, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', current_timestamp, '', null, '');
-- 登录日志按钮
insert into sys_menu values(1042, '登录查询', 501, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1043, '登录删除', 501, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1044, '日志导出', 501, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1045, '账户解锁', 501, '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', current_timestamp, '', null, '');
-- 在线用户按钮
insert into sys_menu values(1046, '在线查询', 109, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1047, '批量强退', 109, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1048, '单条强退', 109, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', current_timestamp, '', null, '');
-- 定时任务按钮
insert into sys_menu values(1049, '任务查询', 110, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1050, '任务新增', 110, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1051, '任务修改', 110, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1052, '任务删除', 110, '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1053, '状态修改', 110, '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1054, '任务导出', 110, '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', current_timestamp, '', null, '');
-- 代码生成按钮
insert into sys_menu values(1055, '生成查询', 116, '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1056, '生成修改', 116, '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1057, '生成删除', 116, '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1058, '导入代码', 116, '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1059, '预览代码', 116, '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', current_timestamp, '', null, '');
insert into sys_menu values(1060, '生成代码', 116, '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', current_timestamp, '', null, '');
-- ----------------------------
-- 6、用户和角色关联表 用户N-1角色
-- ----------------------------
drop table if exists sys_user_role;
create table sys_user_role (
user_id bigint not null,
role_id bigint not null,
primary key (user_id, role_id)
);
comment on column sys_user_role.user_id is '用户ID';
comment on column sys_user_role.role_id is '角色ID';
comment on table sys_user_role is '用户和角色关联表';
-- ----------------------------
-- 初始化-用户和角色关联表数据
-- ----------------------------
insert into sys_user_role values (1, 1);
insert into sys_user_role values (2, 2);
-- ----------------------------
-- 7、角色和菜单关联表 角色1-N菜单
-- ----------------------------
drop table if exists sys_role_menu;
create table sys_role_menu (
role_id bigint not null,
menu_id bigint not null,
primary key (role_id, menu_id)
);
comment on column sys_role_menu.role_id is '角色ID';
comment on column sys_role_menu.menu_id is '菜单ID';
comment on table sys_role_menu is '角色和菜单关联表';
-- ----------------------------
-- 初始化-角色和菜单关联表数据
-- ----------------------------
insert into sys_role_menu values (2, 1);
insert into sys_role_menu values (2, 2);
insert into sys_role_menu values (2, 3);
insert into sys_role_menu values (2, 4);
insert into sys_role_menu values (2, 100);
insert into sys_role_menu values (2, 101);
insert into sys_role_menu values (2, 102);
insert into sys_role_menu values (2, 103);
insert into sys_role_menu values (2, 104);
insert into sys_role_menu values (2, 105);
insert into sys_role_menu values (2, 106);
insert into sys_role_menu values (2, 107);
insert into sys_role_menu values (2, 108);
insert into sys_role_menu values (2, 109);
insert into sys_role_menu values (2, 110);
insert into sys_role_menu values (2, 111);
insert into sys_role_menu values (2, 112);
insert into sys_role_menu values (2, 113);
insert into sys_role_menu values (2, 114);
insert into sys_role_menu values (2, 115);
insert into sys_role_menu values (2, 116);
insert into sys_role_menu values (2, 117);
insert into sys_role_menu values (2, 500);
insert into sys_role_menu values (2, 501);
insert into sys_role_menu values (2, 1000);
insert into sys_role_menu values (2, 1001);
insert into sys_role_menu values (2, 1002);
insert into sys_role_menu values (2, 1003);
insert into sys_role_menu values (2, 1004);
insert into sys_role_menu values (2, 1005);
insert into sys_role_menu values (2, 1006);
insert into sys_role_menu values (2, 1007);
insert into sys_role_menu values (2, 1008);
insert into sys_role_menu values (2, 1009);
insert into sys_role_menu values (2, 1010);
insert into sys_role_menu values (2, 1011);
insert into sys_role_menu values (2, 1012);
insert into sys_role_menu values (2, 1013);
insert into sys_role_menu values (2, 1014);
insert into sys_role_menu values (2, 1015);
insert into sys_role_menu values (2, 1016);
insert into sys_role_menu values (2, 1017);
insert into sys_role_menu values (2, 1018);
insert into sys_role_menu values (2, 1019);
insert into sys_role_menu values (2, 1020);
insert into sys_role_menu values (2, 1021);
insert into sys_role_menu values (2, 1022);
insert into sys_role_menu values (2, 1023);
insert into sys_role_menu values (2, 1024);
insert into sys_role_menu values (2, 1025);
insert into sys_role_menu values (2, 1026);
insert into sys_role_menu values (2, 1027);
insert into sys_role_menu values (2, 1028);
insert into sys_role_menu values (2, 1029);
insert into sys_role_menu values (2, 1030);
insert into sys_role_menu values (2, 1031);
insert into sys_role_menu values (2, 1032);
insert into sys_role_menu values (2, 1033);
insert into sys_role_menu values (2, 1034);
insert into sys_role_menu values (2, 1035);
insert into sys_role_menu values (2, 1036);
insert into sys_role_menu values (2, 1037);
insert into sys_role_menu values (2, 1038);
insert into sys_role_menu values (2, 1039);
insert into sys_role_menu values (2, 1040);
insert into sys_role_menu values (2, 1041);
insert into sys_role_menu values (2, 1042);
insert into sys_role_menu values (2, 1043);
insert into sys_role_menu values (2, 1044);
insert into sys_role_menu values (2, 1045);
insert into sys_role_menu values (2, 1046);
insert into sys_role_menu values (2, 1047);
insert into sys_role_menu values (2, 1048);
insert into sys_role_menu values (2, 1049);
insert into sys_role_menu values (2, 1050);
insert into sys_role_menu values (2, 1051);
insert into sys_role_menu values (2, 1052);
insert into sys_role_menu values (2, 1053);
insert into sys_role_menu values (2, 1054);
insert into sys_role_menu values (2, 1055);
insert into sys_role_menu values (2, 1056);
insert into sys_role_menu values (2, 1057);
insert into sys_role_menu values (2, 1058);
insert into sys_role_menu values (2, 1059);
insert into sys_role_menu values (2, 1060);
-- ----------------------------
-- 8、角色和部门关联表 角色1-N部门
-- ----------------------------
drop table if exists sys_role_dept;
create table sys_role_dept (
role_id bigint not null,
dept_id bigint not null,
primary key (role_id, dept_id)
);
comment on column sys_role_dept.role_id is '角色ID';
comment on column sys_role_dept.dept_id is '部门ID';
comment on table sys_role_dept is '角色和部门关联表';
-- ----------------------------
-- 初始化-角色和部门关联表数据
-- ----------------------------
insert into sys_role_dept values (2, 100);
insert into sys_role_dept values (2, 101);
insert into sys_role_dept values (2, 105);
-- ----------------------------
-- 9、用户与岗位关联表 用户1-N岗位
-- ----------------------------
drop table if exists sys_user_post;
create table sys_user_post (
user_id bigint not null,
post_id bigint not null,
primary key (user_id, post_id)
);
comment on column sys_user_post.user_id is '用户ID';
comment on column sys_user_post.post_id is '岗位ID';
comment on table sys_user_post is '用户与岗位关联表';
-- ----------------------------
-- 初始化-用户与岗位关联表数据
-- ----------------------------
insert into sys_user_post values (1, 1);
insert into sys_user_post values (2, 2);
-- ----------------------------
-- 10、操作日志记录
-- ----------------------------
drop table if exists sys_oper_log;
create table sys_oper_log (
oper_id bigserial not null,
title varchar(50) default '',
business_type int4 default 0,
method varchar(100) default '',
request_method varchar(10) default '',
operator_type int4 default 0,
oper_name varchar(50) default '',
dept_name varchar(50) default '',
oper_url varchar(255) default '',
oper_ip varchar(128) default '',
oper_location varchar(255) default '',
oper_param varchar(2000) default '',
json_result varchar(2000) default '',
status int4 default 0,
error_msg varchar(2000) default '',
oper_time timestamp(0),
cost_time int8 default 0,
primary key (oper_id)
);
alter sequence sys_oper_log_oper_id_seq restart 100;
create index idx_sys_oper_log_bt on sys_oper_log(business_type);
create index idx_sys_oper_log_s on sys_oper_log(status);
create index idx_sys_oper_log_ot on sys_oper_log(oper_time);
comment on column sys_oper_log.oper_id is '日志主键';
comment on column sys_oper_log.title is '模块标题';
comment on column sys_oper_log.business_type is '业务类型0其它 1新增 2修改 3删除';
comment on column sys_oper_log.method is '方法名称';
comment on column sys_oper_log.request_method is '请求方式';
comment on column sys_oper_log.operator_type is '操作类别0其它 1后台用户 2手机端用户';
comment on column sys_oper_log.oper_name is '操作人员';
comment on column sys_oper_log.dept_name is '部门名称';
comment on column sys_oper_log.oper_url is '请求URL';
comment on column sys_oper_log.oper_ip is '主机地址';
comment on column sys_oper_log.oper_location is '操作地点';
comment on column sys_oper_log.oper_param is '请求参数';
comment on column sys_oper_log.json_result is '返回参数';
comment on column sys_oper_log.status is '操作状态0正常 1异常';
comment on column sys_oper_log.error_msg is '错误消息';
comment on column sys_oper_log.oper_time is '操作时间';
comment on table sys_oper_log is '操作日志记录';
-- ----------------------------
-- 11、字典类型表
-- ----------------------------
drop table if exists sys_dict_type;
create table sys_dict_type (
dict_id bigserial not null,
dict_name varchar(100) default '',
dict_type varchar(100) unique default '',
status char(1) default '0',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default null,
primary key (dict_id)
);
alter sequence sys_dict_type_dict_id_seq restart 100;
comment on column sys_dict_type.dict_id is '字典主键';
comment on column sys_dict_type.dict_name is '字典名称';
comment on column sys_dict_type.dict_type is '字典类型';
comment on column sys_dict_type.status is '状态0正常 1停用';
comment on column sys_dict_type.create_by is '创建者';
comment on column sys_dict_type.create_time is '创建时间';
comment on column sys_dict_type.update_by is '更新者';
comment on column sys_dict_type.update_time is '更新时间';
comment on column sys_dict_type.remark is '备注';
comment on table sys_dict_type is '字典类型表';
-- ----------------------------
-- 初始化-字典类型表数据
-- ----------------------------
insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', current_timestamp, '', null, '用户性别列表');
insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', current_timestamp, '', null, '菜单状态列表');
insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', current_timestamp, '', null, '系统开关列表');
insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', current_timestamp, '', null, '任务状态列表');
insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', current_timestamp, '', null, '任务分组列表');
insert into sys_dict_type values(6, '任务执行器', 'sys_job_executor', '0', 'admin', current_timestamp, '', null, '任务执行器列表');
insert into sys_dict_type values(7, '系统是否', 'sys_yes_no', '0', 'admin', current_timestamp, '', null, '系统是否列表');
insert into sys_dict_type values(8, '通知类型', 'sys_notice_type', '0', 'admin', current_timestamp, '', null, '通知类型列表');
insert into sys_dict_type values(9, '通知状态', 'sys_notice_status', '0', 'admin', current_timestamp, '', null, '通知状态列表');
insert into sys_dict_type values(10, '操作类型', 'sys_oper_type', '0', 'admin', current_timestamp, '', null, '操作类型列表');
insert into sys_dict_type values(11, '系统状态', 'sys_common_status', '0', 'admin', current_timestamp, '', null, '登录状态列表');
-- ----------------------------
-- 12、字典数据表
-- ----------------------------
drop table if exists sys_dict_data;
create table sys_dict_data (
dict_code bigserial not null,
dict_sort int4 default 0,
dict_label varchar(100) default '',
dict_value varchar(100) default '',
dict_type varchar(100) default '',
css_class varchar(100) default null,
list_class varchar(100) default null,
is_default char(1) default 'N',
status char(1) default '0',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default null,
primary key (dict_code)
);
alter sequence sys_dict_data_dict_code_seq restart 100;
comment on column sys_dict_data.dict_code is '字典编码';
comment on column sys_dict_data.dict_sort is '字典排序';
comment on column sys_dict_data.dict_label is '字典标签';
comment on column sys_dict_data.dict_value is '字典键值';
comment on column sys_dict_data.dict_type is '字典类型';
comment on column sys_dict_data.css_class is '样式属性(其他样式扩展)';
comment on column sys_dict_data.list_class is '表格回显样式';
comment on column sys_dict_data.is_default is '是否默认Y是 N否';
comment on column sys_dict_data.status is '状态0正常 1停用';
comment on column sys_dict_data.create_by is '创建者';
comment on column sys_dict_data.create_time is '创建时间';
comment on column sys_dict_data.update_by is '更新者';
comment on column sys_dict_data.update_time is '更新时间';
comment on column sys_dict_data.remark is '备注';
comment on table sys_dict_data is '字典数据表';
-- ----------------------------
-- 初始化-字典数据表数据
-- ----------------------------
insert into sys_dict_data values(1, 1, '', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', current_timestamp, '', null, '性别男');
insert into sys_dict_data values(2, 2, '', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', current_timestamp, '', null, '性别女');
insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', current_timestamp, '', null, '性别未知');
insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', current_timestamp, '', null, '显示菜单');
insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '隐藏菜单');
insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', current_timestamp, '', null, '正常状态');
insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '停用状态');
insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', current_timestamp, '', null, '正常状态');
insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '停用状态');
insert into sys_dict_data values(10, 1, '默认', 'default', 'sys_job_group', '', '', 'Y', '0', 'admin', current_timestamp, '', null, '默认分组');
insert into sys_dict_data values(11, 2, '数据库', 'sqlalchemy', 'sys_job_group', '', '', 'N', '0', 'admin', current_timestamp, '', null, '数据库分组');
insert into sys_dict_data values(12, 3, 'redis', 'redis', 'sys_job_group', '', '', 'N', '0', 'admin', current_timestamp, '', null, 'reids分组');
insert into sys_dict_data values(13, 1, '默认', 'default', 'sys_job_executor', '', '', 'N', '0', 'admin', current_timestamp, '', null, '线程池');
insert into sys_dict_data values(14, 2, '进程池', 'processpool', 'sys_job_executor', '', '', 'N', '0', 'admin', current_timestamp, '', null, '进程池');
insert into sys_dict_data values(15, 1, '', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', current_timestamp, '', null, '系统默认是');
insert into sys_dict_data values(16, 2, '', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '系统默认否');
insert into sys_dict_data values(17, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', current_timestamp, '', null, '通知');
insert into sys_dict_data values(18, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', current_timestamp, '', null, '公告');
insert into sys_dict_data values(19, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', current_timestamp, '', null, '正常状态');
insert into sys_dict_data values(20, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '关闭状态');
insert into sys_dict_data values(21, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', current_timestamp, '', null, '其他操作');
insert into sys_dict_data values(22, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', current_timestamp, '', null, '新增操作');
insert into sys_dict_data values(23, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', current_timestamp, '', null, '修改操作');
insert into sys_dict_data values(24, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '删除操作');
insert into sys_dict_data values(25, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', current_timestamp, '', null, '授权操作');
insert into sys_dict_data values(26, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', current_timestamp, '', null, '导出操作');
insert into sys_dict_data values(27, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', current_timestamp, '', null, '导入操作');
insert into sys_dict_data values(28, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '强退操作');
insert into sys_dict_data values(29, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', current_timestamp, '', null, '生成操作');
insert into sys_dict_data values(30, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '清空操作');
insert into sys_dict_data values(31, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', current_timestamp, '', null, '正常状态');
insert into sys_dict_data values(32, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', current_timestamp, '', null, '停用状态');
-- ----------------------------
-- 13、参数配置表
-- ----------------------------
drop table if exists sys_config;
create table sys_config (
config_id serial not null,
config_name varchar(100) default '',
config_key varchar(100) default '',
config_value varchar(500) default '',
config_type char(1) default 'N',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default null,
primary key (config_id)
);
alter sequence sys_config_config_id_seq restart 100;
comment on column sys_config.config_id is '参数主键';
comment on column sys_config.config_name is '参数名称';
comment on column sys_config.config_key is '参数键名';
comment on column sys_config.config_value is '参数键值';
comment on column sys_config.config_type is '系统内置Y是 N否';
comment on column sys_config.create_by is '创建者';
comment on column sys_config.create_time is '创建时间';
comment on column sys_config.update_by is '更新者';
comment on column sys_config.update_time is '更新时间';
comment on column sys_config.remark is '备注';
comment on table sys_config is '参数配置表';
-- ----------------------------
-- 初始化-参数配置表数据
-- ----------------------------
insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', current_timestamp, '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', current_timestamp, '', null, '初始化密码 123456' );
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', current_timestamp, '', null, '深色主题theme-dark浅色主题theme-light' );
insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', current_timestamp, '', null, '是否开启验证码功能true开启false关闭');
insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', current_timestamp, '', null, '是否开启注册用户功能true开启false关闭');
insert into sys_config values(6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', current_timestamp, '', null, '设置登录IP黑名单限制多个匹配项以;分隔,支持匹配(*通配、网段)');
-- ----------------------------
-- 14、系统访问记录
-- ----------------------------
drop table if exists sys_logininfor;
create table sys_logininfor (
info_id bigserial not null,
user_name varchar(50) default '',
ipaddr varchar(128) default '',
login_location varchar(255) default '',
browser varchar(50) default '',
os varchar(50) default '',
status char(1) default '0',
msg varchar(255) default '',
login_time timestamp(0),
primary key (info_id)
);
alter sequence sys_logininfor_info_id_seq restart 100;
create index idx_sys_logininfor_s on sys_logininfor(status);
create index idx_sys_logininfor_lt on sys_logininfor(login_time);
comment on column sys_logininfor.info_id is '访问ID';
comment on column sys_logininfor.user_name is '用户账号';
comment on column sys_logininfor.ipaddr is '登录IP地址';
comment on column sys_logininfor.login_location is '登录地点';
comment on column sys_logininfor.browser is '浏览器类型';
comment on column sys_logininfor.os is '操作系统';
comment on column sys_logininfor.status is '登录状态0成功 1失败';
comment on column sys_logininfor.msg is '提示消息';
comment on column sys_logininfor.login_time is '访问时间';
comment on table sys_logininfor is '系统访问记录';
-- ----------------------------
-- 15、定时任务调度表
-- ----------------------------
drop table if exists sys_job;
create table sys_job (
job_id bigserial not null,
job_name varchar(64) default '',
job_group varchar(64) default 'default',
job_executor varchar(64) default 'default',
invoke_target varchar(500) not null,
job_args varchar(255) default '',
job_kwargs varchar(255) default '',
cron_expression varchar(255) default '',
misfire_policy varchar(20) default '3',
concurrent char(1) default '1',
status char(1) default '0',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default '',
primary key (job_id, job_name, job_group)
);
alter sequence sys_job_job_id_seq restart 100;
comment on column sys_job.job_id is '任务ID';
comment on column sys_job.job_name is '任务名称';
comment on column sys_job.job_group is '任务组名';
comment on column sys_job.job_executor is '任务执行器';
comment on column sys_job.invoke_target is '调用目标字符串';
comment on column sys_job.job_args is '位置参数';
comment on column sys_job.job_kwargs is '关键字参数';
comment on column sys_job.cron_expression is 'cron执行表达式';
comment on column sys_job.misfire_policy is '计划执行错误策略1立即执行 2执行一次 3放弃执行';
comment on column sys_job.concurrent is '是否并发执行0允许 1禁止';
comment on column sys_job.status is '状态0正常 1暂停';
comment on column sys_job.create_by is '创建者';
comment on column sys_job.create_time is '创建时间';
comment on column sys_job.update_by is '更新者';
comment on column sys_job.update_time is '更新时间';
comment on column sys_job.remark is '备注信息';
comment on table sys_job is '定时任务调度表';
-- ----------------------------
-- 初始化-定时任务调度表数据
-- ----------------------------
insert into sys_job values(1, '系统默认(无参)', 'default', 'default', 'module_task.scheduler_test.job', null, null, '0/10 * * * * ?', '3', '1', '1', 'admin', current_timestamp, '', null, '');
insert into sys_job values(2, '系统默认(有参)', 'default', 'default', 'module_task.scheduler_test.job', 'test', null, '0/15 * * * * ?', '3', '1', '1', 'admin', current_timestamp, '', null, '');
insert into sys_job values(3, '系统默认(多参)', 'default', 'default', 'module_task.scheduler_test.job', 'new', '{test: 111}', '0/20 * * * * ?', '3', '1', '1', 'admin', current_timestamp, '', null, '');
-- ----------------------------
-- 16、定时任务调度日志表
-- ----------------------------
drop table if exists sys_job_log;
create table sys_job_log (
job_log_id bigserial not null,
job_name varchar(64) not null,
job_group varchar(64) not null,
job_executor varchar(64) not null,
invoke_target varchar(500) not null,
job_args varchar(255) default '',
job_kwargs varchar(255) default '',
job_trigger varchar(255) default '',
job_message varchar(500),
status char(1) default '0',
exception_info varchar(2000) default '',
create_time timestamp(0),
primary key (job_log_id)
);
comment on column sys_job_log.job_log_id is '任务日志ID';
comment on column sys_job_log.job_name is '任务名称';
comment on column sys_job_log.job_group is '任务组名';
comment on column sys_job_log.job_executor is '任务执行器';
comment on column sys_job_log.invoke_target is '调用目标字符串';
comment on column sys_job_log.job_args is '位置参数';
comment on column sys_job_log.job_kwargs is '关键字参数';
comment on column sys_job_log.job_trigger is '任务触发器';
comment on column sys_job_log.job_message is '日志信息';
comment on column sys_job_log.status is '执行状态0正常 1失败';
comment on column sys_job_log.exception_info is '异常信息';
comment on column sys_job_log.create_time is '创建时间';
comment on table sys_job_log is '定时任务调度日志表';
-- ----------------------------
-- 17、通知公告表
-- ----------------------------
drop table if exists sys_notice;
create table sys_notice (
notice_id serial not null,
notice_title varchar(50) not null,
notice_type char(1) not null,
notice_content bytea default null,
status char(1) default '0',
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(255) default null,
primary key (notice_id)
);
alter sequence sys_notice_notice_id_seq restart 10;
comment on column sys_notice.notice_id is '公告ID';
comment on column sys_notice.notice_title is '公告标题';
comment on column sys_notice.notice_type is '公告类型1通知 2公告';
comment on column sys_notice.notice_content is '公告内容';
comment on column sys_notice.status is '公告状态0正常 1关闭';
comment on column sys_notice.create_by is '创建者';
comment on column sys_notice.create_time is '创建时间';
comment on column sys_notice.update_by is '更新者';
comment on column sys_notice.update_time is '更新时间';
comment on column sys_notice.remark is '备注';
comment on table sys_notice is '通知公告表';
-- ----------------------------
-- 初始化-公告信息表数据
-- ----------------------------
insert into sys_notice values(1, '温馨提醒2018-07-01 vfadmin新版本发布啦', '2', '新版本内容', '0', 'admin', current_timestamp, '', null, '管理员');
insert into sys_notice values(2, '维护通知2018-07-01 vfadmin系统凌晨维护', '1', '维护内容', '0', 'admin', current_timestamp, '', null, '管理员');
-- ----------------------------
-- 18、代码生成业务表
-- ----------------------------
drop table if exists gen_table;
create table gen_table (
table_id bigserial not null,
table_name varchar(200) default '',
table_comment varchar(500) default '',
sub_table_name varchar(64) default null,
sub_table_fk_name varchar(64) default null,
class_name varchar(100) default '',
tpl_category varchar(200) default 'crud',
tpl_web_type varchar(30) default '',
package_name varchar(100),
module_name varchar(30),
business_name varchar(30),
function_name varchar(50),
function_author varchar(50),
gen_type char(1) default '0',
gen_path varchar(200) default '/',
options varchar(1000),
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
remark varchar(500) default null,
primary key (table_id)
);
comment on column gen_table.table_id is '编号';
comment on column gen_table.table_name is '表名称';
comment on column gen_table.table_comment is '表描述';
comment on column gen_table.sub_table_name is '关联子表的表名';
comment on column gen_table.sub_table_fk_name is '子表关联的外键名';
comment on column gen_table.class_name is '实体类名称';
comment on column gen_table.tpl_category is '使用的模板crud单表操作 tree树表操作';
comment on column gen_table.tpl_web_type is '前端模板类型element-ui模版 element-plus模版';
comment on column gen_table.package_name is '生成包路径';
comment on column gen_table.module_name is '生成模块名';
comment on column gen_table.business_name is '生成业务名';
comment on column gen_table.function_name is '生成功能名';
comment on column gen_table.function_author is '生成功能作者';
comment on column gen_table.gen_type is '生成代码方式0zip压缩包 1自定义路径';
comment on column gen_table.gen_path is '生成路径(不填默认项目路径)';
comment on column gen_table.options is '其它生成选项';
comment on column gen_table.create_by is '创建者';
comment on column gen_table.create_time is '创建时间';
comment on column gen_table.update_by is '更新者';
comment on column gen_table.update_time is '更新时间';
comment on column gen_table.remark is '备注';
comment on table gen_table is '代码生成业务表';
-- ----------------------------
-- 19、代码生成业务表字段
-- ----------------------------
drop table if exists gen_table_column;
create table gen_table_column (
column_id bigserial not null,
table_id varchar(64),
column_name varchar(200),
column_comment varchar(500),
column_type varchar(100),
java_type varchar(500),
java_field varchar(200),
is_pk char(1),
is_increment char(1),
is_required char(1),
is_insert char(1),
is_edit char(1),
is_list char(1),
is_query char(1),
query_type varchar(200) default 'EQ',
html_type varchar(200),
dict_type varchar(200) default '',
sort int4,
create_by varchar(64) default '',
create_time timestamp(0),
update_by varchar(64) default '',
update_time timestamp(0),
primary key (column_id)
);
comment on column gen_table_column.column_id is '编号';
comment on column gen_table_column.table_id is '归属表编号';
comment on column gen_table_column.column_name is '列名称';
comment on column gen_table_column.column_comment is '列描述';
comment on column gen_table_column.column_type is '列类型';
comment on column gen_table_column.java_type is 'JAVA类型';
comment on column gen_table_column.java_field is 'JAVA字段名';
comment on column gen_table_column.is_pk is '是否主键1是';
comment on column gen_table_column.is_increment is '是否自增1是';
comment on column gen_table_column.is_required is '是否必填1是';
comment on column gen_table_column.is_insert is '是否为插入字段1是';
comment on column gen_table_column.is_edit is '是否编辑字段1是';
comment on column gen_table_column.is_list is '是否列表字段1是';
comment on column gen_table_column.is_query is '是否查询字段1是';
comment on column gen_table_column.query_type is '查询方式(等于、不等于、大于、小于、范围)';
comment on column gen_table_column.html_type is '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)';
comment on column gen_table_column.dict_type is '字典类型';
comment on column gen_table_column.sort is '排序';
comment on column gen_table_column.create_by is '创建者';
comment on column gen_table_column.create_time is '创建时间';
comment on column gen_table_column.update_by is '更新者';
comment on column gen_table_column.update_time is '更新时间';
comment on table gen_table_column is '代码生成业务表字段';
CREATE OR REPLACE FUNCTION "find_in_set"(int8, varchar)
RETURNS "pg_catalog"."bool" AS $BODY$
DECLARE
STR ALIAS FOR $1;
STRS ALIAS FOR $2;
POS INTEGER;
STATUS BOOLEAN;
BEGIN
SELECT POSITION( ','||STR||',' IN ','||STRS||',') INTO POS;
IF POS > 0 THEN
STATUS = TRUE;
ELSE
STATUS = FALSE;
END IF;
RETURN STATUS;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

View File

@@ -138,6 +138,7 @@ create table sys_menu (
path varchar(200) default '' comment '路由地址',
component varchar(255) default null comment '组件路径',
query varchar(255) default null comment '路由参数',
route_name varchar(50) default '' comment '路由名称',
is_frame int(1) default 1 comment '是否为外链0是 1否',
is_cache int(1) default 0 comment '是否缓存0缓存 1不缓存',
menu_type char(1) default '' comment '菜单类型M目录 C菜单 F按钮',
@@ -157,106 +158,106 @@ create table sys_menu (
-- 初始化-菜单信息表数据
-- ----------------------------
-- 一级菜单
insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录');
insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址');
insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录');
insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址');
-- 二级菜单
insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单');
insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单');
insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单');
insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单');
insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单');
insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单');
insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单');
insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单');
insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单');
insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单');
insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单');
insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单');
insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单');
insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单');
insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单');
insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单');
insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单');
insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单');
insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单');
insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单');
insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单');
insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单');
insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单');
insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单');
insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单');
insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单');
insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单');
insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单');
insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单');
insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单');
insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单');
insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单');
insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单');
insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单');
-- 三级菜单
insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单');
insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单');
insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单');
insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单');
-- 用户管理按钮
insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, '');
-- 角色管理按钮
insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, '');
-- 菜单管理按钮
insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, '');
-- 部门管理按钮
insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, '');
-- 岗位管理按钮
insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, '');
-- 字典管理按钮
insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, '');
-- 参数设置按钮
insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, '');
-- 通知公告按钮
insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, '');
-- 操作日志按钮
insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, '');
-- 登录日志按钮
insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, '');
-- 定时任务按钮
insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, '');
-- 代码生成按钮
insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, '');
-- ----------------------------

View File

@@ -7,4 +7,4 @@ def mount_staticfiles(app: FastAPI):
"""
挂载静态文件
"""
app.mount(f"{UploadConfig.UPLOAD_PREFIX}", StaticFiles(directory=f"{UploadConfig.UPLOAD_PATH}"), name="profile")
app.mount(f'{UploadConfig.UPLOAD_PREFIX}', StaticFiles(directory=f'{UploadConfig.UPLOAD_PATH}'), name='profile')

Some files were not shown because too many files have changed in this diff Show More