diff --git a/.gitignore b/.gitignore index 6e9c2a273ee3a3e06de28fc7c7036674ff28529d..006bfbf5d9fa6166c5952fb492a81fcd947b53b9 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ __pycache__/ # Distribution / packaging .Python -build/ develop-eggs/ dist/ downloads/ diff --git a/README.en.md b/README.en.md deleted file mode 100644 index c5d7be31c2f8ed97a529654ec00147db9534ddd5..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# RuoYi-Vue-FastAPI - -#### Description -基于ruoyi-ui和FastAPI开发的一个通用中后台管理框架 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 93cd87fbefc19c897ac8143681d3c3a0bff56f5e..8c69ed69206f315dbcc941c4028196acf12e28bc 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,186 @@ -# RuoYi-Vue-FastAPI +

+ logo +

+

RuoYi-Vue-FastAPI v1.0.0

+

基于RuoYi-Vue+FastAPI前后端分离的快速开发框架

+

+ + + + + + +

-#### 介绍 -基于ruoyi-ui和FastAPI开发的一个通用中后台管理框架 +## 平台简介 -#### 软件架构 -软件架构说明 +RuoYi-Vue-FastAPI是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 +* 前端采用Vue、Element UI,基于[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)前端项目修改。 +* 后端采用FastAPI、sqlalchemy、MySQL、Redis、OAuth2 & Jwt。 +* 权限认证使用OAuth2 & Jwt,支持多终端认证系统。 +* 支持加载动态权限菜单,多方式轻松权限控制。 +* Vue3版本: + - Gitte仓库地址:https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI。 + - GitHub仓库地址:https://github.com/insistence/RuoYi-Vue3-FastAPI。 +* 纯Python版本: + - Gitte仓库地址:https://gitee.com/insistence2022/dash-fastapi-admin。 + - GitHub仓库地址:https://github.com/insistence/Dash-FastAPI-Admin。 +* 特别鸣谢:[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)。 -#### 安装教程 +## 内置功能 -1. xxxx -2. xxxx -3. xxxx +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 +3. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 +4. 部门管理:配置系统组织机构(公司、部门、小组)。 +5. 岗位管理:配置系统用户所属担任职务。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 参数管理:对系统动态配置常用参数。 +8. 通知公告:系统通知公告信息发布维护。 +9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +10. 登录日志:系统登录日志记录查询包含登录异常。 +11. 在线用户:当前系统中活跃用户状态监控。 +12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +13. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 +14. 缓存监控:对系统的缓存信息查询,命令统计等。 +15. 在线构建器:拖动表单元素生成相应的HTML代码。 +16. 系统接口:根据业务代码自动生成相关的api接口文档。 -#### 使用说明 +## 演示图 -1. xxxx -2. xxxx -3. xxxx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-#### 参与贡献 +## 在线体验 +- *账号:admin* +- *密码:admin123* +- 演示地址:vfadmin管理系统 -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +## 项目开发及发布相关 +### 开发 -#### 特技 +```bash +# 克隆项目 +git clone https://gitee.com/insistence2022/RuoYi-Vue-FastAPI.git -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +# 进入项目根目录 +cd RuoYi-Vue-FastAPI +``` + +#### 前端 +```bash +# 进入前端目录 +cd ruoyi-fastapi-frontend + +# 安装依赖 +npm install + +# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 +npm install --registry=https://registry.npmmirror.com + +# 启动服务 +npm run dev +``` + +#### 后端 +```bash +# 进入后端目录 +cd ruoyi-fastapi-backend + +# 安装项目依赖环境 +pip3 install -r requirements.txt + +# 配置环境 +在.env.dev文件中配置开发环境的数据库和redis + +# 运行sql文件 +1.新建数据库ruoyi-fastapi(默认,可修改) +2.使用命令或数据库连接工具运行sql文件夹下的ruoyi-fastapi.sql + +# 运行后端 +python3 app.py --env=dev +``` + +#### 访问 +```bash +# 默认账号密码 +账号:admin +密码:admin123 + +# 浏览器访问 +地址:http://localhost:80 +``` + +### 发布 + +#### 前端 +```bash +# 构建测试环境 +npm run build:stage + +# 构建生产环境 +npm run build:prod +``` + +#### 后端 +```bash +# 配置环境 +在.env.prod文件中配置生产环境的数据库和redis + +# 运行后端 +python3 app.py --env=prod +``` + +## 交流与赞助 +如果有对本项目及FastAPI感兴趣的朋友,欢迎加入知识星球一起交流学习,让我们一起变得更强。如果你觉得这个项目帮助到了你,你可以请作者喝杯咖啡表示鼓励☕。扫描下面微信二维码添加微信备注VF-Admin即可进群。 + + + + + + + + +
zsxqzanzhu
wxcode
\ No newline at end of file diff --git a/demo-pictures/api.png b/demo-pictures/api.png new file mode 100644 index 0000000000000000000000000000000000000000..3ec9c249f896d4505e7b563826fbe31c1340376c Binary files /dev/null and b/demo-pictures/api.png differ diff --git a/demo-pictures/cache.png b/demo-pictures/cache.png new file mode 100644 index 0000000000000000000000000000000000000000..6529c7d63e28331b0c5c344d4e12dd13e7b8c7fc Binary files /dev/null and b/demo-pictures/cache.png differ diff --git a/demo-pictures/cacheList.png b/demo-pictures/cacheList.png new file mode 100644 index 0000000000000000000000000000000000000000..b2cdddc436efa24fde8e2661da8b26d3d3f9ce9b Binary files /dev/null and b/demo-pictures/cacheList.png differ diff --git a/demo-pictures/config.png b/demo-pictures/config.png new file mode 100644 index 0000000000000000000000000000000000000000..99de373f95f19589b1472ee1866ee83d7a2db126 Binary files /dev/null and b/demo-pictures/config.png differ diff --git a/demo-pictures/dashboard.png b/demo-pictures/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..5a371c5549a3996f9c9974e5ecc04c2c6a25bb0c Binary files /dev/null and b/demo-pictures/dashboard.png differ diff --git a/demo-pictures/dept.png b/demo-pictures/dept.png new file mode 100644 index 0000000000000000000000000000000000000000..46680f82c823ddff470c6ec06ada5980a180a84a Binary files /dev/null and b/demo-pictures/dept.png differ diff --git a/demo-pictures/dict.png b/demo-pictures/dict.png new file mode 100644 index 0000000000000000000000000000000000000000..e34617bd692690ffd79c9c7c2065b858fd4ae0db Binary files /dev/null and b/demo-pictures/dict.png differ diff --git a/demo-pictures/form.png b/demo-pictures/form.png new file mode 100644 index 0000000000000000000000000000000000000000..caac855a29200879fbde2735ad9eda156480abfb Binary files /dev/null and b/demo-pictures/form.png differ diff --git a/demo-pictures/job.png b/demo-pictures/job.png new file mode 100644 index 0000000000000000000000000000000000000000..69a4c01b5416911ebdfa98f11e202918eecec0bf Binary files /dev/null and b/demo-pictures/job.png differ diff --git a/demo-pictures/login.png b/demo-pictures/login.png new file mode 100644 index 0000000000000000000000000000000000000000..c9679e26268dcc5b7c658893665112fdcd4feaf3 Binary files /dev/null and b/demo-pictures/login.png differ diff --git a/demo-pictures/loginLog.png b/demo-pictures/loginLog.png new file mode 100644 index 0000000000000000000000000000000000000000..f64137b3de82bf301d2fbe582b90ed97472d7aab Binary files /dev/null and b/demo-pictures/loginLog.png differ diff --git a/demo-pictures/menu.png b/demo-pictures/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..1b8a8193c0e41fe9283ed14aeea800fb17e481b9 Binary files /dev/null and b/demo-pictures/menu.png differ diff --git a/demo-pictures/notice.png b/demo-pictures/notice.png new file mode 100644 index 0000000000000000000000000000000000000000..cca87c3a9c47090579614a87cae48d8e2294a868 Binary files /dev/null and b/demo-pictures/notice.png differ diff --git a/demo-pictures/online.png b/demo-pictures/online.png new file mode 100644 index 0000000000000000000000000000000000000000..1573f86665c44a72093753d8d2ecfeacc2765379 Binary files /dev/null and b/demo-pictures/online.png differ diff --git a/demo-pictures/operLog.png b/demo-pictures/operLog.png new file mode 100644 index 0000000000000000000000000000000000000000..14e797c4e80a5a285ccc258dd02d4d84b383e87c Binary files /dev/null and b/demo-pictures/operLog.png differ diff --git a/demo-pictures/post.png b/demo-pictures/post.png new file mode 100644 index 0000000000000000000000000000000000000000..5060b4ff87ddc2fc7d0f84cb7d1f89bbd9e7f8f4 Binary files /dev/null and b/demo-pictures/post.png differ diff --git a/demo-pictures/profile.png b/demo-pictures/profile.png new file mode 100644 index 0000000000000000000000000000000000000000..13de5c9140752e9eaadae5a0bb5cb53f63d8502c Binary files /dev/null and b/demo-pictures/profile.png differ diff --git a/demo-pictures/role.png b/demo-pictures/role.png new file mode 100644 index 0000000000000000000000000000000000000000..6039f2c05089fe6097dc48c3b72e028013c3a3e1 Binary files /dev/null and b/demo-pictures/role.png differ diff --git a/demo-pictures/server.png b/demo-pictures/server.png new file mode 100644 index 0000000000000000000000000000000000000000..d7185bb502acf5255072b36c5ac028c281f090c2 Binary files /dev/null and b/demo-pictures/server.png differ diff --git a/demo-pictures/user.png b/demo-pictures/user.png new file mode 100644 index 0000000000000000000000000000000000000000..aa1d83acbf1f5744680f6109841389789ee08d31 Binary files /dev/null and b/demo-pictures/user.png differ diff --git a/demo-pictures/wxcode.jpg b/demo-pictures/wxcode.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d9a0b1d589e5c4dab0715704cb3f943d553def0 Binary files /dev/null and b/demo-pictures/wxcode.jpg differ diff --git a/demo-pictures/zanzhu.jpg b/demo-pictures/zanzhu.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fb6e349cfad942ed3ab5b07b186bb06a7b38d4ee Binary files /dev/null and b/demo-pictures/zanzhu.jpg differ diff --git a/demo-pictures/zsxq.jpg b/demo-pictures/zsxq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6babeaff47a78607d760ede75cc39836fc4c5e38 Binary files /dev/null and b/demo-pictures/zsxq.jpg differ diff --git a/ruoyi-fastapi-backend/.env.dev b/ruoyi-fastapi-backend/.env.dev new file mode 100644 index 0000000000000000000000000000000000000000..33d19fc02ba3c70701448d05305841ec1e49198b --- /dev/null +++ b/ruoyi-fastapi-backend/.env.dev @@ -0,0 +1,50 @@ +# -------- 应用配置 -------- +# 应用运行环境 +APP_ENV = 'dev' +# 应用名称 +APP_NAME = 'RuoYi-FasAPI' +# 应用代理路径 +APP_ROOT_PATH = '/dev-api' +# 应用主机 +APP_HOST = '0.0.0.0' +# 应用端口 +APP_PORT = 9099 +# 应用版本 +APP_VERSION= '1.0.0' +# 应用是否开启热重载 +APP_RELOAD = true + +# -------- Jwt配置 -------- +# Jwt秘钥 +JWT_SECRET_KEY = 'b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55' +# Jwt算法 +JWT_ALGORITHM = 'HS256' +# 令牌过期时间 +JWT_EXPIRE_MINUTES = 1440 +# redis中令牌过期时间 +JWT_REDIS_EXPIRE_MINUTES = 30 + + +# -------- 数据库配置 -------- +# 数据库主机 +DB_HOST = '127.0.0.1' +# 数据库端口 +DB_PORT = 3306 +# 数据库用户名 +DB_USERNAME = 'root' +# 数据库密码 +DB_PASSWORD = 'mysqlroot' +# 数据库名称 +DB_DATABASE = 'ruoyi-fastapi' + +# -------- Redis配置 -------- +# Redis主机 +REDIS_HOST = '127.0.0.1' +# Redis端口 +REDIS_PORT = 6379 +# Redis用户名 +REDIS_USERNAME = '' +# Redis密码 +REDIS_PASSWORD = '' +# Redis数据库 +REDIS_DATABASE = 2 \ No newline at end of file diff --git a/ruoyi-fastapi-backend/.env.prod b/ruoyi-fastapi-backend/.env.prod new file mode 100644 index 0000000000000000000000000000000000000000..eddcd5895248ea7add3ee18c22d7ce736451dacf --- /dev/null +++ b/ruoyi-fastapi-backend/.env.prod @@ -0,0 +1,50 @@ +# -------- 应用配置 -------- +# 应用运行环境 +APP_ENV = 'prod' +# 应用名称 +APP_NAME = 'RuoYi-FasAPI' +# 应用代理路径 +APP_ROOT_PATH = '/prod-api' +# 应用主机 +APP_HOST = '0.0.0.0' +# 应用端口 +APP_PORT = 9099 +# 应用版本 +APP_VERSION= '1.0.0' +# 应用是否开启热重载 +APP_RELOAD = false + +# -------- Jwt配置 -------- +# Jwt秘钥 +JWT_SECRET_KEY = 'b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55' +# Jwt算法 +JWT_ALGORITHM = 'HS256' +# 令牌过期时间 +JWT_EXPIRE_MINUTES = 1440 +# redis中令牌过期时间 +JWT_REDIS_EXPIRE_MINUTES = 30 + + +# -------- 数据库配置 -------- +# 数据库主机 +DB_HOST = '127.0.0.1' +# 数据库端口 +DB_PORT = 3306 +# 数据库用户名 +DB_USERNAME = 'root' +# 数据库密码 +DB_PASSWORD = 'root' +# 数据库名称 +DB_DATABASE = 'ruoyi-fastapi' + +# -------- Redis配置 -------- +# Redis主机 +REDIS_HOST = '127.0.0.1' +# Redis端口 +REDIS_PORT = 6379 +# Redis用户名 +REDIS_USERNAME = '' +# Redis密码 +REDIS_PASSWORD = '' +# Redis数据库 +REDIS_DATABASE = 2 \ No newline at end of file diff --git a/ruoyi-fastapi-backend/app.py b/ruoyi-fastapi-backend/app.py new file mode 100644 index 0000000000000000000000000000000000000000..7797fa934cb5641a857724ae64d0307221ac97f1 --- /dev/null +++ b/ruoyi-fastapi-backend/app.py @@ -0,0 +1,12 @@ +import uvicorn +from server import app, AppConfig + + +if __name__ == '__main__': + uvicorn.run( + app='app:app', + host=AppConfig.app_host, + port=AppConfig.app_port, + root_path=AppConfig.app_root_path, + reload=AppConfig.app_reload + ) diff --git a/ruoyi-fastapi/assets/font/Arial.ttf b/ruoyi-fastapi-backend/assets/font/Arial.ttf similarity index 100% rename from ruoyi-fastapi/assets/font/Arial.ttf rename to ruoyi-fastapi-backend/assets/font/Arial.ttf diff --git a/ruoyi-fastapi/config/database.py b/ruoyi-fastapi-backend/config/database.py similarity index 62% rename from ruoyi-fastapi/config/database.py rename to ruoyi-fastapi-backend/config/database.py index a9acc4c4f06f77155e6cbe2feaf82c7a0a7babc9..8d2012fbcd07067aacb69682876e474444058ace 100644 --- a/ruoyi-fastapi/config/database.py +++ b/ruoyi-fastapi-backend/config/database.py @@ -4,8 +4,8 @@ from sqlalchemy.orm import sessionmaker from urllib.parse import quote_plus from config.env import DataBaseConfig -SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.USERNAME}:{quote_plus(DataBaseConfig.PASSWORD)}@" \ - f"{DataBaseConfig.HOST}:{DataBaseConfig.PORT}/{DataBaseConfig.DB}" +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=True diff --git a/ruoyi-fastapi-backend/config/env.py b/ruoyi-fastapi-backend/config/env.py new file mode 100644 index 0000000000000000000000000000000000000000..224a2708a0292022bc1fd874b6556a3952053a9c --- /dev/null +++ b/ruoyi-fastapi-backend/config/env.py @@ -0,0 +1,189 @@ +import os +import sys +import argparse +from pydantic_settings import BaseSettings +from functools import lru_cache +from dotenv import load_dotenv + + +class AppSettings(BaseSettings): + """ + 应用配置 + """ + app_env: str = 'dev' + app_name: str = 'RuoYi-FasAPI' + app_root_path: str = '/dev-api' + app_host: str = '0.0.0.0' + app_port: int = 9099 + app_version: str = '1.0.0' + app_reload: bool = True + + +class JwtSettings(BaseSettings): + """ + Jwt配置 + """ + jwt_secret_key: str = 'b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55' + jwt_algorithm: str = 'HS256' + jwt_expire_minutes: int = 1440 + jwt_redis_expire_minutes: int = 30 + + +class DataBaseSettings(BaseSettings): + """ + 数据库配置 + """ + db_host: str = '127.0.0.1' + db_port: int = 3306 + db_username: str = 'root' + db_password: str = 'mysqlroot' + db_database: str = 'ruoyi-fastapi' + + +class RedisSettings(BaseSettings): + """ + Redis配置 + """ + redis_host: str = '127.0.0.1' + redis_port: int = 6379 + redis_username: str = '' + redis_password: str = '' + redis_database: int = 2 + + +class UploadSettings: + """ + 上传配置 + """ + UPLOAD_PREFIX = '/profile' + UPLOAD_PATH = 'vf_admin/upload_path' + UPLOAD_MACHINE = 'A' + DEFAULT_ALLOWED_EXTENSION = [ + # 图片 + "bmp", "gif", "jpg", "jpeg", "png", + # word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + # 压缩文件 + "rar", "zip", "gz", "bz2", + # 视频格式 + "mp4", "avi", "rmvb", + # pdf + "pdf" + ] + DOWNLOAD_PATH = 'vf_admin/download_path' + + def __init__(self): + if not os.path.exists(self.UPLOAD_PATH): + os.makedirs(self.UPLOAD_PATH) + if not os.path.exists(self.DOWNLOAD_PATH): + os.makedirs(self.DOWNLOAD_PATH) + + +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: + """ + 获取配置 + """ + + def __init__(self): + self.parse_cli_args() + + @lru_cache() + def get_app_config(self): + """ + 获取应用配置 + """ + # 实例化应用配置模型 + return AppSettings() + + @lru_cache() + def get_jwt_config(self): + """ + 获取Jwt配置 + """ + # 实例化Jwt配置模型 + return JwtSettings() + + @lru_cache() + def get_database_config(self): + """ + 获取数据库配置 + """ + # 实例化数据库配置模型 + return DataBaseSettings() + + @lru_cache() + def get_redis_config(self): + """ + 获取Redis配置 + """ + # 实例化Redis配置模型 + return RedisSettings() + + @lru_cache() + def get_upload_config(self): + """ + 获取数据库配置 + """ + # 实例上传配置 + return UploadSettings() + + @staticmethod + def parse_cli_args(): + """ + 解析命令行参数 + """ + if 'uvicorn' in sys.argv[0]: + # 使用uvicorn启动时,命令行参数需要按照uvicorn的文档进行配置,无法自定义参数 + pass + else: + # 使用argparse定义命令行参数 + parser = argparse.ArgumentParser(description='命令行参数') + parser.add_argument('--env', type=str, default='', help='运行环境') + # 解析命令行参数 + args = parser.parse_args() + # 设置环境变量,如果未设置命令行参数,默认APP_ENV为dev + os.environ['APP_ENV'] = args.env if args.env else 'dev' + # 读取运行环境 + run_env = os.environ.get('APP_ENV', '') + # 运行环境未指定时默认加载.env.dev + env_file = '.env.dev' + # 运行环境不为空时按命令行参数加载对应.env文件 + if run_env != '': + env_file = f'.env.{run_env}' + # 加载配置 + load_dotenv(env_file) + + +# 实例化获取配置类 +get_config = GetConfig() +# 应用配置 +AppConfig = get_config.get_app_config() +# Jwt配置 +JwtConfig = get_config.get_jwt_config() +# 数据库配置 +DataBaseConfig = get_config.get_database_config() +# Redis配置 +RedisConfig = get_config.get_redis_config() +# 上传配置 +UploadConfig = get_config.get_upload_config() diff --git a/ruoyi-fastapi/config/get_db.py b/ruoyi-fastapi-backend/config/get_db.py similarity index 100% rename from ruoyi-fastapi/config/get_db.py rename to ruoyi-fastapi-backend/config/get_db.py diff --git a/ruoyi-fastapi/config/get_redis.py b/ruoyi-fastapi-backend/config/get_redis.py similarity index 63% rename from ruoyi-fastapi/config/get_redis.py rename to ruoyi-fastapi-backend/config/get_redis.py index c7bc8ec6dfdca02c4670df43e2c4e55699ad8cb0..4c3ef800f881cae013ac0d3a76590b98d5860ceb 100644 --- a/ruoyi-fastapi/config/get_redis.py +++ b/ruoyi-fastapi-backend/config/get_redis.py @@ -1,4 +1,5 @@ -import aioredis +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.env import RedisConfig @@ -19,15 +20,26 @@ class RedisUtil: """ logger.info("开始连接redis...") redis = await aioredis.from_url( - url=f"redis://{RedisConfig.HOST}", - port=RedisConfig.PORT, - username=RedisConfig.USERNAME, - password=RedisConfig.PASSWORD, - db=RedisConfig.DB, + 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 ) - logger.info("redis连接成功") + try: + connection = await redis.ping() + if connection: + logger.info("redis连接成功") + else: + logger.error("redis连接失败") + except AuthenticationError as e: + logger.error(f"redis用户名或密码错误,详细错误信息:{e}") + except TimeoutError as e: + logger.error(f"redis连接超时,详细错误信息:{e}") + except RedisError as e: + logger.error(f"redis连接错误,详细错误信息:{e}") return redis @classmethod diff --git a/ruoyi-fastapi/config/get_scheduler.py b/ruoyi-fastapi-backend/config/get_scheduler.py similarity index 74% rename from ruoyi-fastapi/config/get_scheduler.py rename to ruoyi-fastapi-backend/config/get_scheduler.py index b60cadee5bc18cfc1dbdc6c5ea7c5ac4617a7a1e..17e5ae5bb8e6f8b4de759fee04c30de0cfb4acf5 100644 --- a/ruoyi-fastapi/config/get_scheduler.py +++ b/ruoyi-fastapi-backend/config/get_scheduler.py @@ -20,11 +20,49 @@ class MyCronTrigger(CronTrigger): @classmethod def from_crontab(cls, expr, timezone=None): values = expr.split() - if len(values) != 7: - raise ValueError('Wrong number of fields; got {}, expected 7'.format(len(values))) + if len(values) != 6 and len(values) != 7: + raise ValueError('Wrong number of fields; got {}, expected 6 or 7'.format(len(values))) - return cls(second=values[0], minute=values[1], hour=values[2], day=values[3], month=values[4], - day_of_week=values[5], year=values[6], timezone=timezone) + second = values[0] + minute = values[1] + hour = values[2] + if '?' in values[3]: + day = None + elif 'L' in values[5]: + day = f"last {values[5].replace('L', '')}" + elif 'W' in values[3]: + day = cls.__find_recent_workday(int(values[3].split('W')[0])) + else: + day = values[3].replace('L', 'last') + month = values[4] + if '?' in values[5] or 'L' in values[5]: + week = None + elif '#' in values[5]: + week = int(values[5].split('#')[1]) + else: + week = values[5] + if '#' in values[5]: + day_of_week = int(values[5].split('#')[0]) - 1 + 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) + + @classmethod + def __find_recent_workday(cls, day): + now = datetime.now() + date = datetime(now.year, now.month, day) + if date.weekday() < 5: + return date.day + else: + diff = 1 + while True: + previous_day = date - timedelta(days=diff) + if previous_day.weekday() < 5: + return previous_day.day + else: + diff += 1 job_stores = { @@ -32,11 +70,11 @@ job_stores = { 'sqlalchemy': SQLAlchemyJobStore(url=SQLALCHEMY_DATABASE_URL, engine=engine), 'redis': RedisJobStore( **dict( - host=RedisConfig.HOST, - port=RedisConfig.PORT, - username=RedisConfig.USERNAME, - password=RedisConfig.PASSWORD, - db=RedisConfig.DB + host=RedisConfig.redis_host, + port=RedisConfig.redis_port, + username=RedisConfig.redis_username, + password=RedisConfig.redis_password, + db=RedisConfig.redis_database ) ) } @@ -177,18 +215,18 @@ class SchedulerUtil: 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 = dict( - job_name=job_name, - job_group=job_group, - job_executor=job_executor, - invoke_target=invoke_target, - job_args=job_args, - job_kwargs=job_kwargs, - job_trigger=job_trigger, - job_message=job_message, + 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, - exception_info=exception_info + exceptionInfo=exception_info ) session = SessionLocal() - JobLogService.add_job_log_services(session, JobLogModel(**job_log)) + JobLogService.add_job_log_services(session, job_log) session.close() diff --git a/ruoyi-fastapi-backend/exceptions/exception.py b/ruoyi-fastapi-backend/exceptions/exception.py new file mode 100644 index 0000000000000000000000000000000000000000..ef2fda06fdc21e8ea79bf5969483e4a97e7018c5 --- /dev/null +++ b/ruoyi-fastapi-backend/exceptions/exception.py @@ -0,0 +1,28 @@ +class LoginException(Exception): + """ + 自定义登录异常LoginException + """ + + def __init__(self, data: str = None, message: str = None): + self.data = data + self.message = message + + +class AuthException(Exception): + """ + 自定义令牌异常AuthException + """ + + def __init__(self, data: str = None, message: str = None): + self.data = data + self.message = message + + +class PermissionException(Exception): + """ + 自定义权限异常PermissionException + """ + + def __init__(self, data: str = None, message: str = None): + self.data = data + self.message = message diff --git a/ruoyi-fastapi-backend/exceptions/handle.py b/ruoyi-fastapi-backend/exceptions/handle.py new file mode 100644 index 0000000000000000000000000000000000000000..61b7f9009f07b85e14f95399ee2671527792790a --- /dev/null +++ b/ruoyi-fastapi-backend/exceptions/handle.py @@ -0,0 +1,27 @@ +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 + + +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(PermissionException) + async def permission_exception_handler(request: Request, exc: PermissionException): + return ResponseUtil.forbidden(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 + ) diff --git a/ruoyi-fastapi-backend/middlewares/cors_middleware.py b/ruoyi-fastapi-backend/middlewares/cors_middleware.py new file mode 100644 index 0000000000000000000000000000000000000000..4b78db9fc1f66cd449810a626cbbc3d4b88b49b7 --- /dev/null +++ b/ruoyi-fastapi-backend/middlewares/cors_middleware.py @@ -0,0 +1,19 @@ +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + + +def add_cors_middleware(app: FastAPI): + # 前端页面url + origins = [ + "http://localhost:80", + "http://127.0.0.1:80", + ] + + # 后台api允许跨域 + app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) diff --git a/ruoyi-fastapi-backend/middlewares/handle.py b/ruoyi-fastapi-backend/middlewares/handle.py new file mode 100644 index 0000000000000000000000000000000000000000..311ec6b62d27957b8aade8920b867ee8c818f8a0 --- /dev/null +++ b/ruoyi-fastapi-backend/middlewares/handle.py @@ -0,0 +1,10 @@ +from fastapi import FastAPI +from middlewares.cors_middleware import add_cors_middleware + + +def handle_middleware(app: FastAPI): + """ + 全局中间件处理 + """ + # 加载跨域中间件 + add_cors_middleware(app) diff --git a/ruoyi-fastapi/module_admin/annotation/log_annotation.py b/ruoyi-fastapi-backend/module_admin/annotation/log_annotation.py similarity index 100% rename from ruoyi-fastapi/module_admin/annotation/log_annotation.py rename to ruoyi-fastapi-backend/module_admin/annotation/log_annotation.py diff --git a/ruoyi-fastapi/module_admin/annotation/form_annotation.py b/ruoyi-fastapi-backend/module_admin/annotation/pydantic_annotation.py similarity index 48% rename from ruoyi-fastapi/module_admin/annotation/form_annotation.py rename to ruoyi-fastapi-backend/module_admin/annotation/pydantic_annotation.py index 06d9c2620f6eb0be54c1ffa0df3f87c3dde2deca..306901568a12df48ef422799e0921e8d58718cef 100644 --- a/ruoyi-fastapi/module_admin/annotation/form_annotation.py +++ b/ruoyi-fastapi-backend/module_admin/annotation/pydantic_annotation.py @@ -1,14 +1,52 @@ import inspect from typing import Type -from fastapi import Form +from fastapi import Query, Form from pydantic import BaseModel from pydantic.fields import FieldInfo +def as_query(cls: Type[BaseModel]): + """ + pydantic模型查询参数装饰器,将pydantic模型用于接收查询参数 + """ + new_parameters = [] + + for field_name, model_field in cls.model_fields.items(): + model_field: FieldInfo # type: ignore + + if not model_field.is_required(): + new_parameters.append( + inspect.Parameter( + model_field.alias, + inspect.Parameter.POSITIONAL_ONLY, + default=Query(model_field.default), + annotation=model_field.annotation + ) + ) + else: + new_parameters.append( + inspect.Parameter( + model_field.alias, + inspect.Parameter.POSITIONAL_ONLY, + default=Query(...), + annotation=model_field.annotation + ) + ) + + async def as_query_func(**data): + return cls(**data) + + sig = inspect.signature(as_query_func) + sig = sig.replace(parameters=new_parameters) + as_query_func.__signature__ = sig # type: ignore + setattr(cls, 'as_query', as_query_func) + return cls + + def as_form(cls: Type[BaseModel]): """ - pydantic模型表单装饰器,将pydantic模型用于接收表单数据 + pydantic模型表单参数装饰器,将pydantic模型用于接收表单参数 """ new_parameters = [] diff --git a/ruoyi-fastapi/module_admin/aspect/data_scope.py b/ruoyi-fastapi-backend/module_admin/aspect/data_scope.py similarity index 100% rename from ruoyi-fastapi/module_admin/aspect/data_scope.py rename to ruoyi-fastapi-backend/module_admin/aspect/data_scope.py diff --git a/ruoyi-fastapi/module_admin/aspect/interface_auth.py b/ruoyi-fastapi-backend/module_admin/aspect/interface_auth.py similarity index 92% rename from ruoyi-fastapi/module_admin/aspect/interface_auth.py rename to ruoyi-fastapi-backend/module_admin/aspect/interface_auth.py index 876670a8c14ecea29a57c358eac33f9b3cd64773..d91bdb4dfe022ffbc28cfab35b530408fd55fc48 100644 --- a/ruoyi-fastapi/module_admin/aspect/interface_auth.py +++ b/ruoyi-fastapi-backend/module_admin/aspect/interface_auth.py @@ -1,7 +1,7 @@ from fastapi import Depends from module_admin.entity.vo.user_vo import CurrentUserModel from module_admin.service.login_service import LoginService -from utils.response_util import PermissionException +from exceptions.exception import PermissionException class CheckUserInterfaceAuth: diff --git a/ruoyi-fastapi/module_admin/controller/cache_controller.py b/ruoyi-fastapi-backend/module_admin/controller/cache_controller.py similarity index 50% rename from ruoyi-fastapi/module_admin/controller/cache_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/cache_controller.py index 76426a58e1949c2877cdc4786ebc7ad1f51c1997..7b7da4bf1f97ffffd4dc3a5b8737c4628438324f 100644 --- a/ruoyi-fastapi/module_admin/controller/cache_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/cache_controller.py @@ -1,94 +1,94 @@ from fastapi import APIRouter from fastapi import Depends -from module_admin.service.login_service import get_current_user +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 module_admin.aspect.interface_auth import CheckUserInterfaceAuth -cacheController = APIRouter(prefix='/cache', dependencies=[Depends(get_current_user)]) +cacheController = APIRouter(prefix='/monitor/cache', dependencies=[Depends(LoginService.get_current_user)]) -@cacheController.post("/statisticalInfo", 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 response_200(data=cache_info_query_result, message="获取成功") + return ResponseUtil.success(data=cache_info_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@cacheController.post("/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 response_200(data=cache_name_list_result, message="获取成功") + return ResponseUtil.success(data=cache_name_list_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@cacheController.post("/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 response_200(data=cache_key_list_result, message="获取成功") + return ResponseUtil.success(data=cache_key_list_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@cacheController.post("/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 response_200(data=cache_value_list_result, message="获取成功") + return ResponseUtil.success(data=cache_value_list_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@cacheController.post("/clearCacheName/{cache_name}", response_model=CrudCacheResponse, 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 response_200(data=clear_cache_name_result, message=clear_cache_name_result.message) + return ResponseUtil.success(msg=clear_cache_name_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@cacheController.post("/clearCacheKey/{cache_name}/{cache_key}", response_model=CrudCacheResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) -async def clear_monitor_cache_key(request: Request, cache_name: str, cache_key: str): +@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_name, cache_key) + 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 response_200(data=clear_cache_key_result, message=clear_cache_key_result.message) + return ResponseUtil.success(msg=clear_cache_key_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@cacheController.post("/clearCacheAll", response_model=CrudCacheResponse, 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 response_200(data=clear_cache_all_result, message=clear_cache_all_result.message) + return ResponseUtil.success(msg=clear_cache_all_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/captcha_controller.py b/ruoyi-fastapi-backend/module_admin/controller/captcha_controller.py similarity index 67% rename from ruoyi-fastapi/module_admin/controller/captcha_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/captcha_controller.py index 13545aa572b5b39054c8803d724e7f6a4091ff24..4fc64b66b666dd2e8c21b5701ee218dbb35ed7f0 100644 --- a/ruoyi-fastapi/module_admin/controller/captcha_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/captcha_controller.py @@ -14,6 +14,9 @@ captchaController = APIRouter() @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] @@ -21,7 +24,7 @@ async def get_captcha_image(request: Request): 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=True, img=image, uuid=session_id) + model_content=CaptchaCode(captchaEnabled=captcha_enabled, registerEnabled=register_enabled, img=image, uuid=session_id) ) except Exception as e: logger.exception(e) diff --git a/ruoyi-fastapi-backend/module_admin/controller/common_controller.py b/ruoyi-fastapi-backend/module_admin/controller/common_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..d2981490d341ecf3a4b3546e99a6d114695a2467 --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/controller/common_controller.py @@ -0,0 +1,53 @@ +from fastapi import APIRouter +from fastapi import Depends, File, Query +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 * + +commonController = APIRouter(prefix='/common', dependencies=[Depends(LoginService.get_current_user)]) + + +@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)) + + +@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/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)) diff --git a/ruoyi-fastapi/module_admin/controller/config_controller.py b/ruoyi-fastapi-backend/module_admin/controller/config_controller.py similarity index 54% rename from ruoyi-fastapi/module_admin/controller/config_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/config_controller.py index d24aa8d86048909984015050235a0f3bca6fd852..db89e20e4a1a8225215f530e0a9da37d01a91fa4 100644 --- a/ruoyi-fastapi/module_admin/controller/config_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/config_controller.py @@ -3,34 +3,30 @@ from fastapi import Depends from config.get_db import get_db from module_admin.service.login_service import LoginService, CurrentUserModel from module_admin.service.config_service import * -from module_admin.entity.vo.config_vo import * from utils.response_util import * from utils.log_util import * -from utils.page_util import get_page_obj +from utils.page_util import * from utils.common_util import bytes2file_response from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.annotation.log_annotation import log_decorator -configController = APIRouter(prefix='/config', dependencies=[Depends(LoginService.get_current_user)]) +configController = APIRouter(prefix='/system/config', dependencies=[Depends(LoginService.get_current_user)]) -@configController.post("/config/get", response_model=ConfigPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:list'))]) -async def get_system_config_list(request: Request, config_page_query: ConfigPageObject, query_db: Session = Depends(get_db)): +@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_query = ConfigQueryModel(**config_page_query.dict()) - # 获取全量数据 - config_query_result = ConfigService.get_config_list_services(query_db, config_query) - # 分页操作 - config_page_query_result = get_page_obj(config_query_result, config_page_query.page_num, config_page_query.page_size) + # 获取分页数据 + config_page_query_result = ConfigService.get_config_list_services(query_db, config_page_query, is_page=True) logger.info('获取成功') - return response_200(data=config_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=config_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@configController.post("/config/add", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:add'))]) +@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: @@ -39,58 +35,75 @@ async def add_system_config(request: Request, add_config: ConfigModel, query_db: 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 response_200(data=add_config_result, message=add_config_result.message) + return ResponseUtil.success(msg=add_config_result.message) else: logger.warning(add_config_result.message) - return response_400(data="", message=add_config_result.message) + return ResponseUtil.failure(msg=add_config_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@configController.patch("/config/edit", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:edit'))]) +@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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_config_result, message=edit_config_result.message) + return ResponseUtil.success(msg=edit_config_result.message) else: logger.warning(edit_config_result.message) - return response_400(data="", message=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.delete("/refreshCache", dependencies=[Depends(CheckUserInterfaceAuth('system:config:edit'))]) +@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 response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@configController.post("/config/delete", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:remove'))]) +@configController.delete("/{config_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:config:remove'))]) @log_decorator(title='参数管理', business_type=3) -async def delete_system_config(request: Request, delete_config: DeleteConfigModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_config_result, message=delete_config_result.message) + return ResponseUtil.success(msg=delete_config_result.message) else: logger.warning(delete_config_result.message) - return response_400(data="", message=delete_config_result.message) + return ResponseUtil.failure(msg=delete_config_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@configController.get("/config/{config_id}", response_model=ConfigModel, dependencies=[Depends(CheckUserInterfaceAuth('system:config:query'))]) +@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: - detail_config_result = ConfigService.detail_config_services(query_db, config_id) + config_detail_result = ConfigService.config_detail_services(query_db, config_id) logger.info(f'获取config_id为{config_id}的信息成功') - return response_200(data=detail_config_result, message='获取成功') + return ResponseUtil.success(data=config_detail_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) @configController.get("/configKey/{config_key}") @@ -105,31 +118,15 @@ async def query_system_config(request: Request, config_key: str): return ResponseUtil.error(msg=str(e)) -@configController.post("/config/export", dependencies=[Depends(CheckUserInterfaceAuth('system:config:export'))]) +@configController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:config:export'))]) @log_decorator(title='参数管理', business_type=5) -async def export_system_config_list(request: Request, config_query: ConfigQueryModel, query_db: Session = Depends(get_db)): +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_query) + 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 streaming_response_200(data=bytes2file_response(config_export_result)) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@configController.post("/config/refresh", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:edit'))]) -@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 response_200(data=refresh_config_result, message=refresh_config_result.message) - else: - logger.warning(refresh_config_result.message) - return response_400(data="", message=refresh_config_result.message) + return ResponseUtil.streaming(data=bytes2file_response(config_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/dept_controller.py b/ruoyi-fastapi-backend/module_admin/controller/dept_controller.py similarity index 41% rename from ruoyi-fastapi/module_admin/controller/dept_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/dept_controller.py index b51aff61fe00d3efcd4d795dd63051786d05eff6..a39b7ad3a3e30b8808ded04084055bb574c76d23 100644 --- a/ruoyi-fastapi/module_admin/controller/dept_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/dept_controller.py @@ -1,10 +1,8 @@ from fastapi import APIRouter, Request from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +from module_admin.service.login_service import LoginService, CurrentUserModel from module_admin.service.dept_service import * -from module_admin.entity.vo.dept_vo import * -from module_admin.dao.dept_dao import * from utils.response_util import * from utils.log_util import * from module_admin.aspect.interface_auth import CheckUserInterfaceAuth @@ -12,102 +10,93 @@ from module_admin.aspect.data_scope import GetDataScope from module_admin.annotation.log_annotation import log_decorator -deptController = APIRouter(dependencies=[Depends(get_current_user)]) +deptController = APIRouter(prefix='/system/dept', dependencies=[Depends(LoginService.get_current_user)]) -@deptController.post("/dept/tree", response_model=DeptTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_dept_tree(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))): +@deptController.get("/list/exclude/{dept_id}", response_model=List[DeptModel], dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +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_result = DeptService.get_dept_tree_services(query_db, dept_query, data_scope_sql) + 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 response_200(data=dept_query_result, message="获取成功") + return ResponseUtil.success(data=dept_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@deptController.post("/dept/forEditOption", response_model=DeptTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_dept_tree_for_edit_option(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))): - try: - dept_query_result = DeptService.get_dept_tree_for_edit_option_services(query_db, dept_query, data_scope_sql) - logger.info('获取成功') - return response_200(data=dept_query_result, message="获取成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@deptController.post("/dept/get", response_model=DeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:list'))]) -async def get_system_dept_list(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))): +@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 response_200(data=dept_query_result, message="获取成功") + return ResponseUtil.success(data=dept_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@deptController.post("/dept/add", response_model=CrudDeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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 response_200(data=add_dept_result, message=add_dept_result.message) + return ResponseUtil.success(data=add_dept_result) else: logger.warning(add_dept_result.message) - return response_400(data="", message=add_dept_result.message) + return ResponseUtil.failure(msg=add_dept_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@deptController.patch("/dept/edit", response_model=CrudDeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_dept_result, message=edit_dept_result.message) + return ResponseUtil.success(msg=edit_dept_result.message) else: logger.warning(edit_dept_result.message) - return response_400(data="", message=edit_dept_result.message) + return ResponseUtil.failure(msg=edit_dept_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@deptController.post("/dept/delete", response_model=CrudDeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:remove'))]) +@deptController.delete("/{dept_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:dept:remove'))]) @log_decorator(title='部门管理', business_type=3) -async def delete_system_dept(request: Request, delete_dept: DeleteDeptModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=delete_dept_result, message=delete_dept_result.message) + return ResponseUtil.success(msg=delete_dept_result.message) else: logger.warning(delete_dept_result.message) - return response_400(data="", message=delete_dept_result.message) + return ResponseUtil.failure(msg=delete_dept_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@deptController.get("/dept/{dept_id}", response_model=DeptModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:query'))]) +@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.detail_dept_services(query_db, dept_id) + detail_dept_result = DeptService.dept_detail_services(query_db, dept_id) logger.info(f'获取dept_id为{dept_id}的信息成功') - return response_200(data=detail_dept_result, message='获取成功') + return ResponseUtil.success(data=detail_dept_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/dict_controller.py b/ruoyi-fastapi-backend/module_admin/controller/dict_controller.py similarity index 47% rename from ruoyi-fastapi/module_admin/controller/dict_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/dict_controller.py index 2f13de65c0079186c22519423d2b45de858c9ffa..51e61f464fc8cd60cc21a58e4c6b66c034ab0bb6 100644 --- a/ruoyi-fastapi/module_admin/controller/dict_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/dict_controller.py @@ -1,250 +1,233 @@ from fastapi import APIRouter from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import LoginService, CurrentUserInfoServiceResponse +from module_admin.service.login_service import LoginService, CurrentUserModel from module_admin.service.dict_service import * -from module_admin.entity.vo.dict_vo import * from utils.response_util import * from utils.log_util import * -from utils.page_util import get_page_obj +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_decorator -dictController = APIRouter(prefix='/dict', dependencies=[Depends(LoginService.get_current_user)]) +dictController = APIRouter(prefix='/system/dict', dependencies=[Depends(LoginService.get_current_user)]) -@dictController.get("/data/type/{dict_type}", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) -async def query_system_dict_type_data(request: Request, dict_type: str, query_db: Session = Depends(get_db)): +@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_data_query_result = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type) + # 获取分页数据 + 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(data=dict_data_query_result) + return ResponseUtil.success(model_content=dict_type_page_query_result) except Exception as e: logger.exception(e) return ResponseUtil.error(msg=str(e)) -@dictController.post("/dictType/get", response_model=DictTypePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) -async def get_system_dict_type_list(request: Request, dict_type_page_query: DictTypePageObject, query_db: Session = Depends(get_db)): - try: - dict_type_query = DictTypeQueryModel(**dict_type_page_query.dict()) - # 获取全量数据 - dict_type_query_result = DictTypeService.get_dict_type_list_services(query_db, dict_type_query) - # 分页操作 - dict_type_page_query_result = get_page_obj(dict_type_query_result, dict_type_page_query.page_num, dict_type_page_query.page_size) - logger.info('获取成功') - return response_200(data=dict_type_page_query_result, message="获取成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@dictController.post("/dictType/all", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) -async def get_system_all_dict_type(request: Request, dict_type_query: DictTypeQueryModel, query_db: Session = Depends(get_db)): - try: - dict_type_query_result = DictTypeService.get_all_dict_type_services(query_db) - logger.info('获取成功') - return response_200(data=dict_type_query_result, message="获取成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@dictController.post("/dictType/add", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(LoginService.get_current_user)): +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 response_200(data=add_dict_type_result, message=add_dict_type_result.message) + return ResponseUtil.success(msg=add_dict_type_result.message) else: logger.warning(add_dict_type_result.message) - return response_400(data="", message=add_dict_type_result.message) + return ResponseUtil.failure(msg=add_dict_type_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.patch("/dictType/edit", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(LoginService.get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_dict_type_result, message=edit_dict_type_result.message) + return ResponseUtil.success(msg=edit_dict_type_result.message) else: logger.warning(edit_dict_type_result.message) - return response_400(data="", message=edit_dict_type_result.message) + return ResponseUtil.failure(msg=edit_dict_type_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.post("/dictType/delete", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))]) +@dictController.delete("/type/refreshCache", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))]) +@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/{dict_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))]) @log_decorator(title='字典管理', business_type=3) -async def delete_system_dict_type(request: Request, delete_dict_type: DeleteDictTypeModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_dict_type_result, message=delete_dict_type_result.message) + return ResponseUtil.success(msg=delete_dict_type_result.message) else: logger.warning(delete_dict_type_result.message) - return response_400(data="", message=delete_dict_type_result.message) + return ResponseUtil.failure(msg=delete_dict_type_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.get("/dictType/{dict_id}", response_model=DictTypeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))]) +@dictController.get("/type/optionselect", response_model=List[DictTypeModel], dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))]) +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/{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: - detail_dict_type_result = DictTypeService.detail_dict_type_services(query_db, dict_id) + dict_type_detail_result = DictTypeService.dict_type_detail_services(query_db, dict_id) logger.info(f'获取dict_id为{dict_id}的信息成功') - return response_200(data=detail_dict_type_result, message='获取成功') + return ResponseUtil.success(data=dict_type_detail_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.post("/dictType/export", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))]) +@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_query: DictTypeQueryModel, query_db: Session = Depends(get_db)): +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_query) + 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 streaming_response_200(data=bytes2file_response(dict_type_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(dict_type_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) - - -@dictController.post("/dictType/refresh", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))]) -@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 response_200(data=refresh_dict_result, message=refresh_dict_result.message) - else: - logger.warning(refresh_dict_result.message) - return response_400(data="", message=refresh_dict_result.message) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.post("/dictData/get", response_model=DictDataPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) -async def get_system_dict_data_list(request: Request, dict_data_page_query: DictDataPageObject, query_db: Session = Depends(get_db)): +@dictController.get("/data/type/{dict_type}", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) +async def query_system_dict_type_data(request: Request, dict_type: str, query_db: Session = Depends(get_db)): try: - dict_data_query = DictDataModel(**dict_data_page_query.dict()) # 获取全量数据 - dict_data_query_result = DictDataService.get_dict_data_list_services(query_db, dict_data_query) - # 分页操作 - dict_data_page_query_result = get_page_obj(dict_data_query_result, dict_data_page_query.page_num, dict_data_page_query.page_size) + dict_data_query_result = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type) logger.info('获取成功') - return response_200(data=dict_data_page_query_result, message="获取成功") + return ResponseUtil.success(data=dict_data_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.get("/dictData/query/{dict_type}", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) -async def query_system_dict_data_list(request: Request, dict_type: str, query_db: Session = Depends(get_db)): +@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_query_result = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type) + # 获取分页数据 + dict_data_page_query_result = DictDataService.get_dict_data_list_services(query_db, dict_data_page_query, is_page=True) logger.info('获取成功') - return response_200(data=dict_data_query_result, message="获取成功") + return ResponseUtil.success(model_content=dict_data_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.post("/dictData/add", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(LoginService.get_current_user)): +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 response_200(data=add_dict_data_result, message=add_dict_data_result.message) + return ResponseUtil.success(msg=add_dict_data_result.message) else: logger.warning(add_dict_data_result.message) - return response_400(data="", message=add_dict_data_result.message) + return ResponseUtil.failure(msg=add_dict_data_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.patch("/dictData/edit", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(LoginService.get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_dict_data_result, message=edit_dict_data_result.message) + return ResponseUtil.success(msg=edit_dict_data_result.message) else: logger.warning(edit_dict_data_result.message) - return response_400(data="", message=edit_dict_data_result.message) + return ResponseUtil.failure(msg=edit_dict_data_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.post("/dictData/delete", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))]) +@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, delete_dict_data: DeleteDictDataModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_dict_data_result, message=delete_dict_data_result.message) + return ResponseUtil.success(msg=delete_dict_data_result.message) else: logger.warning(delete_dict_data_result.message) - return response_400(data="", message=delete_dict_data_result.message) + return ResponseUtil.failure(msg=delete_dict_data_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.get("/dictData/{dict_code}", response_model=DictDataModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))]) +@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.detail_dict_data_services(query_db, dict_code) + detail_dict_data_result = DictDataService.dict_data_detail_services(query_db, dict_code) logger.info(f'获取dict_code为{dict_code}的信息成功') - return response_200(data=detail_dict_data_result, message='获取成功') + return ResponseUtil.success(data=detail_dict_data_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@dictController.post("/dictData/export", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))]) +@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_query: DictDataModel, query_db: Session = Depends(get_db)): +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_query) + 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 streaming_response_200(data=bytes2file_response(dict_data_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(dict_data_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/job_controller.py b/ruoyi-fastapi-backend/module_admin/controller/job_controller.py similarity index 45% rename from ruoyi-fastapi/module_admin/controller/job_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/job_controller.py index adf7ec54c0c27057b2c0ece672cbe9d09c33ebb2..508dd2c368f14838606d27ab96b5e11e79d83a43 100644 --- a/ruoyi-fastapi/module_admin/controller/job_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/job_controller.py @@ -1,196 +1,199 @@ from fastapi import APIRouter from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +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 module_admin.entity.vo.job_vo import * from utils.response_util import * from utils.log_util import * -from utils.page_util import get_page_obj +from utils.page_util import * from utils.common_util import bytes2file_response from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.annotation.log_annotation import log_decorator -jobController = APIRouter(dependencies=[Depends(get_current_user)]) +jobController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)]) -@jobController.post("/job/get", response_model=JobPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) -async def get_system_job_list(request: Request, job_page_query: JobPageObject, query_db: Session = Depends(get_db)): +@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: - job_query = JobModel(**job_page_query.dict()) - # 获取全量数据 - job_query_result = JobService.get_job_list_services(query_db, job_query) - # 分页操作 - notice_page_query_result = get_page_obj(job_query_result, job_page_query.page_num, job_page_query.page_size) + # 获取分页数据 + notice_page_query_result = JobService.get_job_list_services(query_db, job_page_query, is_page=True) logger.info('获取成功') - return response_200(data=notice_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=notice_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@jobController.post("/job/add", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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 response_200(data=add_job_result, message=add_job_result.message) + return ResponseUtil.success(msg=add_job_result.message) else: logger.warning(add_job_result.message) - return response_400(data="", message=add_job_result.message) + return ResponseUtil.failure(msg=add_job_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@jobController.patch("/job/edit", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_job_result, message=edit_job_result.message) + return ResponseUtil.success(msg=edit_job_result.message) else: logger.warning(edit_job_result.message) - return response_400(data="", message=edit_job_result.message) + return ResponseUtil.failure(msg=edit_job_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@jobController.post("/job/changeStatus", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))]) +@jobController.put("/job/changeStatus", 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.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/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 response_200(data=execute_job_result, message=execute_job_result.message) + return ResponseUtil.success(msg=execute_job_result.message) else: logger.warning(execute_job_result.message) - return response_400(data="", message=execute_job_result.message) + return ResponseUtil.failure(msg=execute_job_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@jobController.post("/job/delete", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) +@jobController.delete("/job/{job_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) @log_decorator(title='定时任务管理', business_type=3) -async def delete_system_job(request: Request, delete_job: DeleteJobModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_job_result, message=delete_job_result.message) + return ResponseUtil.success(msg=delete_job_result.message) else: logger.warning(delete_job_result.message) - return response_400(data="", message=delete_job_result.message) + return ResponseUtil.failure(msg=delete_job_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(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: Session = Depends(get_db)): try: - detail_job_result = JobService.detail_job_services(query_db, job_id) + job_detail_result = JobService.job_detail_services(query_db, job_id) logger.info(f'获取job_id为{job_id}的信息成功') - return response_200(data=detail_job_result, message='获取成功') + return ResponseUtil.success(data=job_detail_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) @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_query: JobModel, query_db: Session = Depends(get_db)): +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_query) + 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 streaming_response_200(data=bytes2file_response(job_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(job_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@jobController.post("/jobLog/get", response_model=JobLogPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) -async def get_system_job_log_list(request: Request, job_log_page_query: JobLogPageObject, query_db: Session = Depends(get_db)): +@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_query = JobLogQueryModel(**job_log_page_query.dict()) - # 获取全量数据 - job_log_query_result = JobLogService.get_job_log_list_services(query_db, job_log_query) - # 分页操作 - notice_page_query_result = get_page_obj(job_log_query_result, job_log_page_query.page_num, job_log_page_query.page_size) + # 获取分页数据 + job_log_page_query_result = JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=True) logger.info('获取成功') - return response_200(data=notice_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=job_log_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@jobController.post("/jobLog/delete", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) +@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, delete_job_log: DeleteJobLogModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_job_log_result, message=delete_job_log_result.message) + return ResponseUtil.success(msg=delete_job_log_result.message) else: logger.warning(delete_job_log_result.message) - return response_400(data="", message=delete_job_log_result.message) + return ResponseUtil.failure(msg=delete_job_log_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@jobController.post("/jobLog/clear", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) +@jobController.post("/jobLog/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) @log_decorator(title='定时任务日志管理', business_type=9) -async def clear_system_job_log(request: Request, clear_job_log: ClearJobLogModel, query_db: Session = Depends(get_db)): +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, clear_job_log) + 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 response_200(data=clear_job_log_result, message=clear_job_log_result.message) + return ResponseUtil.success(msg=clear_job_log_result.message) else: logger.warning(clear_job_log_result.message) - return response_400(data="", message=clear_job_log_result.message) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@jobController.get("/jobLog/{job_log_id}", response_model=JobLogModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))]) -async def query_detail_system_job_log(request: Request, job_log_id: int, query_db: Session = Depends(get_db)): - try: - detail_job_log_result = JobLogService.detail_job_log_services(query_db, job_log_id) - logger.info(f'获取job_log_id为{job_log_id}的信息成功') - return response_200(data=detail_job_log_result, message='获取成功') + return ResponseUtil.failure(msg=clear_job_log_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) @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_query: JobLogQueryModel, query_db: Session = Depends(get_db)): +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_query) - job_log_export_result = JobLogService.export_job_log_list_services(query_db, job_log_query_result) + 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 streaming_response_200(data=bytes2file_response(job_log_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/log_controller.py b/ruoyi-fastapi-backend/module_admin/controller/log_controller.py similarity index 39% rename from ruoyi-fastapi/module_admin/controller/log_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/log_controller.py index 3e7175c29dd1ce07989751641964376f52f9423c..095ca5ea9bf95f3a98a4df92b1f1d537906909c8 100644 --- a/ruoyi-fastapi/module_admin/controller/log_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/log_controller.py @@ -1,164 +1,149 @@ from fastapi import APIRouter from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user +from module_admin.service.login_service import LoginService from module_admin.service.log_service import * -from module_admin.entity.vo.log_vo import * from utils.response_util import * from utils.log_util import * -from utils.page_util import get_page_obj +from utils.page_util import * from utils.common_util import bytes2file_response from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.annotation.log_annotation import log_decorator -logController = APIRouter(prefix='/log', dependencies=[Depends(get_current_user)]) +logController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)]) -@logController.post("/operation/get", response_model=OperLogPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:list'))]) -async def get_system_operation_log_list(request: Request, operation_log_page_query: OperLogPageObject, query_db: Session = Depends(get_db)): +@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_query = OperLogQueryModel(**operation_log_page_query.dict()) - # 获取全量数据 - operation_log_query_result = OperationLogService.get_operation_log_list_services(query_db, operation_log_query) - # 分页操作 - operation_log_page_query_result = get_page_obj(operation_log_query_result, operation_log_page_query.page_num, operation_log_page_query.page_size) + # 获取分页数据 + operation_log_page_query_result = OperationLogService.get_operation_log_list_services(query_db, operation_log_page_query, is_page=True) logger.info('获取成功') - return response_200(data=operation_log_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=operation_log_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@logController.post("/operation/delete", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))]) -@log_decorator(title='操作日志管理', business_type=3) -async def delete_system_operation_log(request: Request, delete_operation_log: DeleteOperLogModel, query_db: Session = Depends(get_db)): - try: - 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 response_200(data=delete_operation_log_result, message=delete_operation_log_result.message) - else: - logger.warning(delete_operation_log_result.message) - return response_400(data="", message=delete_operation_log_result.message) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@logController.post("/operation/clear", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))]) +@logController.delete("/operlog/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))]) @log_decorator(title='操作日志管理', business_type=9) -async def clear_system_operation_log(request: Request, clear_operation_log: ClearOperLogModel, query_db: Session = Depends(get_db)): +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, clear_operation_log) + 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 response_200(data=clear_operation_log_result, message=clear_operation_log_result.message) + return ResponseUtil.success(msg=clear_operation_log_result.message) else: logger.warning(clear_operation_log_result.message) - return response_400(data="", message=clear_operation_log_result.message) + return ResponseUtil.failure(msg=clear_operation_log_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@logController.get("/operation/{oper_id}", response_model=OperLogModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:query'))]) -async def query_detail_system_operation_log(request: Request, oper_id: int, query_db: Session = Depends(get_db)): +@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: - detail_operation_log_result = OperationLogService.detail_operation_log_services(query_db, oper_id) - logger.info(f'获取oper_id为{oper_id}的信息成功') - return response_200(data=detail_operation_log_result, message='获取成功') + 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 response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@logController.post("/operation/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:export'))]) +@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_query: OperLogQueryModel, query_db: Session = Depends(get_db)): +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_query) + 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 streaming_response_200(data=bytes2file_response(operation_log_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(operation_log_export_result)) except Exception as e: logger.exception(e) return response_500(data="", message=str(e)) -@logController.post("/login/get", response_model=LoginLogPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:list'))]) -async def get_system_login_log_list(request: Request, login_log_page_query: LoginLogPageObject, query_db: Session = Depends(get_db)): +@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_query = LoginLogQueryModel(**login_log_page_query.dict()) - # 获取全量数据 - login_log_query_result = LoginLogService.get_login_log_list_services(query_db, login_log_query) - # 分页操作 - login_log_page_query_result = get_page_obj(login_log_query_result, login_log_page_query.page_num, login_log_page_query.page_size) + # 获取分页数据 + login_log_page_query_result = LoginLogService.get_login_log_list_services(query_db, login_log_page_query, is_page=True) logger.info('获取成功') - return response_200(data=login_log_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=login_log_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@logController.post("/login/delete", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))]) -@log_decorator(title='登录日志管理', business_type=3) -async def delete_system_login_log(request: Request, delete_login_log: DeleteLoginLogModel, query_db: Session = Depends(get_db)): +@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: - 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 response_200(data=delete_login_log_result, message=delete_login_log_result.message) + 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(delete_login_log_result.message) - return response_400(data="", message=delete_login_log_result.message) + logger.warning(clear_login_log_result.message) + return ResponseUtil.failure(msg=clear_login_log_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@logController.post("/login/clear", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))]) -@log_decorator(title='登录日志管理', business_type=9) -async def clear_system_login_log(request: Request, clear_login_log: ClearLoginLogModel, query_db: Session = Depends(get_db)): +@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: - clear_login_log_result = LoginLogService.clear_login_log_services(query_db, clear_login_log) - if clear_login_log_result.is_success: - logger.info(clear_login_log_result.message) - return response_200(data=clear_login_log_result, message=clear_login_log_result.message) + 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(clear_login_log_result.message) - return response_400(data="", message=clear_login_log_result.message) + logger.warning(delete_login_log_result.message) + return ResponseUtil.failure(msg=delete_login_log_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@logController.post("/login/unlock", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:unlock'))]) +@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, unlock_user: UnlockUser, query_db: Session = Depends(get_db)): +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 response_200(data=unlock_user_result, message=unlock_user_result.message) + return ResponseUtil.success(msg=unlock_user_result.message) else: logger.warning(unlock_user_result.message) - return response_400(data="", message=unlock_user_result.message) + return ResponseUtil.failure(msg=unlock_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@logController.post("/login/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:export'))]) +@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_query: LoginLogQueryModel, query_db: Session = Depends(get_db)): +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_query) + 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 streaming_response_200(data=bytes2file_response(login_log_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(login_log_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/login_controller.py b/ruoyi-fastapi-backend/module_admin/controller/login_controller.py similarity index 61% rename from ruoyi-fastapi/module_admin/controller/login_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/login_controller.py index d89dcf19094cb538b5b05e2dccb57851aec088e8..a036862a4dbba5406fe8f4f1a970e99bdbad5114 100644 --- a/ruoyi-fastapi/module_admin/controller/login_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/login_controller.py @@ -2,11 +2,10 @@ 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 -from utils.response_util import * +from utils.response_util import ResponseUtil from utils.log_util import * -from module_admin.aspect.interface_auth import CheckUserInterfaceAuth -from module_admin.annotation.log_annotation import log_decorator from datetime import timedelta @@ -30,7 +29,7 @@ async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = D except LoginException as e: return ResponseUtil.failure(msg=e.message) try: - access_token_expires = timedelta(minutes=JwtConfig.ACCESS_TOKEN_EXPIRE_MINUTES) + access_token_expires = timedelta(minutes=JwtConfig.jwt_expire_minutes) session_id = str(uuid.uuid4()) access_token = LoginService.create_access_token( data={ @@ -43,10 +42,11 @@ async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = D expires_delta=access_token_expires ) await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", access_token, - ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) + ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes)) # 此方法可实现同一账号同一时间只能登录一次 # await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{result[0].user_id}", access_token, - # ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) + # 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 @@ -62,7 +62,7 @@ async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = D return ResponseUtil.error(msg=str(e)) -@loginController.get("/getInfo", response_model=CurrentUserModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@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('获取成功') @@ -72,7 +72,7 @@ async def get_login_user_info(request: Request, current_user: CurrentUserModel = return ResponseUtil.error(msg=str(e)) -@loginController.get("/getRouters", dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@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('获取成功') @@ -83,52 +83,57 @@ async def get_login_user_routers(request: Request, current_user: CurrentUserMode return ResponseUtil.error(msg=str(e)) -@loginController.post("/getSmsCode", response_model=SmsCode) -async def get_sms_code(request: Request, user: ResetUserModel, query_db: Session = Depends(get_db)): +@loginController.post("/register", response_model=CrudResponseModel) +async def register_user(request: Request, user_register: UserRegister, query_db: Session = Depends(get_db)): try: - sms_result = await get_sms_code_services(request, query_db, user) - if sms_result.is_success: - logger.info('获取成功') - return response_200(data=sms_result, message='获取成功') + 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(sms_result.message) - return response_400(data='', message=sms_result.message) + logger.warning(user_register_result.message) + return ResponseUtil.failure(msg=user_register_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) - - -@loginController.post("/forgetPwd", response_model=CrudUserResponse) -async def forget_user_pwd(request: Request, forget_user: ResetUserModel, query_db: Session = Depends(get_db)): - try: - forget_user_result = await forget_user_services(request, query_db, forget_user) - if forget_user_result.is_success: - logger.info(forget_user_result.message) - return response_200(data=forget_user_result, message=forget_user_result.message) - else: - logger.warning(forget_user_result.message) - return response_400(data="", message=forget_user_result.message) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@loginController.post("/getLoginUserInfo", response_model=CurrentUserInfoServiceResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_login_user_info(request: Request, current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): - try: - logger.info('获取成功') - return response_200(data=current_user, message="获取成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) +# @loginController.post("/getSmsCode", response_model=SmsCode) +# async def get_sms_code(request: Request, user: ResetUserModel, query_db: Session = Depends(get_db)): +# try: +# sms_result = await LoginService.get_sms_code_services(request, query_db, user) +# if sms_result.is_success: +# logger.info('获取成功') +# return ResponseUtil.success(data=sms_result) +# else: +# logger.warning(sms_result.message) +# return ResponseUtil.failure(msg=sms_result.message) +# except Exception as e: +# logger.exception(e) +# return ResponseUtil.error(msg=str(e)) +# +# +# @loginController.post("/forgetPwd", response_model=CrudResponseModel) +# async def forget_user_pwd(request: Request, forget_user: ResetUserModel, query_db: Session = Depends(get_db)): +# try: +# forget_user_result = await LoginService.forget_user_services(request, query_db, forget_user) +# if forget_user_result.is_success: +# logger.info(forget_user_result.message) +# return ResponseUtil.success(data=forget_user_result, msg=forget_user_result.message) +# else: +# logger.warning(forget_user_result.message) +# return ResponseUtil.failure(msg=forget_user_result.message) +# except Exception as e: +# logger.exception(e) +# return ResponseUtil.error(msg=str(e)) @loginController.post("/logout") async def logout(request: Request, token: Optional[str] = Depends(oauth2_scheme)): try: - payload = jwt.decode(token, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM]) + payload = jwt.decode(token, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm]) session_id: str = payload.get("session_id") - await logout_services(request, session_id) + await LoginService.logout_services(request, session_id) logger.info('退出成功') return ResponseUtil.success(msg="退出成功") except Exception as e: diff --git a/ruoyi-fastapi/module_admin/controller/menu_controller.py b/ruoyi-fastapi-backend/module_admin/controller/menu_controller.py similarity index 43% rename from ruoyi-fastapi/module_admin/controller/menu_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/menu_controller.py index 51c13220c47b5099fb7f93c54f4b42023b29f21d..79663fa47a79dfab1080047a82de7085cf96b154 100644 --- a/ruoyi-fastapi/module_admin/controller/menu_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/menu_controller.py @@ -1,110 +1,109 @@ from fastapi import APIRouter, Request from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user +from module_admin.service.login_service import LoginService from module_admin.service.menu_service import * -from module_admin.entity.vo.menu_vo import * -from module_admin.dao.menu_dao 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_decorator -menuController = APIRouter(dependencies=[Depends(get_current_user)]) +menuController = APIRouter(prefix='/system/menu', dependencies=[Depends(LoginService.get_current_user)]) -@menuController.post("/menu/tree", response_model=MenuTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_menu_tree(request: Request, menu_query: MenuTreeModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): +@menuController.get("/treeselect", dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +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, menu_query, current_user) + menu_query_result = MenuService.get_menu_tree_services(query_db, current_user) logger.info('获取成功') - return response_200(data=menu_query_result, message="获取成功") + return ResponseUtil.success(data=menu_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@menuController.post("/menu/forEditOption", response_model=MenuTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_menu_tree_for_edit_option(request: Request, menu_query: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): +@menuController.get("/roleMenuTreeselect/{role_id}", dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +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: - menu_query_result = MenuService.get_menu_tree_for_edit_option_services(query_db, menu_query, current_user) + role_menu_query_result = MenuService.get_role_menu_tree_services(query_db, role_id, current_user) logger.info('获取成功') - return response_200(data=menu_query_result, message="获取成功") + return ResponseUtil.success(model_content=role_menu_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@menuController.post("/menu/get", response_model=MenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:list'))]) -async def get_system_menu_list(request: Request, menu_query: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): +@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 response_200(data=menu_query_result, message="获取成功") + return ResponseUtil.success(data=menu_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@menuController.post("/menu/add", response_model=CrudMenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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 response_200(data=add_menu_result, message=add_menu_result.message) + return ResponseUtil.success(msg=add_menu_result.message) else: logger.warning(add_menu_result.message) - return response_400(data="", message=add_menu_result.message) + return ResponseUtil.failure(msg=add_menu_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@menuController.patch("/menu/edit", response_model=CrudMenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_menu_result, message=edit_menu_result.message) + return ResponseUtil.success(msg=edit_menu_result.message) else: logger.warning(edit_menu_result.message) - return response_400(data="", message=edit_menu_result.message) + return ResponseUtil.failure(msg=edit_menu_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@menuController.post("/menu/delete", response_model=CrudMenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:remove'))]) +@menuController.delete("/{menu_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:menu:remove'))]) @log_decorator(title='菜单管理', business_type=3) -async def delete_system_menu(request: Request, delete_menu: DeleteMenuModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_menu_result, message=delete_menu_result.message) + return ResponseUtil.success(msg=delete_menu_result.message) else: logger.warning(delete_menu_result.message) - return response_400(data="", message=delete_menu_result.message) + return ResponseUtil.failure(msg=delete_menu_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@menuController.get("/menu/{menu_id}", response_model=MenuModel, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:query'))]) +@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: - detail_menu_result = MenuService.detail_menu_services(query_db, menu_id) + menu_detail_result = MenuService.menu_detail_services(query_db, menu_id) logger.info(f'获取menu_id为{menu_id}的信息成功') - return response_200(data=detail_menu_result, message='获取成功') + return ResponseUtil.success(data=menu_detail_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/notice_controller.py b/ruoyi-fastapi-backend/module_admin/controller/notice_controller.py similarity index 46% rename from ruoyi-fastapi/module_admin/controller/notice_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/notice_controller.py index cbda2de2fd2baba1e2ea0ae4113b8fed5970b363..4caaa7a680a4cacc1e4246ee46a0c648c2c93ae2 100644 --- a/ruoyi-fastapi/module_admin/controller/notice_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/notice_controller.py @@ -1,92 +1,89 @@ from fastapi import APIRouter, Request from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +from module_admin.service.login_service import LoginService, CurrentUserModel from module_admin.service.notice_service import * -from module_admin.entity.vo.notice_vo import * from utils.response_util import * from utils.log_util import * -from utils.page_util import get_page_obj +from utils.page_util import * from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.annotation.log_annotation import log_decorator -noticeController = APIRouter(dependencies=[Depends(get_current_user)]) +noticeController = APIRouter(prefix='/system/notice', dependencies=[Depends(LoginService.get_current_user)]) -@noticeController.post("/notice/get", response_model=NoticePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:list'))]) -async def get_system_notice_list(request: Request, notice_page_query: NoticePageObject, query_db: Session = Depends(get_db)): +@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_query = NoticeQueryModel(**notice_page_query.dict()) - # 获取全量数据 - notice_query_result = NoticeService.get_notice_list_services(query_db, notice_query) - # 分页操作 - notice_page_query_result = get_page_obj(notice_query_result, notice_page_query.page_num, notice_page_query.page_size) + # 获取分页数据 + notice_page_query_result = NoticeService.get_notice_list_services(query_db, notice_page_query, is_page=True) logger.info('获取成功') - return response_200(data=notice_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=notice_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@noticeController.post("/notice/add", response_model=CrudNoticeResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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 response_200(data=add_notice_result, message=add_notice_result.message) + return ResponseUtil.success(msg=add_notice_result.message) else: logger.warning(add_notice_result.message) - return response_400(data="", message=add_notice_result.message) + return ResponseUtil.failure(msg=add_notice_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@noticeController.patch("/notice/edit", response_model=CrudNoticeResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_notice_result, message=edit_notice_result.message) + return ResponseUtil.success(msg=edit_notice_result.message) else: logger.warning(edit_notice_result.message) - return response_400(data="", message=edit_notice_result.message) + return ResponseUtil.failure(msg=edit_notice_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@noticeController.post("/notice/delete", response_model=CrudNoticeResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:remove'))]) +@noticeController.delete("/{notice_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:notice:remove'))]) @log_decorator(title='通知公告管理', business_type=3) -async def delete_system_notice(request: Request, delete_notice: DeleteNoticeModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_notice_result, message=delete_notice_result.message) + return ResponseUtil.success(msg=delete_notice_result.message) else: logger.warning(delete_notice_result.message) - return response_400(data="", message=delete_notice_result.message) + return ResponseUtil.failure(msg=delete_notice_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@noticeController.get("/notice/{notice_id}", response_model=NoticeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:query'))]) +@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: - detail_notice_result = NoticeService.detail_notice_services(query_db, notice_id) + notice_detail_result = NoticeService.notice_detail_services(query_db, notice_id) logger.info(f'获取notice_id为{notice_id}的信息成功') - return response_200(data=detail_notice_result, message='获取成功') + return ResponseUtil.success(data=notice_detail_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/online_controller.py b/ruoyi-fastapi-backend/module_admin/controller/online_controller.py similarity index 33% rename from ruoyi-fastapi/module_admin/controller/online_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/online_controller.py index 9390c8b0e15e12cfc88fe10047a72b41b0fe4276..cecee5f358bfa554fb9ac8eacca292ed24faf427 100644 --- a/ruoyi-fastapi/module_admin/controller/online_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/online_controller.py @@ -1,59 +1,42 @@ from fastapi import APIRouter from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user, Session +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 get_page_obj +from utils.page_util import * from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.annotation.log_annotation import log_decorator -onlineController = APIRouter(prefix='/online', dependencies=[Depends(get_current_user)]) +onlineController = APIRouter(prefix='/monitor/online', dependencies=[Depends(LoginService.get_current_user)]) -@onlineController.post("/get", response_model=OnlinePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:list'))]) -async def get_monitor_online_list(request: Request, online_page_query: OnlinePageObject): +@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) - # 分页操作 - online_page_query_result = get_page_obj(online_query_result, online_page_query.page_num, online_page_query.page_size) logger.info('获取成功') - return response_200(data=online_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=PageResponseModel(rows=online_query_result, total=len(online_query_result))) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@onlineController.post("/forceLogout", response_model=CrudOnlineResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:forceLogout'))]) +@onlineController.delete("/{token_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:forceLogout'))]) @log_decorator(title='在线用户', business_type=7) -async def delete_monitor_online(request: Request, delete_online: DeleteOnlineModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_online_result, message=delete_online_result.message) + return ResponseUtil.success(msg=delete_online_result.message) else: logger.warning(delete_online_result.message) - return response_400(data="", message=delete_online_result.message) + return ResponseUtil.failure(msg=delete_online_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) - - -@onlineController.post("/batchLogout", response_model=CrudOnlineResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:batchLogout'))]) -@log_decorator(title='在线用户', business_type=7) -async def delete_monitor_online(request: Request, delete_online: DeleteOnlineModel, query_db: Session = Depends(get_db)): - try: - delete_online_result = await OnlineService.delete_online_services(request, delete_online) - if delete_online_result.is_success: - logger.info(delete_online_result.message) - return response_200(data=delete_online_result, message=delete_online_result.message) - else: - logger.warning(delete_online_result.message) - return response_400(data="", message=delete_online_result.message) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/post_controler.py b/ruoyi-fastapi-backend/module_admin/controller/post_controler.py similarity index 43% rename from ruoyi-fastapi/module_admin/controller/post_controler.py rename to ruoyi-fastapi-backend/module_admin/controller/post_controler.py index e917826c67b3be0df04844c95203a14d4805a975..ebf41ea78e393355c7b57bb7c3aa7b65fe60a4c5 100644 --- a/ruoyi-fastapi/module_admin/controller/post_controler.py +++ b/ruoyi-fastapi-backend/module_admin/controller/post_controler.py @@ -1,118 +1,105 @@ from fastapi import APIRouter, Request from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +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 get_page_obj +from utils.page_util import * from utils.common_util import bytes2file_response from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.annotation.log_annotation import log_decorator -postController = APIRouter(dependencies=[Depends(get_current_user)]) +postController = APIRouter(prefix='/system/post', dependencies=[Depends(LoginService.get_current_user)]) -@postController.post("/post/forSelectOption", response_model=PostSelectOptionResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_post_select(request: Request, query_db: Session = Depends(get_db)): +@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: - role_query_result = PostService.get_post_select_option_services(query_db) + # 获取分页数据 + post_page_query_result = PostService.get_post_list_services(query_db, post_page_query, is_page=True) logger.info('获取成功') - return response_200(data=role_query_result, message="获取成功") + return ResponseUtil.success(model_content=post_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@postController.post("/post/get", response_model=PostPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:list'))]) -async def get_system_post_list(request: Request, post_page_query: PostPageObject, query_db: Session = Depends(get_db)): - try: - post_query = PostModel(**post_page_query.dict()) - # 获取全量数据 - post_query_result = PostService.get_post_list_services(query_db, post_query) - # 分页操作 - post_page_query_result = get_page_obj(post_query_result, post_page_query.page_num, post_page_query.page_size) - logger.info('获取成功') - return response_200(data=post_page_query_result, message="获取成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@postController.post("/post/add", response_model=CrudPostResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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 response_200(data=add_post_result, message=add_post_result.message) + return ResponseUtil.success(msg=add_post_result.message) else: logger.warning(add_post_result.message) - return response_400(data="", message=add_post_result.message) + return ResponseUtil.failure(msg=add_post_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@postController.patch("/post/edit", response_model=CrudPostResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_post_result, message=edit_post_result.message) + return ResponseUtil.success(msg=edit_post_result.message) else: logger.warning(edit_post_result.message) - return response_400(data="", message=edit_post_result.message) + return ResponseUtil.failure(msg=edit_post_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@postController.post("/post/delete", response_model=CrudPostResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:remove'))]) +@postController.delete("/{post_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:post:remove'))]) @log_decorator(title='岗位管理', business_type=3) -async def delete_system_post(request: Request, delete_post: DeletePostModel, query_db: Session = Depends(get_db)): +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 response_200(data=delete_post_result, message=delete_post_result.message) + return ResponseUtil.success(msg=delete_post_result.message) else: logger.warning(delete_post_result.message) - return response_400(data="", message=delete_post_result.message) + return ResponseUtil.failure(msg=delete_post_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@postController.get("/post/{post_id}", response_model=PostModel, dependencies=[Depends(CheckUserInterfaceAuth('system:post:query'))]) +@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: - detail_post_result = PostService.detail_post_services(query_db, post_id) + post_detail_result = PostService.post_detail_services(query_db, post_id) logger.info(f'获取post_id为{post_id}的信息成功') - return response_200(data=detail_post_result, message='获取成功') + return ResponseUtil.success(data=post_detail_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@postController.post("/post/export", dependencies=[Depends(CheckUserInterfaceAuth('system:post:export'))]) +@postController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:post:export'))]) @log_decorator(title='岗位管理', business_type=5) -async def export_system_post_list(request: Request, post_query: PostModel, query_db: Session = Depends(get_db)): +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_query) + 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 streaming_response_200(data=bytes2file_response(post_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(post_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/role_controller.py b/ruoyi-fastapi-backend/module_admin/controller/role_controller.py similarity index 35% rename from ruoyi-fastapi/module_admin/controller/role_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/role_controller.py index 55e68fdc6994c814dfd03b97bdc87a065fefc348..d99096e9fd373c4d618b5024aa1cb180717ddbb3 100644 --- a/ruoyi-fastapi/module_admin/controller/role_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/role_controller.py @@ -1,198 +1,230 @@ from fastapi import APIRouter, Request from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +from module_admin.service.login_service import LoginService, CurrentUserModel from module_admin.service.role_service import * -from module_admin.service.user_service import UserService, UserRoleQueryModel, UserRolePageObject, UserRolePageObjectResponse, CrudUserRoleModel -from module_admin.entity.vo.role_vo 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 get_page_obj +from utils.page_util import PageResponseModel from utils.common_util import bytes2file_response from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.aspect.data_scope import GetDataScope from module_admin.annotation.log_annotation import log_decorator -roleController = APIRouter(dependencies=[Depends(get_current_user)]) +roleController = APIRouter(prefix='/system/role', dependencies=[Depends(LoginService.get_current_user)]) -@roleController.post("/role/forSelectOption", response_model=RoleSelectOptionResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_role_select(request: Request, query_db: Session = Depends(get_db)): +@roleController.get("/deptTree/{role_id}", dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +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: - role_query_result = RoleService.get_role_select_option_services(query_db) + 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 response_200(data=role_query_result, message="获取成功") + return ResponseUtil.success(model_content=role_dept_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/get", response_model=RolePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))]) -async def get_system_role_list(request: Request, role_page_query: RolePageObject, query_db: Session = Depends(get_db)): +@roleController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))]) +async def get_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_query), query_db: Session = Depends(get_db)): try: - role_query = RoleQueryModel(**role_page_query.dict()) - role_query_result = RoleService.get_role_list_services(query_db, role_query) - # 分页操作 - role_page_query_result = get_page_obj(role_query_result, role_page_query.page_num, role_page_query.page_size) + role_page_query_result = RoleService.get_role_list_services(query_db, role_page_query, is_page=True) logger.info('获取成功') - return response_200(data=role_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=role_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/add", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:add'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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 response_200(data=add_role_result, message=add_role_result.message) + return ResponseUtil.success(msg=add_role_result.message) else: logger.warning(add_role_result.message) - return response_400(data="", message=add_role_result.message) + return ResponseUtil.failure(msg=add_role_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.patch("/role/edit", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))]) +@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: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_role_result, message=edit_role_result.message) + return ResponseUtil.success(msg=edit_role_result.message) else: logger.warning(edit_role_result.message) - return response_400(data="", message=edit_role_result.message) + return ResponseUtil.failure(msg=edit_role_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.patch("/role/dataScope", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))]) +@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: RoleDataScopeModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=role_data_scope_result, message=role_data_scope_result.message) + return ResponseUtil.success(msg=role_data_scope_result.message) else: logger.warning(role_data_scope_result.message) - return response_400(data="", message=role_data_scope_result.message) + return ResponseUtil.failure(msg=role_data_scope_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/delete", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:remove'))]) +@roleController.delete("/{role_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:role:remove'))]) @log_decorator(title='角色管理', business_type=3) -async def delete_system_role(request: Request, delete_role: DeleteRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): +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.update_by = current_user.user.user_name - delete_role.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=delete_role_result, message=delete_role_result.message) + return ResponseUtil.success(msg=delete_role_result.message) else: logger.warning(delete_role_result.message) - return response_400(data="", message=delete_role_result.message) + return ResponseUtil.failure(msg=delete_role_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.get("/role/{role_id}", response_model=RoleDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:query'))]) +@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: - delete_role_result = RoleService.detail_role_services(query_db, role_id) + role_detail_result = RoleService.role_detail_services(query_db, role_id) logger.info(f'获取role_id为{role_id}的信息成功') - return response_200(data=delete_role_result, message='获取成功') + return ResponseUtil.success(data=role_detail_result.model_dump(by_alias=True)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/export", dependencies=[Depends(CheckUserInterfaceAuth('system:role:export'))]) +@roleController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:role:export'))]) @log_decorator(title='角色管理', business_type=5) -async def export_system_role_list(request: Request, role_query: RoleQueryModel, query_db: Session = Depends(get_db)): +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_query) + role_query_result = RoleService.get_role_list_services(query_db, role_page_query, is_page=False) role_export_result = RoleService.export_role_list_services(role_query_result) logger.info('导出成功') - return streaming_response_200(data=bytes2file_response(role_export_result)) + return ResponseUtil.streaming(data=bytes2file_response(role_export_result)) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/authUser/allocatedList", response_model=UserRolePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_allocated_user_list(request: Request, user_role: UserRolePageObject, query_db: Session = Depends(get_db)): +@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: - user_role_query = UserRoleQueryModel(**user_role.dict()) - user_role_allocated_query_result = UserService.get_user_role_allocated_list_services(query_db, user_role_query) - # 分页操作 - user_role_allocated_page_query_result = get_page_obj(user_role_allocated_query_result, user_role.page_num, user_role.page_size) + 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.get("/authUser/allocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_allocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)): + try: + role_user_allocated_page_query_result = RoleService.get_role_user_allocated_list_services(query_db, user_role, is_page=True) logger.info('获取成功') - return response_200(data=user_role_allocated_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=role_user_allocated_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/authUser/unallocatedList", response_model=UserRolePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_unallocated_user_list(request: Request, user_role: UserRolePageObject, query_db: Session = Depends(get_db)): +@roleController.get("/authUser/unallocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_unallocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)): try: - user_role_query = UserRoleQueryModel(**user_role.dict()) - user_role_unallocated_query_result = UserService.get_user_role_unallocated_list_services(query_db, user_role_query) - # 分页操作 - user_role_unallocated_page_query_result = get_page_obj(user_role_unallocated_query_result, user_role.page_num, user_role.page_size) + role_user_unallocated_page_query_result = RoleService.get_role_user_unallocated_list_services(query_db, user_role, is_page=True) logger.info('获取成功') - return response_200(data=user_role_unallocated_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=role_user_unallocated_page_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/authUser/selectAll", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))]) +@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_user_role: CrudUserRoleModel, query_db: Session = Depends(get_db)): +async def add_system_role_user(request: Request, add_role_user: CrudUserRoleModel = Depends(CrudUserRoleModel.as_query), query_db: Session = Depends(get_db)): try: - add_user_role_result = UserService.add_user_role_services(query_db, add_user_role) - if add_user_role_result.is_success: - logger.info(add_user_role_result.message) - return response_200(data=add_user_role_result, message=add_user_role_result.message) + 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_user_role_result.message) - return response_400(data="", message=add_user_role_result.message) + logger.warning(add_role_user_result.message) + return ResponseUtil.failure(msg=add_role_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@roleController.post("/role/authUser/cancel", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))]) +@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 response_200(data=cancel_user_role_result, message=cancel_user_role_result.message) + return ResponseUtil.success(msg=cancel_user_role_result.message) else: logger.warning(cancel_user_role_result.message) - return response_400(data="", message=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.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 response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/server_controller.py b/ruoyi-fastapi-backend/module_admin/controller/server_controller.py similarity index 53% rename from ruoyi-fastapi/module_admin/controller/server_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/server_controller.py index 0119f9fb44e00fed9248b5303e1bbba2fc255810..b08991263cdfd6fd59144ae5a9887b382a61504b 100644 --- a/ruoyi-fastapi/module_admin/controller/server_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/server_controller.py @@ -1,22 +1,22 @@ from fastapi import APIRouter, Request from fastapi import Depends -from module_admin.service.login_service import get_current_user +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 module_admin.aspect.interface_auth import CheckUserInterfaceAuth -serverController = APIRouter(prefix='/server', dependencies=[Depends(get_current_user)]) +serverController = APIRouter(prefix='/monitor/server', dependencies=[Depends(LoginService.get_current_user)]) -@serverController.post("/statisticalInfo", 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 response_200(data=server_info_query_result, message="获取成功") + return ResponseUtil.success(data=server_info_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/controller/user_controller.py b/ruoyi-fastapi-backend/module_admin/controller/user_controller.py similarity index 62% rename from ruoyi-fastapi/module_admin/controller/user_controller.py rename to ruoyi-fastapi-backend/module_admin/controller/user_controller.py index 32a8d78c67d1e23caa5198b3ed13e6ce0d91b7e3..46ea0b82f9c708c8b535c67427978a4b5d25b42d 100644 --- a/ruoyi-fastapi/module_admin/controller/user_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/user_controller.py @@ -1,22 +1,21 @@ from fastapi import APIRouter, Request from fastapi import Depends, File, Query -import base64 from config.get_db import get_db +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 module_admin.entity.vo.user_vo import * -from module_admin.dao.user_dao import * -from utils.page_util import * +from utils.page_util import PageResponseModel from utils.response_util import * from utils.log_util import * from utils.common_util import bytes2file_response +from utils.upload_util import UploadUtil from module_admin.aspect.interface_auth import CheckUserInterfaceAuth from module_admin.aspect.data_scope import GetDataScope from module_admin.annotation.log_annotation import log_decorator -userController = APIRouter(prefix='/user', dependencies=[Depends(LoginService.get_current_user)]) +userController = APIRouter(prefix='/system/user', dependencies=[Depends(LoginService.get_current_user)]) @userController.get("/deptTree", dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))]) @@ -30,14 +29,11 @@ async def get_system_dept_tree(request: Request, query_db: Session = Depends(get return ResponseUtil.error(msg=str(e)) -@userController.post("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))]) -async def get_system_user_list(request: Request, user_page_query: UserPageQueryModel, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))): +@userController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))]) +async def get_system_user_list(request: Request, user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_query), query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))): try: - user_query = UserQueryModel(**user_page_query.model_dump(by_alias=True)) - # 获取全量数据 - user_query_result = UserService.get_user_list_services(query_db, user_query, data_scope_sql) - # 分页操作 - user_page_query_result = get_page_obj(user_query_result, user_page_query.page_num, user_page_query.page_size) + # 获取分页数据 + user_page_query_result = UserService.get_user_list_services(query_db, user_page_query, data_scope_sql, is_page=True) logger.info('获取成功') return ResponseUtil.success(model_content=user_page_query_result) except Exception as e: @@ -123,6 +119,25 @@ async def reset_system_user_pwd(request: Request, edit_user: EditUserModel, quer return ResponseUtil.error(msg=str(e)) +@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.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: @@ -146,77 +161,81 @@ async def query_detail_system_user(request: Request, user_id: Optional[Union[int return ResponseUtil.error(msg=str(e)) -@userController.patch("/user/profile/changeAvatar", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@userController.post("/profile/avatar") @log_decorator(title='个人信息', business_type=2) -async def change_system_user_profile_avatar(request: Request, edit_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): +async def change_system_user_profile_avatar(request: Request, avatarfile: bytes = File(), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): try: - avatar = edit_user.avatar - # 去除 base64 字符串中的头部信息(data:image/jpeg;base64, 等等) - base64_string = avatar.split(',', 1)[1] - # 解码 base64 字符串 - file_data = base64.b64decode(base64_string) - dir_path = os.path.join(CachePathConfig.PATH, 'avatar', current_user.user.user_name) + 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) except FileExistsError: pass - filepath = os.path.join(dir_path, f'{current_user.user.user_name}_avatar.jpeg') - with open(filepath, 'wb') as f: - f.write(file_data) - edit_user.user_id = current_user.user.user_id - edit_user.avatar = f'/common/{CachePathConfig.PATHSTR}?taskPath=avatar&taskId={current_user.user.user_name}&filename={current_user.user.user_name}_avatar.jpeg' - edit_user.update_by = current_user.user.user_name - edit_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + avatar_name = f'avatar_{datetime.now().strftime("%Y%m%d%H%M%S")}{UploadConfig.UPLOAD_MACHINE}{UploadUtil.generate_random_number()}.png' + avatar_path = os.path.join(dir_path, avatar_name) + with open(avatar_path, 'wb') as f: + f.write(avatarfile) + edit_user = EditUserModel( + userId=current_user.user.user_id, + avatar=f'{UploadConfig.UPLOAD_PREFIX}/{relative_path}/{avatar_name}', + updateBy=current_user.user.user_name, + updateTime=datetime.now(), + 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 response_200(data=edit_user_result, message=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 response_400(data="", message=edit_user_result.message) + return ResponseUtil.failure(msg=edit_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@userController.patch("/user/profile/changeInfo", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@userController.put("/profile") @log_decorator(title='个人信息', business_type=2) -async def change_system_user_profile_info(request: Request, edit_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): +async def change_system_user_profile_info(request: Request, user_info: UserInfoModel, query_db: 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().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=edit_user_result, message=edit_user_result.message) + return ResponseUtil.success(msg=edit_user_result.message) else: logger.warning(edit_user_result.message) - return response_400(data="", message=edit_user_result.message) + return ResponseUtil.failure(msg=edit_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@userController.patch("/user/profile/resetPwd", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@userController.put("/profile/updatePwd") @log_decorator(title='个人信息', business_type=2) -async def reset_system_user_password(request: Request, reset_user: ResetUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): +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: - if not reset_user.user_id and reset_user.old_password: - reset_user.user_id = current_user.user.user_id - reset_user.password = PwdUtil.get_password_hash(reset_user.password) - reset_user.update_by = current_user.user.user_name - reset_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + 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 response_200(data=reset_user_result, message=reset_user_result.message) + return ResponseUtil.success(msg=reset_user_result.message) else: logger.warning(reset_user_result.message) - return response_400(data="", message=reset_user_result.message) + return ResponseUtil.failure(msg=reset_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) @userController.post("/importData", dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))]) @@ -250,9 +269,8 @@ async def export_system_user_template(request: Request, query_db: Session = Depe @log_decorator(title='用户管理', business_type=5) async def export_system_user_list(request: Request, user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_form), query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))): try: - user_query = UserQueryModel(**user_page_query.model_dump(by_alias=True)) # 获取全量数据 - user_query_result = UserService.get_user_list_services(query_db, user_query, data_scope_sql) + user_query_result = UserService.get_user_list_services(query_db, user_page_query, data_scope_sql, is_page=False) user_export_result = UserService.export_user_list_services(user_query_result) logger.info('导出成功') return ResponseUtil.streaming(data=bytes2file_response(user_export_result)) @@ -261,61 +279,28 @@ async def export_system_user_list(request: Request, user_page_query: UserPageQue return ResponseUtil.error(msg=str(e)) -@userController.post("/user/authRole/allocatedList", response_model=UserRolePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_allocated_role_list(request: Request, user_role: UserRolePageObject, query_db: Session = Depends(get_db)): +@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(**user_role.dict()) + user_role_query = UserRoleQueryModel(userId=user_id) user_role_allocated_query_result = UserService.get_user_role_allocated_list_services(query_db, user_role_query) - # 分页操作 - user_role_allocated_page_query_result = get_page_obj(user_role_allocated_query_result, user_role.page_num, user_role.page_size) - logger.info('获取成功') - return response_200(data=user_role_allocated_page_query_result, message="获取成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@userController.post("/user/authRole/unallocatedList", response_model=UserRolePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_unallocated_role_list(request: Request, user_role: UserRolePageObject, query_db: Session = Depends(get_db)): - try: - user_role_query = UserRoleQueryModel(**user_role.dict()) - user_role_unallocated_query_result = UserService.get_user_role_unallocated_list_services(query_db, user_role_query) - # 分页操作 - user_role_unallocated_page_query_result = get_page_obj(user_role_unallocated_query_result, user_role.page_num, user_role.page_size) logger.info('获取成功') - return response_200(data=user_role_unallocated_page_query_result, message="获取成功") + return ResponseUtil.success(model_content=user_role_allocated_query_result) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) -@userController.post("/user/authRole/selectAll", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))]) -@log_decorator(title='用户管理', business_type=4) -async def add_system_role_user(request: Request, add_user_role: CrudUserRoleModel, query_db: Session = Depends(get_db)): +@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, add_user_role) + 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 response_200(data=add_user_role_result, message=add_user_role_result.message) + return ResponseUtil.success(msg=add_user_role_result.message) else: logger.warning(add_user_role_result.message) - return response_400(data="", message=add_user_role_result.message) + return ResponseUtil.failure(msg=add_user_role_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message=str(e)) - - -@userController.post("/user/authRole/cancel", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:user: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 response_200(data=cancel_user_role_result, message=cancel_user_role_result.message) - else: - logger.warning(cancel_user_role_result.message) - return response_400(data="", message=cancel_user_role_result.message) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) + return ResponseUtil.error(msg=str(e)) diff --git a/ruoyi-fastapi/module_admin/dao/config_dao.py b/ruoyi-fastapi-backend/module_admin/dao/config_dao.py similarity index 77% rename from ruoyi-fastapi/module_admin/dao/config_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/config_dao.py index a7fb473c973a48c23950f69279020b62f5f5b19c..7a13a97a58b9d1ce281659eab9a0bb3799bb14d4 100644 --- a/ruoyi-fastapi/module_admin/dao/config_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/config_dao.py @@ -1,7 +1,7 @@ from sqlalchemy.orm import Session from module_admin.entity.do.config_do import SysConfig -from module_admin.entity.vo.config_vo import ConfigModel, ConfigQueryModel -from utils.time_format_util import list_format_datetime +from module_admin.entity.vo.config_vo import * +from utils.page_util import PageUtil from datetime import datetime, time @@ -40,36 +40,27 @@ class ConfigDao: return config_info @classmethod - def get_all_config(cls, db: Session): - """ - 获取所有的参数配置信息 - :param db: orm对象 - :return: 参数配置信息列表对象 - """ - config_info = db.query(SysConfig).all() - - return list_format_datetime(config_info) - - @classmethod - def get_config_list(cls, db: Session, query_object: ConfigQueryModel): + def get_config_list(cls, db: Session, query_object: ConfigPageQueryModel, is_page: bool = False): """ 根据查询参数获取参数配置列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 参数配置列表信息对象 """ - config_list = db.query(SysConfig) \ + 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.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.create_time_start and query_object.create_time_end else True + 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().all() + .distinct() + config_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(config_list) + return config_list @classmethod def add_config_dao(cls, db: Session, config: ConfigModel): @@ -79,7 +70,7 @@ class ConfigDao: :param config: 参数配置对象 :return: """ - db_config = SysConfig(**config.dict()) + db_config = SysConfig(**config.model_dump()) db.add(db_config) db.flush() diff --git a/ruoyi-fastapi/module_admin/dao/dept_dao.py b/ruoyi-fastapi-backend/module_admin/dao/dept_dao.py similarity index 94% rename from ruoyi-fastapi/module_admin/dao/dept_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/dept_dao.py index cc1921f07701a3d21b1aa19f9cf419e926a80a93..ffe3b67e7f826586e0b7cb20767ea00a8a1bf872 100644 --- a/ruoyi-fastapi/module_admin/dao/dept_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/dept_dao.py @@ -1,8 +1,6 @@ -from sqlalchemy import or_, func from sqlalchemy.orm import Session -from module_admin.entity.do.role_do import SysRoleDept from module_admin.entity.do.dept_do import SysDept -from module_admin.entity.vo.dept_vo import DeptModel, DeptResponse, CrudDeptResponse +from module_admin.entity.vo.dept_vo import * from utils.time_format_util import list_format_datetime @@ -155,11 +153,7 @@ class DeptDao: .order_by(SysDept.order_num) \ .distinct().all() - result = dict( - rows=list_format_datetime(dept_result), - ) - - return DeptResponse(**result) + return dept_result @classmethod def add_dept_dao(cls, db: Session, dept: DeptModel): @@ -169,7 +163,7 @@ class DeptDao: :param dept: 部门对象 :return: 新增校验结果 """ - db_dept = SysDept(**dept.dict()) + db_dept = SysDept(**dept.model_dump()) db.add(db_dept) db.flush() diff --git a/ruoyi-fastapi/module_admin/dao/dict_dao.py b/ruoyi-fastapi-backend/module_admin/dao/dict_dao.py similarity index 89% rename from ruoyi-fastapi/module_admin/dao/dict_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/dict_dao.py index 30312fd9dad7fa09ef858a208500d09f0472ccd8..3b7d127d8ad534f932dec146920b643ea21e8ba5 100644 --- a/ruoyi-fastapi/module_admin/dao/dict_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/dict_dao.py @@ -1,8 +1,9 @@ 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 DictTypeModel, DictTypeQueryModel, DictDataModel +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 @@ -52,25 +53,27 @@ class DictTypeDao: return list_format_datetime(dict_type_info) @classmethod - def get_dict_type_list(cls, db: Session, query_object: DictTypeQueryModel): + def get_dict_type_list(cls, db: Session, query_object: DictTypePageQueryModel, is_page: bool = False): """ 根据查询参数获取字典类型列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 字典类型列表信息对象 """ - dict_type_list = db.query(SysDictType) \ + 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.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.create_time_start and query_object.create_time_end else True + 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().all() + .distinct() + dict_type_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(dict_type_list) + return dict_type_list @classmethod def add_dict_type_dao(cls, db: Session, dict_type: DictTypeModel): @@ -147,22 +150,24 @@ class DictDataDao: return dict_data_info @classmethod - def get_dict_data_list(cls, db: Session, query_object: DictDataModel): + def get_dict_data_list(cls, db: Session, query_object: DictDataPageQueryModel, is_page: bool = False): """ 根据查询参数获取字典数据列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 字典数据列表信息对象 """ - dict_data_list = db.query(SysDictData) \ + 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) \ - .distinct().all() + .distinct() + dict_data_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(dict_data_list) + return dict_data_list @classmethod def query_dict_data_list(cls, db: Session, dict_type: str): @@ -178,7 +183,7 @@ class DictDataDao: .order_by(SysDictData.dict_sort) \ .distinct().all() - return list_format_datetime(dict_data_list) + return dict_data_list @classmethod def add_dict_data_dao(cls, db: Session, dict_data: DictDataModel): diff --git a/ruoyi-fastapi/module_admin/dao/job_dao.py b/ruoyi-fastapi-backend/module_admin/dao/job_dao.py similarity index 86% rename from ruoyi-fastapi/module_admin/dao/job_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/job_dao.py index ca318c8c0eb942f591a14a608ba1cffbc8a62c2f..0007b5220225f57d5147fd7c365e05a88430670f 100644 --- a/ruoyi-fastapi/module_admin/dao/job_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/job_dao.py @@ -1,7 +1,7 @@ from sqlalchemy.orm import Session from module_admin.entity.do.job_do import SysJob -from module_admin.entity.vo.job_vo import JobModel -from utils.time_format_util import list_format_datetime, object_format_datetime +from module_admin.entity.vo.job_vo import * +from utils.page_util import PageUtil class JobDao: @@ -21,7 +21,7 @@ class JobDao: .filter(SysJob.job_id == job_id) \ .first() - return object_format_datetime(job_info) + return job_info @classmethod def get_job_detail_by_info(cls, db: Session, job: JobModel): @@ -41,21 +41,23 @@ class JobDao: return job_info @classmethod - def get_job_list(cls, db: Session, query_object: JobModel): + def get_job_list(cls, db: Session, query_object: JobPageQueryModel, is_page: bool = False): """ 根据查询参数获取定时任务列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 定时任务列表信息对象 """ - job_list = db.query(SysJob) \ + 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 ) \ - .distinct().all() + .distinct() + job_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(job_list) + return job_list @classmethod def get_job_list_for_scheduler(cls, db: Session): @@ -68,7 +70,7 @@ class JobDao: .filter(SysJob.status == 0) \ .distinct().all() - return list_format_datetime(job_list) + return job_list @classmethod def add_job_dao(cls, db: Session, job: JobModel): @@ -78,7 +80,7 @@ class JobDao: :param job: 定时任务对象 :return: """ - db_job = SysJob(**job.dict()) + db_job = SysJob(**job.model_dump()) db.add(db_job) db.flush() diff --git a/ruoyi-fastapi/module_admin/dao/job_log_dao.py b/ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py similarity index 63% rename from ruoyi-fastapi/module_admin/dao/job_log_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py index b3cd75c830f72448039639f1e240c9e060c27ef1..713946594c8067107cbc380a5f7a6973937757c3 100644 --- a/ruoyi-fastapi/module_admin/dao/job_log_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py @@ -1,7 +1,7 @@ from sqlalchemy.orm import Session from module_admin.entity.do.job_do import SysJobLog -from module_admin.entity.vo.job_vo import JobLogModel, JobLogQueryModel -from utils.time_format_util import list_format_datetime, object_format_datetime +from module_admin.entity.vo.job_vo import * +from utils.page_util import PageUtil from datetime import datetime, time @@ -11,39 +11,27 @@ class JobLogDao: """ @classmethod - def get_job_log_detail_by_id(cls, db: Session, job_log_id: int): - """ - 根据定时任务日志id获取定时任务日志详细信息 - :param db: orm对象 - :param job_log_id: 定时任务日志id - :return: 定时任务日志信息对象 - """ - job_log_info = db.query(SysJobLog) \ - .filter(SysJobLog.job_log_id == job_log_id) \ - .first() - - return object_format_datetime(job_log_info) - - @classmethod - def get_job_log_list(cls, db: Session, query_object: JobLogQueryModel): + def get_job_log_list(cls, db: Session, query_object: JobLogPageQueryModel, is_page: bool = False): """ 根据查询参数获取定时任务日志列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 定时任务日志列表信息对象 """ - job_log_list = db.query(SysJobLog) \ + 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.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.create_time_start and query_object.create_time_end else True + 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().all() + .distinct() + job_log_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(job_log_list) + return job_log_list @classmethod def add_job_log_dao(cls, db: Session, job_log: JobLogModel): @@ -53,7 +41,7 @@ class JobLogDao: :param job_log: 定时任务日志对象 :return: """ - db_job_log = SysJobLog(**job_log.dict()) + db_job_log = SysJobLog(**job_log.model_dump()) db.add(db_job_log) db.flush() diff --git a/ruoyi-fastapi/module_admin/dao/log_dao.py b/ruoyi-fastapi-backend/module_admin/dao/log_dao.py similarity index 74% rename from ruoyi-fastapi/module_admin/dao/log_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/log_dao.py index a4fa2eb32b63fe1db2d4ff8fc10f904329927937..7fefc8f1edb0b287af9b58bd836ff7e7c7c1ce78 100644 --- a/ruoyi-fastapi/module_admin/dao/log_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/log_dao.py @@ -1,7 +1,7 @@ from sqlalchemy.orm import Session from module_admin.entity.do.log_do import SysOperLog, SysLogininfor -from module_admin.entity.vo.log_vo import OperLogModel, LogininforModel, OperLogQueryModel, LoginLogQueryModel -from utils.time_format_util import object_format_datetime, list_format_datetime +from module_admin.entity.vo.log_vo import * +from utils.page_util import PageUtil from datetime import datetime, time @@ -9,42 +9,29 @@ class OperationLogDao: """ 操作日志管理模块数据库操作层 """ - - @classmethod - def get_operation_log_detail_by_id(cls, db: Session, oper_id: int): - """ - 根据操作日志id获取操作日志详细信息 - :param db: orm对象 - :param oper_id: 操作日志id - :return: 操作日志信息对象 - """ - operation_log_info = db.query(SysOperLog) \ - .filter(SysOperLog.oper_id == oper_id) \ - .first() - - return object_format_datetime(operation_log_info) - @classmethod - def get_operation_log_list(cls, db: Session, query_object: OperLogQueryModel): + def get_operation_log_list(cls, db: Session, query_object: OperLogPageQueryModel, is_page: bool = False): """ 根据查询参数获取操作日志列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 操作日志列表信息对象 """ - operation_log_list = db.query(SysOperLog) \ + 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.oper_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.oper_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.oper_time_start and query_object.oper_time_end else True + 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().all() + .distinct() + operation_log_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(operation_log_list) + return operation_log_list @classmethod def add_operation_log_dao(cls, db: Session, operation_log: OperLogModel): @@ -89,25 +76,27 @@ class LoginLogDao: """ @classmethod - def get_login_log_list(cls, db: Session, query_object: LoginLogQueryModel): + def get_login_log_list(cls, db: Session, query_object: LoginLogPageQueryModel, is_page: bool = False): """ 根据查询参数获取登录日志列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 登录日志列表信息对象 """ - login_log_list = db.query(SysLogininfor) \ + 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.login_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.login_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.login_time_start and query_object.login_time_end else True + 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().all() + .distinct() + login_log_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(login_log_list) + return login_log_list @classmethod def add_login_log_dao(cls, db: Session, login_log: LogininforModel): diff --git a/ruoyi-fastapi/module_admin/dao/login_dao.py b/ruoyi-fastapi-backend/module_admin/dao/login_dao.py similarity index 100% rename from ruoyi-fastapi/module_admin/dao/login_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/login_dao.py diff --git a/ruoyi-fastapi/module_admin/dao/menu_dao.py b/ruoyi-fastapi-backend/module_admin/dao/menu_dao.py similarity index 66% rename from ruoyi-fastapi/module_admin/dao/menu_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/menu_dao.py index 6409572fbde17b9895ca204a51c56123100f9d22..272529be55ed0476f52a7f27e47f3e8149671946 100644 --- a/ruoyi-fastapi/module_admin/dao/menu_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/menu_dao.py @@ -3,8 +3,7 @@ from sqlalchemy.orm import Session 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 MenuModel, MenuResponse -from utils.time_format_util import list_format_datetime +from module_admin.entity.vo.menu_vo import * class MenuDao: @@ -43,43 +42,10 @@ class MenuDao: return menu_info @classmethod - def get_menu_info_for_edit_option(cls, db: Session, menu_info: MenuModel, user_id: int, role: list): - """ - 根据角色信息获取菜单编辑对应的在用菜单列表信息 - :param db: orm对象 - :param menu_info: 菜单对象 - :param user_id: 用户id - :param role: 用户角色列表信息 - :return: 菜单列表信息 - """ - role_id_list = [item.role_id for item in role] - if 1 in role_id_list: - menu_result = db.query(SysMenu) \ - .filter(SysMenu.menu_id != menu_info.menu_id, SysMenu.parent_id != menu_info.menu_id, - SysMenu.status == 0) \ - .all() - else: - menu_result = 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.menu_id != menu_info.menu_id, - SysMenu.parent_id != menu_info.menu_id, - SysMenu.status == 0)) \ - .order_by(SysMenu.order_num) \ - .distinct().all() - - return list_format_datetime(menu_result) - - @classmethod - def get_menu_list_for_tree(cls, db: Session, menu_info: MenuModel, user_id: int, role: list): + def get_menu_list_for_tree(cls, db: Session, user_id: int, role: list): """ 根据角色信息获取所有在用菜单列表信息 :param db: orm对象 - :param menu_info: 菜单对象 :param user_id: 用户id :param role: 用户角色列表信息 :return: 菜单列表信息 @@ -87,8 +53,7 @@ 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, - SysMenu.menu_name.like(f'%{menu_info.menu_name}%') if menu_info.menu_name else True) \ + .filter(SysMenu.status == 0) \ .order_by(SysMenu.order_num) \ .distinct().all() else: @@ -98,17 +63,14 @@ class MenuDao: .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, - SysMenu.menu_name.like( - f'%{menu_info.menu_name}%') if menu_info.menu_name else True)) \ + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0,)) \ .order_by(SysMenu.order_num) \ .distinct().all() - return list_format_datetime(menu_query_all) + return menu_query_all @classmethod - def get_menu_list(cls, db: Session, page_object: MenuModel, user_id: int, role: list): + def get_menu_list(cls, db: Session, page_object: MenuQueryModel, user_id: int, role: list): """ 根据查询参数获取菜单列表信息 :param db: orm对象 @@ -139,11 +101,7 @@ class MenuDao: .order_by(SysMenu.order_num) \ .distinct().all() - result = dict( - rows=list_format_datetime(menu_query_all), - ) - - return MenuResponse(**result) + return menu_query_all @classmethod def add_menu_dao(cls, db: Session, menu: MenuModel): @@ -153,7 +111,7 @@ class MenuDao: :param menu: 菜单对象 :return: """ - db_menu = SysMenu(**menu.dict()) + db_menu = SysMenu(**menu.model_dump()) db.add(db_menu) db.flush() diff --git a/ruoyi-fastapi/module_admin/dao/notice_dao.py b/ruoyi-fastapi-backend/module_admin/dao/notice_dao.py similarity index 81% rename from ruoyi-fastapi/module_admin/dao/notice_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/notice_dao.py index b72d59f28e20b1e237a19bc72581c6da20e32621..2d3646f420496263489c7c29f1f16610e5c4073b 100644 --- a/ruoyi-fastapi/module_admin/dao/notice_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/notice_dao.py @@ -1,7 +1,7 @@ from sqlalchemy.orm import Session from module_admin.entity.do.notice_do import SysNotice -from module_admin.entity.vo.notice_vo import NoticeModel, NoticeQueryModel, CrudNoticeResponse -from utils.time_format_util import list_format_datetime, object_format_datetime +from module_admin.entity.vo.notice_vo import * +from utils.page_util import PageUtil from datetime import datetime, time @@ -22,7 +22,7 @@ class NoticeDao: .filter(SysNotice.notice_id == notice_id) \ .first() - return object_format_datetime(notice_info) + return notice_info @classmethod def get_notice_detail_by_info(cls, db: Session, notice: NoticeModel): @@ -41,25 +41,27 @@ class NoticeDao: return notice_info @classmethod - def get_notice_list(cls, db: Session, query_object: NoticeQueryModel): + def get_notice_list(cls, db: Session, query_object: NoticePageQueryModel, is_page: bool = False): """ 根据查询参数获取通知公告列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 通知公告列表信息对象 """ - notice_list = db.query(SysNotice) \ + 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.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.create_time_start and query_object.create_time_end else True + 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().all() + .distinct() + notice_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(notice_list) + return notice_list @classmethod def add_notice_dao(cls, db: Session, notice: NoticeModel): @@ -69,7 +71,7 @@ class NoticeDao: :param notice: 通知公告对象 :return: """ - db_notice = SysNotice(**notice.dict()) + db_notice = SysNotice(**notice.model_dump()) db.add(db_notice) db.flush() diff --git a/ruoyi-fastapi/module_admin/dao/post_dao.py b/ruoyi-fastapi-backend/module_admin/dao/post_dao.py similarity index 82% rename from ruoyi-fastapi/module_admin/dao/post_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/post_dao.py index ecde7b7b53535fc55bba6895eef15d866f860e95..2cb7f89744e972120897d2d291d8fc48c1c00a12 100644 --- a/ruoyi-fastapi/module_admin/dao/post_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/post_dao.py @@ -1,7 +1,7 @@ from sqlalchemy.orm import Session from module_admin.entity.do.post_do import SysPost -from module_admin.entity.vo.post_vo import PostModel -from utils.common_util import CamelCaseUtil +from module_admin.entity.vo.post_vo import * +from utils.page_util import PageUtil class PostDao: @@ -55,35 +55,24 @@ class PostDao: return post_info @classmethod - def get_post_select_option_dao(cls, db: Session): - """ - 获取所有在用岗位信息 - :param db: orm对象 - :return: 在用岗位信息列表 - """ - post_info = db.query(SysPost) \ - .filter(SysPost.status == 0) \ - .all() - - return post_info - - @classmethod - def get_post_list(cls, db: Session, query_object: PostModel): + def get_post_list(cls, db: Session, query_object: PostPageQueryModel, is_page: bool = False): """ 根据查询参数获取岗位列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 岗位列表信息对象 """ - post_list = db.query(SysPost) \ + 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) \ - .distinct().all() + .distinct() + post_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return CamelCaseUtil.transform_result(post_list) + return post_list @classmethod def add_post_dao(cls, db: Session, post: PostModel): @@ -93,7 +82,7 @@ class PostDao: :param post: 岗位对象 :return: """ - db_post = SysPost(**post.dict()) + db_post = SysPost(**post.model_dump()) db.add(db_post) db.flush() diff --git a/ruoyi-fastapi/module_admin/dao/role_dao.py b/ruoyi-fastapi-backend/module_admin/dao/role_dao.py similarity index 77% rename from ruoyi-fastapi/module_admin/dao/role_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/role_dao.py index b1f41cd046c16319e9aed11e5508ac91f0fc2b7b..32267dabab28395fa627b16ed5b561611bce98c8 100644 --- a/ruoyi-fastapi/module_admin/dao/role_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/role_dao.py @@ -1,10 +1,9 @@ -from sqlalchemy import and_, desc +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.do.menu_do import SysMenu -from module_admin.entity.vo.role_vo import RoleModel, RoleMenuModel, RoleDeptModel, RoleQueryModel, RoleDetailModel -from utils.time_format_util import list_format_datetime, object_format_datetime +from module_admin.entity.vo.role_vo import * +from utils.page_util import PageUtil from datetime import datetime, time @@ -67,26 +66,11 @@ class RoleDao: :param role_id: 角色id :return: 当前role_id的角色信息对象 """ - query_role_basic_info = db.query(SysRole) \ + query_role_info = db.query(SysRole) \ .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ .distinct().first() - query_role_menu_info = db.query(SysMenu).select_from(SysRole) \ - .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ - .distinct().all() - query_role_dept_info = db.query(SysDept).select_from(SysRole) \ - .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ - .outerjoin(SysRoleDept, SysRole.role_id == SysRoleDept.role_id) \ - .outerjoin(SysDept, and_(SysRoleDept.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ - .distinct().all() - results = dict( - role=object_format_datetime(query_role_basic_info), - menu=list_format_datetime(query_role_menu_info), - dept=list_format_datetime(query_role_dept_info), - ) - return RoleDetailModel(**results) + return query_role_info @classmethod def get_role_select_option_dao(cls, db: Session): @@ -102,25 +86,27 @@ class RoleDao: return role_info @classmethod - def get_role_list(cls, db: Session, query_object: RoleQueryModel): + def get_role_list(cls, db: Session, query_object: RolePageQueryModel, is_page: bool = False): """ 根据查询参数获取角色列表信息 :param db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 角色列表信息对象 """ - role_list = db.query(SysRole) \ + query = db.query(SysRole) \ .filter(SysRole.del_flag == 0, SysRole.role_name.like(f'%{query_object.role_name}%') if query_object.role_name else True, SysRole.role_key.like(f'%{query_object.role_key}%') if query_object.role_key else True, SysRole.status == query_object.status if query_object.status else True, SysRole.create_time.between( - datetime.combine(datetime.strptime(query_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.create_time_start and query_object.create_time_end else True + 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) \ - .distinct().all() + .distinct() + role_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) return role_list @@ -132,7 +118,7 @@ class RoleDao: :param role: 角色对象 :return: """ - db_role = SysRole(**role.dict()) + db_role = SysRole(**role.model_dump(exclude={'admin'})) db.add(db_role) db.flush() @@ -162,6 +148,20 @@ class RoleDao: .filter(SysRole.role_id == role.role_id) \ .update({SysRole.del_flag: '2', SysRole.update_by: role.update_by, SysRole.update_time: role.update_time}) + @classmethod + def get_role_menu_dao(cls, db: Session, role_id: int): + """ + 根据角色id获取角色菜单关联列表信息 + :param db: orm对象 + :param role_id: 角色id + :return: 角色菜单关联列表信息 + """ + role_menu_query_all = db.query(SysRoleMenu) \ + .filter(SysRoleMenu.role_id == role_id) \ + .distinct().all() + + return role_menu_query_all + @classmethod def add_role_menu_dao(cls, db: Session, role_menu: RoleMenuModel): """ @@ -170,7 +170,7 @@ class RoleDao: :param role_menu: 用户角色菜单关联对象 :return: """ - db_role_menu = SysRoleMenu(**role_menu.dict()) + db_role_menu = SysRoleMenu(**role_menu.model_dump()) db.add(db_role_menu) @classmethod @@ -185,6 +185,22 @@ class RoleDao: .filter(SysRoleMenu.role_id == role_menu.role_id) \ .delete() + @classmethod + def get_role_dept_dao(cls, db: Session, role_id: int): + """ + 根据角色id获取角色部门关联列表信息 + :param db: orm对象 + :param role_id: 角色id + :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() + + return role_dept_query_all + @classmethod def add_role_dept_dao(cls, db: Session, role_dept: RoleDeptModel): """ diff --git a/ruoyi-fastapi/module_admin/dao/user_dao.py b/ruoyi-fastapi-backend/module_admin/dao/user_dao.py similarity index 87% rename from ruoyi-fastapi/module_admin/dao/user_dao.py rename to ruoyi-fastapi-backend/module_admin/dao/user_dao.py index 9dee271a4c4d5d219c6b99fcd747aa9794f59fc9..f6c2c2fb3c6dd3c9f946929f8996b7ec715330ef 100644 --- a/ruoyi-fastapi/module_admin/dao/user_dao.py +++ b/ruoyi-fastapi-backend/module_admin/dao/user_dao.py @@ -1,12 +1,12 @@ 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, SysRoleMenu, SysRoleDept +from module_admin.entity.do.role_do import SysRole, 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 UserModel, UserRoleModel, UserPostModel, CurrentUserInfo, UserQueryModel, UserRoleQueryModel -from utils.time_format_util import object_format_datetime, list_format_datetime +from module_admin.entity.vo.user_vo import * +from utils.page_util import PageUtil from datetime import datetime, time @@ -137,15 +137,16 @@ class UserDao: return results @classmethod - def get_user_list(cls, db: Session, query_object: UserQueryModel, data_scope_sql: str): + def get_user_list(cls, db: Session, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False): """ 根据查询参数获取用户列表信息 :param db: orm对象 :param query_object: 查询参数对象 :param data_scope_sql: 数据权限对应的查询sql语句 + :param is_page: 是否开启分页 :return: 用户列表信息对象 """ - user_list = db.query(SysUser, SysDept) \ + query = db.query(SysUser, SysDept) \ .filter(SysUser.del_flag == 0, or_(SysUser.dept_id == query_object.dept_id, SysUser.dept_id.in_( db.query(SysDept.dept_id).filter(func.find_in_set(query_object.dept_id, SysDept.ancestors)) @@ -163,7 +164,8 @@ class UserDao: eval(data_scope_sql) ) \ .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ - .distinct().all() + .distinct() + user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) return user_list @@ -175,7 +177,7 @@ class UserDao: :param user: 用户对象 :return: 新增校验结果 """ - db_user = SysUser(**user.model_dump()) + db_user = SysUser(**user.model_dump(exclude={'admin'})) db.add(db_user) db.flush() @@ -224,38 +226,18 @@ class UserDao: ) ).distinct().all() - return list_format_datetime(allocated_role_list) + return allocated_role_list @classmethod - def get_user_role_unallocated_list_by_user_id(cls, db: Session, query_object: UserRoleQueryModel): - """ - 根据用户id获取用户未分配的角色列表信息数据库操作 - :param db: orm对象 - :param query_object: 用户角色查询对象 - :return: 用户未分配的角色列表信息 - """ - unallocated_role_list = db.query(SysRole) \ - .filter( - SysRole.del_flag == 0, - SysRole.role_id != 1, - SysRole.role_name == query_object.role_name if query_object.role_name else True, - SysRole.role_key == query_object.role_key if query_object.role_key else True, - ~SysRole.role_id.in_( - db.query(SysUserRole.role_id).filter(SysUserRole.user_id == query_object.user_id) - ) - ).distinct().all() - - return list_format_datetime(unallocated_role_list) - - @classmethod - def get_user_role_allocated_list_by_role_id(cls, db: Session, query_object: UserRoleQueryModel): + def get_user_role_allocated_list_by_role_id(cls, db: Session, query_object: UserRolePageQueryModel, is_page: bool = False): """ 根据角色id获取已分配的用户列表信息 :param db: orm对象 :param query_object: 用户角色查询对象 + :param is_page: 是否开启分页 :return: 角色已分配的用户列表信息 """ - allocated_user_list = db.query(SysUser) \ + query = db.query(SysUser) \ .filter( SysUser.del_flag == 0, SysUser.user_id != 1, @@ -264,19 +246,21 @@ class UserDao: SysUser.user_id.in_( db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id) ) - ).distinct().all() + ).distinct() + allocated_user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(allocated_user_list) + return allocated_user_list @classmethod - def get_user_role_unallocated_list_by_role_id(cls, db: Session, query_object: UserRoleQueryModel): + def get_user_role_unallocated_list_by_role_id(cls, db: Session, query_object: UserRolePageQueryModel, is_page: bool = False): """ 根据角色id获取未分配的用户列表信息 :param db: orm对象 :param query_object: 用户角色查询对象 + :param is_page: 是否开启分页 :return: 角色未分配的用户列表信息 """ - unallocated_user_list = db.query(SysUser) \ + query = db.query(SysUser) \ .filter( SysUser.del_flag == 0, SysUser.user_id != 1, @@ -285,9 +269,10 @@ class UserDao: ~SysUser.user_id.in_( db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id) ) - ).distinct().all() + ).distinct() + unallocated_user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page) - return list_format_datetime(unallocated_user_list) + return unallocated_user_list @classmethod def add_user_role_dao(cls, db: Session, user_role: UserRoleModel): @@ -297,7 +282,7 @@ class UserDao: :param user_role: 用户角色关联对象 :return: """ - db_user_role = SysUserRole(**user_role.dict()) + db_user_role = SysUserRole(**user_role.model_dump()) db.add(db_user_role) @classmethod @@ -321,7 +306,8 @@ class UserDao: :return: """ db.query(SysUserRole) \ - .filter(SysUserRole.user_id == user_role.user_id, SysUserRole.role_id == user_role.role_id) \ + .filter(SysUserRole.user_id == user_role.user_id, + SysUserRole.role_id == user_role.role_id if user_role.role_id else True) \ .delete() @classmethod @@ -346,7 +332,7 @@ class UserDao: :param user_post: 用户岗位关联对象 :return: """ - db_user_post = SysUserPost(**user_post.dict()) + db_user_post = SysUserPost(**user_post.model_dump()) db.add(db_user_post) @classmethod diff --git a/ruoyi-fastapi/module_admin/entity/do/config_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/config_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/config_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/config_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/dept_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/dept_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/dept_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/dept_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/dict_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/dict_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/dict_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/dict_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/job_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/job_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/job_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/job_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/log_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/log_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/log_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/log_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/menu_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/menu_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/menu_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/menu_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/notice_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/notice_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/notice_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/notice_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/post_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/post_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/post_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/post_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/role_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/role_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/role_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/role_do.py diff --git a/ruoyi-fastapi/module_admin/entity/do/user_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/user_do.py similarity index 100% rename from ruoyi-fastapi/module_admin/entity/do/user_do.py rename to ruoyi-fastapi-backend/module_admin/entity/do/user_do.py diff --git a/ruoyi-fastapi/module_admin/entity/vo/cache_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/cache_vo.py similarity index 34% rename from ruoyi-fastapi/module_admin/entity/vo/cache_vo.py rename to ruoyi-fastapi-backend/module_admin/entity/vo/cache_vo.py index 18c23572c6b05359a19412d7d24881a78f282936..f2fc9ff24024e8e210cc657720b7e0f81f799c75 100644 --- a/ruoyi-fastapi/module_admin/entity/vo/cache_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/cache_vo.py @@ -1,4 +1,5 @@ -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict +from pydantic.alias_generators import to_camel from typing import Optional, List, Any @@ -6,24 +7,20 @@ class CacheMonitorModel(BaseModel): """ 缓存监控信息对应pydantic模型 """ - command_stats: Optional[List] - db_size: Optional[int] - info: Optional[dict] + model_config = ConfigDict(alias_generator=to_camel) + + command_stats: Optional[List] = [] + db_size: Optional[int] = None + info: Optional[dict] = {} class CacheInfoModel(BaseModel): """ 缓存监控对象对应pydantic模型 """ - cache_key: Optional[str] - cache_name: Optional[str] - cache_value: Optional[Any] - remark: Optional[str] - + model_config = ConfigDict(alias_generator=to_camel) -class CrudCacheResponse(BaseModel): - """ - 操作缓存响应模型 - """ - is_success: bool - message: str + cache_key: Optional[str] = None + cache_name: Optional[str] = None + cache_value: Optional[Any] = None + remark: Optional[str] = None diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/common_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/common_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..64e929ee5074f102e180bca45edb45c9b8c259d1 --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/common_vo.py @@ -0,0 +1,24 @@ +from pydantic import BaseModel, ConfigDict +from pydantic.alias_generators import to_camel +from typing import Optional, Any + + +class CrudResponseModel(BaseModel): + """ + 操作响应模型 + """ + is_success: bool + message: str + result: Optional[Any] = None + + +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 diff --git a/ruoyi-fastapi/module_admin/entity/vo/config_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/config_vo.py similarity index 50% rename from ruoyi-fastapi/module_admin/entity/vo/config_vo.py rename to ruoyi-fastapi-backend/module_admin/entity/vo/config_vo.py index f55b9f817cc524ebfa3f1b0c0a7c9d50a5fcb14b..6c7ada7c49b4e0c17484eee2e31c9f95be569f8d 100644 --- a/ruoyi-fastapi/module_admin/entity/vo/config_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/config_vo.py @@ -1,63 +1,50 @@ -from pydantic import BaseModel +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 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[str] = None + create_time: Optional[datetime] = None update_by: Optional[str] = None - update_time: Optional[str] = None + update_time: Optional[datetime] = None remark: Optional[str] = None - class Config: - from_attributes = True - class ConfigQueryModel(ConfigModel): """ 参数配置管理不分页查询模型 """ - create_time_start: Optional[str] = None - create_time_end: Optional[str] = None + begin_time: Optional[str] = None + end_time: Optional[str] = None -class ConfigPageObject(ConfigQueryModel): +@as_query +@as_form +class ConfigPageQueryModel(ConfigQueryModel): """ 参数配置管理分页查询模型 """ - page_num: int - page_size: int - - -class ConfigPageObjectResponse(BaseModel): - """ - 参数配置管理列表分页查询返回模型 - """ - rows: List[Union[ConfigModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool + page_num: int = 1 + page_size: int = 10 class DeleteConfigModel(BaseModel): """ 删除参数配置模型 """ - config_ids: str - + model_config = ConfigDict(alias_generator=to_camel) -class CrudConfigResponse(BaseModel): - """ - 操作参数配置响应模型 - """ - is_success: bool - message: str + config_ids: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/dept_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/dept_vo.py similarity index 63% rename from ruoyi-fastapi/module_admin/entity/vo/dept_vo.py rename to ruoyi-fastapi-backend/module_admin/entity/vo/dept_vo.py index e54def1c9f17836fca89d918a4990991a87f8693..9a8eb3e7fa50630f0416e950117d4df8374d8aef 100644 --- a/ruoyi-fastapi/module_admin/entity/vo/dept_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/dept_vo.py @@ -2,6 +2,7 @@ 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 class DeptModel(BaseModel): @@ -26,40 +27,21 @@ class DeptModel(BaseModel): update_time: Optional[datetime] = None -class DeptPageObject(DeptModel): +@as_query +class DeptQueryModel(DeptModel): """ - 部门管理分页查询模型 + 部门管理不分页查询模型 """ - page_num: int - page_size: int - - -class DeptResponse(BaseModel): - """ - 用户管理列表不分页查询返回模型 - """ - rows: List[Union[DeptModel, None]] = [] - - -class DeptTree(BaseModel): - """ - 部门树响应模型 - """ - dept_tree: Union[List, None] - - -class CrudDeptResponse(BaseModel): - """ - 操作部门响应模型 - """ - is_success: bool - message: str + begin_time: Optional[str] = None + end_time: Optional[str] = None class DeleteDeptModel(BaseModel): """ 删除部门模型 """ + model_config = ConfigDict(alias_generator=to_camel) + dept_ids: str - update_by: Optional[str] - update_time: Optional[str] + update_by: Optional[str] = None + update_time: Optional[str] = None diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/dict_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/dict_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..e4cda55c5c29ee5c0a110db16004ed0b8c69888a --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/dict_vo.py @@ -0,0 +1,98 @@ +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 + + +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 + + +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 + + +class DictTypeQueryModel(DictTypeModel): + """ + 字典类型管理不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +@as_query +@as_form +class DictTypePageQueryModel(DictTypeQueryModel): + """ + 字典类型管理分页查询模型 + """ + page_num: int = 1 + page_size: int = 10 + + +class DeleteDictTypeModel(BaseModel): + """ + 删除字典类型模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + dict_ids: str + + +class DictDataQueryModel(DictDataModel): + """ + 字典数据管理不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +@as_query +@as_form +class DictDataPageQueryModel(DictDataQueryModel): + """ + 字典数据管理分页查询模型 + """ + page_num: int = 1 + page_size: int = 10 + + +class DeleteDictDataModel(BaseModel): + """ + 删除字典数据模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + dict_codes: str diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..f6f91d3967337e1495fd1c4e4453096434f0fd4b --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py @@ -0,0 +1,110 @@ +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 + + +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 + + +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 + + +class JobQueryModel(JobModel): + """ + 定时任务管理不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +@as_query +@as_form +class JobPageQueryModel(JobQueryModel): + """ + 定时任务管理分页查询模型 + """ + page_num: int = 1 + page_size: int = 10 + + +class EditJobModel(JobModel): + """ + 编辑定时任务模型 + """ + type: Optional[str] = None + + +class DeleteJobModel(BaseModel): + """ + 删除定时任务模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + job_ids: str + + +class JobLogQueryModel(JobLogModel): + """ + 定时任务日志不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +@as_query +@as_form +class JobLogPageQueryModel(JobLogQueryModel): + """ + 定时任务日志管理分页查询模型 + """ + page_num: int = 1 + page_size: int = 10 + + +class DeleteJobLogModel(BaseModel): + """ + 删除定时任务日志模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + job_log_ids: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/log_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/log_vo.py similarity index 65% rename from ruoyi-fastapi/module_admin/entity/vo/log_vo.py rename to ruoyi-fastapi-backend/module_admin/entity/vo/log_vo.py index 14aee9135b9d461677cddbdddcbbda869ea19f4e..d410a238de89091f1957025859d640c6bf0bb093 100644 --- a/ruoyi-fastapi/module_admin/entity/vo/log_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/log_vo.py @@ -2,6 +2,7 @@ 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 class OperLogModel(BaseModel): @@ -50,94 +51,61 @@ class OperLogQueryModel(OperLogModel): """ 操作日志管理不分页查询模型 """ - oper_time_start: Optional[str] - oper_time_end: Optional[str] + begin_time: Optional[str] = None + end_time: Optional[str] = None -class OperLogPageObject(OperLogQueryModel): +@as_query +@as_form +class OperLogPageQueryModel(OperLogQueryModel): """ 操作日志管理分页查询模型 """ - page_num: int - page_size: int - - -class OperLogPageObjectResponse(BaseModel): - """ - 操作日志列表分页查询返回模型 - """ - rows: List[Union[OperLogModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool + page_num: int = 1 + page_size: int = 10 class DeleteOperLogModel(BaseModel): """ 删除操作日志模型 """ - oper_ids: str - + model_config = ConfigDict(alias_generator=to_camel) -class ClearOperLogModel(BaseModel): - """ - 清除操作日志模型 - """ - oper_type: str + oper_ids: str class LoginLogQueryModel(LogininforModel): """ 登录日志管理不分页查询模型 """ - login_time_start: Optional[str] - login_time_end: Optional[str] + begin_time: Optional[str] = None + end_time: Optional[str] = None -class LoginLogPageObject(LoginLogQueryModel): - """ - 登录日志管理分页查询模型 - """ - page_num: int - page_size: int - -class LoginLogPageObjectResponse(BaseModel): +@as_query +@as_form +class LoginLogPageQueryModel(LoginLogQueryModel): """ - 登录日志列表分页查询返回模型 + 登录日志管理分页查询模型 """ - rows: List[Union[LogininforModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool + page_num: int = 1 + page_size: int = 10 class DeleteLoginLogModel(BaseModel): """ 删除登录日志模型 """ - info_ids: str + model_config = ConfigDict(alias_generator=to_camel) - -class ClearLoginLogModel(BaseModel): - """ - 清除登录日志模型 - """ - oper_type: str + info_ids: str class UnlockUser(BaseModel): """ 解锁用户模型 """ - user_name: str - + model_config = ConfigDict(alias_generator=to_camel) -class CrudLogResponse(BaseModel): - """ - 操作各类日志响应模型 - """ - is_success: bool - message: str + user_name: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/login_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/login_vo.py similarity index 75% rename from ruoyi-fastapi/module_admin/entity/vo/login_vo.py rename to ruoyi-fastapi-backend/module_admin/entity/vo/login_vo.py index 6c1ba121df6510c805e5af1bcb15295cc46a542c..09a595f2a7cbbaf257045debc372790010e2d0a0 100644 --- a/ruoyi-fastapi/module_admin/entity/vo/login_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/login_vo.py @@ -14,6 +14,16 @@ class UserLogin(BaseModel): captcha_enabled: Optional[bool] = None +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 + + class Token(BaseModel): access_token: str token_type: str @@ -23,6 +33,7 @@ class CaptchaCode(BaseModel): model_config = ConfigDict(alias_generator=to_camel) captcha_enabled: bool + register_enabled: bool img: str uuid: str diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/menu_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/menu_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..08f22e187b26a12cab6b726ef4ee06214f3905db --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/menu_vo.py @@ -0,0 +1,50 @@ +from pydantic import BaseModel, ConfigDict +from pydantic.alias_generators import to_camel +from datetime import datetime +from typing import Union, Optional, List +from module_admin.annotation.pydantic_annotation import as_query + + +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 + + +@as_query +class MenuQueryModel(MenuModel): + """ + 菜单管理不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +class DeleteMenuModel(BaseModel): + """ + 删除菜单模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + menu_ids: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/notice_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/notice_vo.py similarity index 30% rename from ruoyi-fastapi/module_admin/entity/vo/notice_vo.py rename to ruoyi-fastapi-backend/module_admin/entity/vo/notice_vo.py index 1e5c0b9562a9d30ab98746c6adaf4eaeabed6b73..8403fa24a4736d75a9e5a50448caa9218c9b8b17 100644 --- a/ruoyi-fastapi/module_admin/entity/vo/notice_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/notice_vo.py @@ -1,63 +1,50 @@ -from pydantic import BaseModel +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 class NoticeModel(BaseModel): """ 通知公告表对应pydantic模型 """ - notice_id: Optional[int] - notice_title: Optional[str] - notice_type: Optional[str] - notice_content: Optional[bytes] - status: Optional[str] - create_by: Optional[str] - create_time: Optional[str] - update_by: Optional[str] - update_time: Optional[str] - remark: Optional[str] + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) - class Config: - 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 class NoticeQueryModel(NoticeModel): """ 通知公告管理不分页查询模型 """ - create_time_start: Optional[str] - create_time_end: Optional[str] + begin_time: Optional[str] = None + end_time: Optional[str] = None -class NoticePageObject(NoticeQueryModel): +@as_query +@as_form +class NoticePageQueryModel(NoticeQueryModel): """ 通知公告管理分页查询模型 """ - page_num: int - page_size: int - - -class NoticePageObjectResponse(BaseModel): - """ - 通知公告管理列表分页查询返回模型 - """ - rows: List[Union[NoticeModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class CrudNoticeResponse(BaseModel): - """ - 操作通知公告响应模型 - """ - is_success: bool - message: str + page_num: int = 1 + page_size: int = 10 class DeleteNoticeModel(BaseModel): """ 删除通知公告模型 """ + model_config = ConfigDict(alias_generator=to_camel) + notice_ids: str diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/online_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/online_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..616fd2a33b3531779767787c4ac6aa0b1fd6a264 --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/online_vo.py @@ -0,0 +1,39 @@ +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 + + +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 + + +@as_query +class OnlineQueryModel(OnlineModel): + """ + 岗位管理不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +class DeleteOnlineModel(BaseModel): + """ + 强退在线用户模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + token_ids: str diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/post_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/post_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..8ba34958fcf78c2d4f2f82b36fcfd5d6da8b18e4 --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/post_vo.py @@ -0,0 +1,50 @@ +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 + + +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 + + +class PostQueryModel(PostModel): + """ + 岗位管理不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +@as_query +@as_form +class PostPageQueryModel(PostQueryModel): + """ + 岗位管理分页查询模型 + """ + page_num: int = 1 + page_size: int = 10 + + +class DeletePostModel(BaseModel): + """ + 删除岗位模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + post_ids: str diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/role_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/role_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..5ec58f11e923a9b8d3a5b94da4728549f2aafe14 --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/role_vo.py @@ -0,0 +1,127 @@ +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 + + +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 + + @field_validator('menu_check_strictly', 'dept_check_strictly') + @classmethod + def check_filed_mapping(cls, v: Union[int, bool]) -> Union[int, bool]: + if v == 1: + v = True + elif v == 0: + v = False + elif v is True: + v = 1 + elif v is False: + v = 0 + return v + + @model_validator(mode='after') + def check_admin(self) -> 'RoleModel': + if self.role_id == 1: + self.admin = True + else: + self.admin = False + return self + + +class RoleMenuModel(BaseModel): + """ + 角色和菜单关联表对应pydantic模型 + """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) + + role_id: Optional[int] = None + menu_id: Optional[int] = None + + +class RoleDeptModel(BaseModel): + """ + 角色和部门关联表对应pydantic模型 + """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) + + role_id: Optional[int] = None + dept_id: Optional[int] = None + + +class RoleQueryModel(RoleModel): + """ + 角色管理不分页查询模型 + """ + begin_time: Optional[str] = None + end_time: Optional[str] = None + + +@as_query +@as_form +class RolePageQueryModel(RoleQueryModel): + """ + 角色管理分页查询模型 + """ + page_num: int = 1 + page_size: int = 10 + + +class RoleMenuQueryModel(BaseModel): + """ + 角色菜单查询模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + menus: List = [] + checked_keys: List[int] = [] + + +class RoleDeptQueryModel(BaseModel): + """ + 角色部门查询模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + depts: List = [] + checked_keys: List[int] = [] + + +class AddRoleModel(RoleModel): + """ + 新增角色模型 + """ + dept_ids: List = [] + menu_ids: List = [] + type: Optional[str] = None + + +class DeleteRoleModel(BaseModel): + """ + 删除角色模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + + role_ids: str + update_by: Optional[str] = None + update_time: Optional[datetime] = None diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/server_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/server_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..4323ddfab2e7b6eb2b56dc52f83fe25fb8e65a0a --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/server_vo.py @@ -0,0 +1,66 @@ +from pydantic import BaseModel, ConfigDict +from pydantic.alias_generators import to_camel +from typing import Optional, List + + +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 + + +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 + + +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 + + +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 + + +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 + + +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]] diff --git a/ruoyi-fastapi/module_admin/entity/vo/user_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/user_vo.py similarity index 54% rename from ruoyi-fastapi/module_admin/entity/vo/user_vo.py rename to ruoyi-fastapi-backend/module_admin/entity/vo/user_vo.py index 6ba811a4228870b888ca5b25a31e6ae0417f6f06..fbc39831eb2976d5e6796f0191850f539b1b7352 100644 --- a/ruoyi-fastapi/module_admin/entity/vo/user_vo.py +++ b/ruoyi-fastapi-backend/module_admin/entity/vo/user_vo.py @@ -1,9 +1,11 @@ -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, model_validator from pydantic.alias_generators import to_camel from typing import Union, Optional, List from datetime import datetime +from module_admin.entity.vo.role_vo import RoleModel from module_admin.entity.vo.dept_vo import DeptModel -from module_admin.annotation.form_annotation import as_form +from module_admin.entity.vo.post_vo import PostModel +from module_admin.annotation.pydantic_annotation import as_query, as_form class TokenData(BaseModel): @@ -38,6 +40,15 @@ class UserModel(BaseModel): update_by: Optional[str] = None update_time: Optional[datetime] = None remark: Optional[str] = None + admin: Optional[bool] = False + + @model_validator(mode='after') + def check_admin(self) -> 'UserModel': + if self.user_id == 1: + self.admin = True + else: + self.admin = False + return self class UserRoleModel(BaseModel): @@ -60,64 +71,11 @@ class UserPostModel(BaseModel): post_id: Optional[int] = None -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[int] = None - dept_check_strictly: Optional[int] = 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 - - -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 - - -class CurrentUserInfo(BaseModel): - """ - 数据库返回当前用户信息 - """ - model_config = ConfigDict(alias_generator=to_camel) - - user_basic_info: List[Union[UserModel, None]] - user_dept_info: List[Union[DeptModel, None]] - user_role_info: List[Union[RoleModel, None]] - user_post_info: List[Union[PostModel, None]] - user_menu_info: Union[List, None] - - class UserInfoModel(UserModel): - post_ids: Union[str, None] - role_ids: Union[str, None] - dept: Union[DeptModel, None] - role: List[Union[RoleModel, None]] + 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]]] = [] class CurrentUserModel(BaseModel): @@ -152,13 +110,6 @@ class UserProfileModel(BaseModel): role_group: Union[str, None] -class CurrentUserInfoServiceResponse(UserDetailModel): - """ - 获取当前用户信息响应模型 - """ - menu: Union[List, None] - - class UserQueryModel(UserModel): """ 用户管理不分页查询模型 @@ -167,13 +118,14 @@ class UserQueryModel(UserModel): end_time: Optional[str] = None +@as_query @as_form class UserPageQueryModel(UserQueryModel): """ 用户管理分页查询模型 """ - page_num: int - page_size: int + page_num: int = 1 + page_size: int = 10 class AddUserModel(UserModel): @@ -212,91 +164,47 @@ class DeleteUserModel(BaseModel): update_time: Optional[datetime] = None -class UserRoleQueryModel(UserRoleModel): +class UserRoleQueryModel(UserModel): """ 用户角色关联管理不分页查询模型 """ - user_name: Optional[str] = None - phonenumber: Optional[str] = None - role_name: Optional[str] = None - role_key: Optional[str] = None + role_id: Optional[int] = None -class UserRolePageObject(UserRoleQueryModel): +@as_query +class UserRolePageQueryModel(UserRoleQueryModel): """ 用户角色关联管理分页查询模型 """ - page_num: int - page_size: int - - -class UserRolePageObjectResponse(BaseModel): - """ - 用户角色关联管理列表分页查询返回模型 - """ - model_config = ConfigDict(alias_generator=to_camel) - - rows: List = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class CrudUserRoleModel(BaseModel): - """ - 新增、删除用户关联角色及角色关联用户模型 - """ - model_config = ConfigDict(alias_generator=to_camel) - - user_ids: Optional[str] = None - role_ids: Optional[str] = None - - -class ImportUserModel(BaseModel): - """ - 批量导入用户模型 - """ - model_config = ConfigDict(alias_generator=to_camel) - - url: str - is_update: bool + page_num: int = 1 + page_size: int = 10 -class CrudUserResponse(BaseModel): +class SelectedRoleModel(RoleModel): """ - 操作用户响应模型 + 是否选择角色模型 """ - model_config = ConfigDict(alias_generator=to_camel) - - is_success: bool - message: str + flag: Optional[bool] = False -class DeptInfo(BaseModel): +class UserRoleResponseModel(BaseModel): """ - 查询部门树 + 用户角色关联管理列表返回模型 """ model_config = ConfigDict(alias_generator=to_camel) - dept_id: int - dept_name: str - ancestors: str + roles: List[Union[SelectedRoleModel, None]] = [] + user: UserInfoModel -class RoleInfo(BaseModel): - """ - 用户角色信息 - """ - model_config = ConfigDict(alias_generator=to_camel) - - role_info: Union[List, None] - - -class MenuList(BaseModel): +@as_query +class CrudUserRoleModel(BaseModel): """ - 用户菜单信息 + 新增、删除用户关联角色及角色关联用户模型 """ model_config = ConfigDict(alias_generator=to_camel) - menu_info: Union[List, None] + user_id: Optional[int] = None + user_ids: Optional[str] = None + role_id: Optional[int] = None + role_ids: Optional[str] = None diff --git a/ruoyi-fastapi/module_admin/service/cache_service.py b/ruoyi-fastapi-backend/module_admin/service/cache_service.py similarity index 80% rename from ruoyi-fastapi/module_admin/service/cache_service.py rename to ruoyi-fastapi-backend/module_admin/service/cache_service.py index 1b0f92bfed50e7a57c8377ff67684e03d7af543d..d021ef4a8c491619074c3979824686c2dfb119fd 100644 --- a/ruoyi-fastapi/module_admin/service/cache_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/cache_service.py @@ -2,7 +2,7 @@ from fastapi import Request from module_admin.entity.vo.cache_vo import * from config.env import RedisInitKeyConfig from config.get_redis import RedisUtil - +from module_admin.entity.vo.common_vo import CrudResponseModel class CacheService: """ @@ -21,9 +21,13 @@ class CacheService: 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 = dict(command_stats=command_stats, db_size=db_size, info=info) + result = CacheMonitorModel( + commandStats=command_stats, + dbSize=db_size, + info=info + ) - return CacheMonitorModel(**result) + return result @classmethod def get_cache_monitor_cache_name_services(cls): @@ -36,9 +40,9 @@ class CacheService: if not attr_name.startswith('__') and isinstance(getattr(RedisInitKeyConfig, attr_name), dict): name_list.append( CacheInfoModel( - cache_key="", - cache_name=getattr(RedisInitKeyConfig, attr_name).get('key'), - cache_value="", + cacheKey="", + cacheName=getattr(RedisInitKeyConfig, attr_name).get('key'), + cacheValue="", remark=getattr(RedisInitKeyConfig, attr_name).get('remark') ) ) @@ -69,7 +73,7 @@ class CacheService: """ cache_value = await request.app.state.redis.get(f"{cache_name}:{cache_key}") - return CacheInfoModel(cache_key=cache_key, cache_name=cache_name, cache_value=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): @@ -84,21 +88,22 @@ class CacheService: await request.app.state.redis.delete(*cache_keys) result = dict(is_success=True, message=f"{cache_name}对应键值清除成功") - return CrudCacheResponse(**result) + return CrudResponseModel(**result) @classmethod - async def clear_cache_monitor_cache_key_services(cls, request: Request, cache_name: str, cache_key: str): + async def clear_cache_monitor_cache_key_services(cls, request: Request, cache_key: str): """ 清除缓存名称对应所有键值service :param request: Request对象 - :param cache_name: 缓存名称 :param cache_key: 缓存键名 :return: 操作缓存响应信息 """ - await request.app.state.redis.delete(f"{cache_name}:{cache_key}") - result = dict(is_success=True, message=f"{cache_name}:{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 CrudCacheResponse(**result) + return CrudResponseModel(**result) @classmethod async def clear_cache_monitor_all_services(cls, request: Request): @@ -115,4 +120,4 @@ class CacheService: await RedisUtil.init_sys_dict(request.app.state.redis) await RedisUtil.init_sys_config(request.app.state.redis) - return CrudCacheResponse(**result) + return CrudResponseModel(**result) diff --git a/ruoyi-fastapi/module_admin/service/captcha_service.py b/ruoyi-fastapi-backend/module_admin/service/captcha_service.py similarity index 100% rename from ruoyi-fastapi/module_admin/service/captcha_service.py rename to ruoyi-fastapi-backend/module_admin/service/captcha_service.py diff --git a/ruoyi-fastapi-backend/module_admin/service/common_service.py b/ruoyi-fastapi-backend/module_admin/service/common_service.py new file mode 100644 index 0000000000000000000000000000000000000000..7c8399dbb58e4576f6d6852edb0aa9fb88db4e6b --- /dev/null +++ b/ruoyi-fastapi-backend/module_admin/service/common_service.py @@ -0,0 +1,87 @@ +from fastapi import Request, BackgroundTasks +import os +from fastapi import UploadFile +from datetime import datetime +from config.env import UploadConfig +from module_admin.entity.vo.common_vo import * +from utils.upload_util import UploadUtil + + +class CommonService: + """ + 通用模块服务层 + """ + + @classmethod + 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='文件类型不合法') + 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) + try: + os.makedirs(dir_path) + except FileExistsError: + pass + filename = f'{file.filename.rsplit(".", 1)[0]}_{datetime.now().strftime("%Y%m%d%H%M%S")}{UploadConfig.UPLOAD_MACHINE}{UploadUtil.generate_random_number()}.{file.filename.rsplit(".")[-1]}' + filepath = os.path.join(dir_path, filename) + with open(filepath, 'wb') as f: + # 流式写出大型文件,这里的10代表10MB + for chunk in iter(lambda: file.file.read(1024 * 1024 * 10), b''): + f.write(chunk) + + result = dict( + 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}' + ), + message='上传成功' + ) + + return CrudResponseModel(**result) + + @classmethod + def download_services(cls, background_tasks: BackgroundTasks, file_name, delete: bool): + """ + 下载下载目录文件service + :param background_tasks: 后台任务对象 + :param file_name: 下载的文件名称 + :param delete: 是否在下载完成后删除文件 + :return: 上传结果 + """ + filepath = os.path.join(UploadConfig.DOWNLOAD_PATH, file_name) + if '..' in file_name: + result = dict(is_success=False, message='文件名称不合法') + elif not UploadUtil.check_file_exists(filepath): + result = dict(is_success=False, 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) + + @classmethod + 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='文件名称不合法') + elif not UploadUtil.check_file_exists(filepath): + result = dict(is_success=False, message='文件不存在') + else: + result = dict(is_success=True, result=UploadUtil.generate_file(filepath), message='下载成功') + return CrudResponseModel(**result) diff --git a/ruoyi-fastapi/module_admin/service/config_service.py b/ruoyi-fastapi-backend/module_admin/service/config_service.py similarity index 78% rename from ruoyi-fastapi/module_admin/service/config_service.py rename to ruoyi-fastapi-backend/module_admin/service/config_service.py index 2177e22f18d25f0ac988c18c0556534a28b32baa..1ab439bf9a6682fe251557a0c5da0b9e5ce74b2a 100644 --- a/ruoyi-fastapi/module_admin/service/config_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/config_service.py @@ -1,8 +1,8 @@ from fastapi import Request from config.env import RedisInitKeyConfig -from module_admin.entity.vo.config_vo import * from module_admin.dao.config_dao import * -from utils.common_util import export_list2excel +from module_admin.entity.vo.common_vo import CrudResponseModel +from utils.common_util import export_list2excel, CamelCaseUtil class ConfigService: @@ -11,14 +11,15 @@ class ConfigService: """ @classmethod - def get_config_list_services(cls, query_db: Session, query_object: ConfigQueryModel): + def get_config_list_services(cls, query_db: Session, 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) + config_list_result = ConfigDao.get_config_list(query_db, query_object, is_page) return config_list_result @@ -35,10 +36,10 @@ class ConfigService: # 删除匹配的键 if keys: await redis.delete(*keys) - config_all = ConfigDao.get_config_list(query_db, ConfigQueryModel(**dict())) + config_all = ConfigDao.get_config_list(query_db, ConfigPageQueryModel(**dict()), is_page=False) for config_obj in config_all: - if config_obj.config_type == 'Y': - await redis.set(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_obj.config_key}", config_obj.config_value) + if config_obj.get('configType') == 'Y': + await redis.set(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_obj.get('configKey')}", config_obj.get('configValue')) @classmethod async def query_config_list_from_cache_services(cls, redis, config_key: str): @@ -61,7 +62,7 @@ class ConfigService: :param page_object: 新增参数配置对象 :return: 新增参数配置校验结果 """ - config = ConfigDao.get_config_detail_by_info(query_db, ConfigModel(**dict(config_key=page_object.config_key))) + config = ConfigDao.get_config_detail_by_info(query_db, ConfigModel(configKey=page_object.config_key)) if config: result = dict(is_success=False, message='参数键名已存在') else: @@ -72,9 +73,9 @@ class ConfigService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudConfigResponse(**result) + return CrudResponseModel(**result) @classmethod async def edit_config_services(cls, request: Request, query_db: Session, page_object: ConfigModel): @@ -85,14 +86,14 @@ class ConfigService: :param page_object: 编辑参数配置对象 :return: 编辑参数配置校验结果 """ - edit_config = page_object.dict(exclude_unset=True) - config_info = cls.detail_config_services(query_db, edit_config.get('config_id')) + 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 CrudConfigResponse(**result) + return CrudResponseModel(**result) try: ConfigDao.edit_config_dao(query_db, edit_config) query_db.commit() @@ -100,11 +101,11 @@ class ConfigService: result = dict(is_success=True, message='更新成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='参数配置不存在') - return CrudConfigResponse(**result) + return CrudResponseModel(**result) @classmethod async def delete_config_services(cls, request: Request, query_db: Session, page_object: DeleteConfigModel): @@ -119,20 +120,19 @@ class ConfigService: config_id_list = page_object.config_ids.split(',') try: for config_id in config_id_list: - config_id_dict = dict(config_id=config_id) - ConfigDao.delete_config_dao(query_db, ConfigModel(**config_id_dict)) + 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='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入字典数据id为空') - return CrudConfigResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_config_services(cls, query_db: Session, config_id: int): + def config_detail_services(cls, query_db: Session, config_id: int): """ 获取参数配置详细信息service :param query_db: orm对象 @@ -140,8 +140,9 @@ class ConfigService: :return: 参数配置id对应的信息 """ config = ConfigDao.get_config_detail_by_id(query_db, config_id=config_id) + result = ConfigModel(**CamelCaseUtil.transform_result(config)) - return config + return result @staticmethod def export_config_list_services(config_list: List): @@ -152,25 +153,25 @@ class ConfigService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "config_id": "参数主键", - "config_name": "参数名称", - "config_key": "参数键名", - "config_value": "参数键值", - "config_type": "系统内置", - "create_by": "创建者", - "create_time": "创建时间", - "update_by": "更新者", - "update_time": "更新时间", + "configId": "参数主键", + "configName": "参数名称", + "configKey": "参数键名", + "configValue": "参数键值", + "configType": "系统内置", + "createBy": "创建者", + "createTime": "创建时间", + "updateBy": "更新者", + "updateTime": "更新时间", "remark": "备注", } - data = [ConfigModel(**vars(row)).dict() for row in config_list] + data = config_list for item in data: - if item.get('config_type') == 'Y': - item['config_type'] = '是' + if item.get('configType') == 'Y': + item['configType'] = '是' else: - item['config_type'] = '否' + item['configType'] = '否' 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) @@ -187,4 +188,4 @@ class ConfigService: await cls.init_cache_sys_config_services(query_db, request.app.state.redis) result = dict(is_success=True, message='刷新成功') - return CrudConfigResponse(**result) + return CrudResponseModel(**result) diff --git a/ruoyi-fastapi/module_admin/service/dept_service.py b/ruoyi-fastapi-backend/module_admin/service/dept_service.py similarity index 69% rename from ruoyi-fastapi/module_admin/service/dept_service.py rename to ruoyi-fastapi-backend/module_admin/service/dept_service.py index 1771e183b5e268a5b339336edd9566a4d73e9256..2c9db676697f9302eef9d60a5268715b9bf40e7f 100644 --- a/ruoyi-fastapi/module_admin/service/dept_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/dept_service.py @@ -1,5 +1,6 @@ -from module_admin.entity.vo.dept_vo import * from module_admin.dao.dept_dao import * +from module_admin.entity.vo.common_vo import CrudResponseModel +from utils.common_util import CamelCaseUtil class DeptService: @@ -22,7 +23,7 @@ class DeptService: return dept_tree_result @classmethod - def get_dept_tree_for_edit_option_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str): + def get_dept_for_edit_option_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str): """ 获取部门编辑部门树信息service :param query_db: orm对象 @@ -31,9 +32,8 @@ class DeptService: :return: 部门树信息对象 """ dept_list_result = DeptDao.get_dept_info_for_edit_option(query_db, page_object, data_scope_sql) - dept_tree_result = cls.list_to_tree(dept_list_result) - return dept_tree_result + return CamelCaseUtil.transform_result(dept_list_result) @classmethod def get_dept_list_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str): @@ -46,7 +46,7 @@ class DeptService: """ dept_list_result = DeptDao.get_dept_list(query_db, page_object, data_scope_sql) - return dept_list_result + return CamelCaseUtil.transform_result(dept_list_result) @classmethod def add_dept_services(cls, query_db: Session, page_object: DeptModel): @@ -61,7 +61,8 @@ class DeptService: 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(**dict(parent_id=page_object.parent_id, 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='同一部门下不允许存在同名的部门') else: @@ -71,9 +72,9 @@ class DeptService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudDeptResponse(**result) + return CrudResponseModel(**result) @classmethod def edit_dept_services(cls, query_db: Session, page_object: DeptModel): @@ -88,32 +89,32 @@ class DeptService: page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}' else: page_object.ancestors = '0' - edit_dept = page_object.dict(exclude_unset=True) - dept_info = cls.detail_dept_services(query_db, edit_dept.get('dept_id')) + 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( - **dict(parent_id=page_object.parent_id, 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 CrudDeptResponse(**result) + return CrudResponseModel(**result) try: DeptDao.edit_dept_dao(query_db, edit_dept) - cls.update_children_info(query_db, DeptModel(dept_id=page_object.dept_id, - ancestors=page_object.ancestors, - update_by=page_object.update_by, - update_time=page_object.update_time - ) + 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() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='部门不存在') - return CrudDeptResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_dept_services(cls, query_db: Session, page_object: DeleteDeptModel): @@ -132,21 +133,20 @@ class DeptService: if dept_id in ancestor[0]: result = dict(is_success=False, message='该部门下有子部门,不允许删除') - return CrudDeptResponse(**result) + return CrudResponseModel(**result) - dept_id_dict = dict(dept_id=dept_id) - DeptDao.delete_dept_dao(query_db, DeptModel(**dept_id_dict)) + DeptDao.delete_dept_dao(query_db, DeptModel(deptId=dept_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入部门id为空') - return CrudDeptResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_dept_services(cls, query_db: Session, dept_id: int): + def dept_detail_services(cls, query_db: Session, dept_id: int): """ 获取部门详细信息service :param query_db: orm对象 @@ -154,8 +154,9 @@ class DeptService: :return: 部门id对应的信息 """ dept = DeptDao.get_dept_detail_by_id(query_db, dept_id=dept_id) + result = DeptModel(**CamelCaseUtil.transform_result(dept)) - return dept + return result @classmethod def list_to_tree(cls, permission_list: list) -> list: @@ -164,8 +165,9 @@ class DeptService: :param permission_list: 部门列表信息 :return: 部门树形嵌套数据 """ - permission_list = [dict(id=item.dept_id, label=item.dept_name, parentId=item.parent_id) for item in permission_list] - # 转成dept_id为key的字典 + 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)) # 树容器 @@ -185,32 +187,6 @@ class DeptService: return container - @classmethod - def get_dept_tree(cls, pid: int, permission_list: DeptTree): - """ - 工具方法:根据部门信息生成树形嵌套数据 - :param pid: 部门id - :param permission_list: 部门列表信息 - :return: 部门树形嵌套数据 - """ - dept_list = [] - for permission in permission_list.dept_tree: - if permission.parent_id == pid: - children = cls.get_dept_tree(permission.dept_id, permission_list) - dept_list_data = {} - if children: - dept_list_data['title'] = permission.dept_name - dept_list_data['key'] = str(permission.dept_id) - dept_list_data['value'] = str(permission.dept_id) - dept_list_data['children'] = children - else: - dept_list_data['title'] = permission.dept_name - dept_list_data['key'] = str(permission.dept_id) - dept_list_data['value'] = str(permission.dept_id) - dept_list.append(dept_list_data) - - return dept_list - @classmethod def update_children_info(cls, query_db, page_object): """ @@ -231,7 +207,7 @@ class DeptService: ) ) 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 - )) + ancestors=child.ancestors, + update_by=page_object.update_by, + update_time=page_object.update_time + )) diff --git a/ruoyi-fastapi/module_admin/service/dict_service.py b/ruoyi-fastapi-backend/module_admin/service/dict_service.py similarity index 77% rename from ruoyi-fastapi/module_admin/service/dict_service.py rename to ruoyi-fastapi-backend/module_admin/service/dict_service.py index 83ea25e1100b8fa7e11a6f0ac70d1a76b39b507f..29dae05ddea257052891c19fe167f3230769ff63 100644 --- a/ruoyi-fastapi/module_admin/service/dict_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/dict_service.py @@ -1,8 +1,8 @@ from fastapi import Request import json from config.env import RedisInitKeyConfig -from module_admin.entity.vo.dict_vo import * from module_admin.dao.dict_dao import * +from module_admin.entity.vo.common_vo import CrudResponseModel from utils.common_util import export_list2excel, CamelCaseUtil @@ -12,25 +12,15 @@ class DictTypeService: """ @classmethod - def get_dict_type_list_services(cls, query_db: Session, query_object: DictTypeQueryModel): + def get_dict_type_list_services(cls, query_db: Session, 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) - - return dict_type_list_result - - @classmethod - def get_all_dict_type_services(cls, query_db: Session): - """ - 获取字所有典类型列表信息service - :param query_db: orm对象 - :return: 字典类型列表信息对象 - """ - dict_type_list_result = DictTypeDao.get_all_dict_type(query_db) + dict_type_list_result = DictTypeDao.get_dict_type_list(query_db, query_object, is_page) return dict_type_list_result @@ -43,7 +33,7 @@ class DictTypeService: :param page_object: 新增岗位对象 :return: 新增字典类型校验结果 """ - dict_type = DictTypeDao.get_dict_type_detail_by_info(query_db, DictTypeModel(**dict(dict_type=page_object.dict_type))) + 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='字典类型已存在') else: @@ -54,9 +44,9 @@ class DictTypeService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudDictResponse(**result) + return CrudResponseModel(**result) @classmethod async def edit_dict_type_services(cls, request: Request, query_db: Session, page_object: DictTypeModel): @@ -67,21 +57,20 @@ class DictTypeService: :param page_object: 编辑字典类型对象 :return: 编辑字典类型校验结果 """ - edit_dict_type = page_object.dict(exclude_unset=True) - dict_type_info = cls.detail_dict_type_services(query_db, edit_dict_type.get('dict_id')) + 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( - **dict(dict_type=page_object.dict_type))) + 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 CrudDictResponse(**result) + return CrudResponseModel(**result) try: if dict_type_info.dict_type != page_object.dict_type: - query_dict_data = DictDataModel(**(dict(dict_type=dict_type_info.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(**(dict(dict_code=dict_data.dict_code, dict_type=page_object.dict_type, update_by=page_object.update_by))).dict(exclude_unset=True) + 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() @@ -89,11 +78,11 @@ class DictTypeService: result = dict(is_success=True, message='更新成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='字典类型不存在') - return CrudDictResponse(**result) + return CrudResponseModel(**result) @classmethod async def delete_dict_type_services(cls, request: Request, query_db: Session, page_object: DeleteDictTypeModel): @@ -108,20 +97,19 @@ class DictTypeService: dict_id_list = page_object.dict_ids.split(',') try: for dict_id in dict_id_list: - dict_id_dict = dict(dict_id=dict_id) - DictTypeDao.delete_dict_type_dao(query_db, DictTypeModel(**dict_id_dict)) + 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='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入字典类型id为空') - return CrudDictResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_dict_type_services(cls, query_db: Session, dict_id: int): + def dict_type_detail_services(cls, query_db: Session, dict_id: int): """ 获取字典类型详细信息service :param query_db: orm对象 @@ -129,8 +117,9 @@ class DictTypeService: :return: 字典类型id对应的信息 """ dict_type = DictTypeDao.get_dict_type_detail_by_id(query_db, dict_id=dict_id) + result = DictTypeModel(**CamelCaseUtil.transform_result(dict_type)) - return dict_type + return result @staticmethod def export_dict_type_list_services(dict_type_list: List): @@ -141,18 +130,18 @@ class DictTypeService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "dict_id": "字典编号", - "dict_name": "字典名称", - "dict_type": "字典类型", + "dictId": "字典编号", + "dictName": "字典名称", + "dictType": "字典类型", "status": "状态", - "create_by": "创建者", - "create_time": "创建时间", - "update_by": "更新者", - "update_time": "更新时间", + "createBy": "创建者", + "createTime": "创建时间", + "updateBy": "更新者", + "updateTime": "更新时间", "remark": "备注", } - data = [DictTypeModel(**vars(row)).dict() for row in dict_type_list] + data = dict_type_list for item in data: if item.get('status') == '0': @@ -175,7 +164,7 @@ class DictTypeService: await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis) result = dict(is_success=True, message='刷新成功') - return CrudDictResponse(**result) + return CrudResponseModel(**result) class DictDataService: @@ -184,14 +173,15 @@ class DictDataService: """ @classmethod - def get_dict_data_list_services(cls, query_db: Session, query_object: DictDataModel): + def get_dict_data_list_services(cls, query_db: Session, 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) + dict_data_list_result = DictDataDao.get_dict_data_list(query_db, query_object, is_page) return dict_data_list_result @@ -224,8 +214,8 @@ class DictDataService: 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 = [DictDataModel(**vars(row)).dict() 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)) + 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)) @classmethod async def query_dict_data_list_from_cache_services(cls, redis, dict_type: str): @@ -262,9 +252,9 @@ class DictDataService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudDictResponse(**result) + return CrudResponseModel(**result) @classmethod async def edit_dict_data_services(cls, request: Request, query_db: Session, page_object: DictDataModel): @@ -275,14 +265,14 @@ class DictDataService: :param page_object: 编辑字典数据对象 :return: 编辑字典数据校验结果 """ - edit_data_type = page_object.dict(exclude_unset=True) - dict_data_info = cls.detail_dict_data_services(query_db, edit_data_type.get('dict_code')) + 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 CrudDictResponse(**result) + return CrudResponseModel(**result) try: DictDataDao.edit_dict_data_dao(query_db, edit_data_type) query_db.commit() @@ -290,11 +280,11 @@ class DictDataService: result = dict(is_success=True, message='更新成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='字典数据不存在') - return CrudDictResponse(**result) + return CrudResponseModel(**result) @classmethod async def delete_dict_data_services(cls, request: Request, query_db: Session, page_object: DeleteDictDataModel): @@ -309,20 +299,19 @@ class DictDataService: dict_code_list = page_object.dict_codes.split(',') try: for dict_code in dict_code_list: - dict_code_dict = dict(dict_code=dict_code) - DictDataDao.delete_dict_data_dao(query_db, DictDataModel(**dict_code_dict)) + 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='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入字典数据id为空') - return CrudDictResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_dict_data_services(cls, query_db: Session, dict_code: int): + def dict_data_detail_services(cls, query_db: Session, dict_code: int): """ 获取字典数据详细信息service :param query_db: orm对象 @@ -330,8 +319,9 @@ class DictDataService: :return: 字典数据id对应的信息 """ dict_data = DictDataDao.get_dict_data_detail_by_id(query_db, dict_code=dict_code) + result = DictDataModel(**CamelCaseUtil.transform_result(dict_data)) - return dict_data + return result @staticmethod def export_dict_data_list_services(dict_data_list: List): @@ -342,33 +332,33 @@ class DictDataService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "dict_code": "字典编码", - "dict_sort": "字典标签", - "dict_label": "字典键值", - "dict_value": "字典排序", - "dict_type": "字典类型", - "css_class": "样式属性", - "list_class": "表格回显样式", - "is_default": "是否默认", + "dictCode": "字典编码", + "dictSort": "字典标签", + "dictLabel": "字典键值", + "dictValue": "字典排序", + "dictType": "字典类型", + "cssClass": "样式属性", + "listClass": "表格回显样式", + "isDefault": "是否默认", "status": "状态", - "create_by": "创建者", - "create_time": "创建时间", - "update_by": "更新者", - "update_time": "更新时间", + "createBy": "创建者", + "createTime": "创建时间", + "updateBy": "更新者", + "updateTime": "更新时间", "remark": "备注", } - data = [DictDataModel(**vars(row)).dict() for row in dict_data_list] + data = dict_data_list for item in data: if item.get('status') == '0': item['status'] = '正常' else: item['status'] = '停用' - if item.get('is_default') == 'Y': - item['is_default'] = '是' + if item.get('isDefault') == 'Y': + item['isDefault'] = '是' else: - item['is_default'] = '否' + item['isDefault'] = '否' 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) diff --git a/ruoyi-fastapi/module_admin/service/job_log_service.py b/ruoyi-fastapi-backend/module_admin/service/job_log_service.py similarity index 55% rename from ruoyi-fastapi/module_admin/service/job_log_service.py rename to ruoyi-fastapi-backend/module_admin/service/job_log_service.py index f1eb6ede16122a18d0ca775868ba15c2e56ed171..7de9d05b55dd4febc91e969f5e3a0395487cf9c9 100644 --- a/ruoyi-fastapi/module_admin/service/job_log_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/job_log_service.py @@ -1,6 +1,6 @@ -from module_admin.entity.vo.job_vo import * from module_admin.dao.job_log_dao import * -from module_admin.dao.dict_dao import DictDataDao +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 @@ -10,14 +10,15 @@ class JobLogService: """ @classmethod - def get_job_log_list_services(cls, query_db: Session, query_object: JobLogQueryModel): + def get_job_log_list_services(cls, query_db: Session, 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) + job_log_list_result = JobLogDao.get_job_log_list(query_db, query_object, is_page) return job_log_list_result @@ -37,7 +38,7 @@ class JobLogService: query_db.rollback() result = dict(is_success=False, message=str(e)) - return CrudJobResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_job_log_services(cls, query_db: Session, page_object: DeleteJobLogModel): @@ -51,86 +52,74 @@ class JobLogService: job_log_id_list = page_object.job_log_ids.split(',') try: for job_log_id in job_log_id_list: - job_log_id_dict = dict(job_log_id=job_log_id) - JobLogDao.delete_job_log_dao(query_db, JobLogModel(**job_log_id_dict)) + JobLogDao.delete_job_log_dao(query_db, JobLogModel(jobLogId=job_log_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入定时任务日志id为空') - return CrudJobResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_job_log_services(cls, query_db: Session, job_log_id: int): - """ - 获取定时任务日志详细信息service - :param query_db: orm对象 - :param job_log_id: 定时任务日志id - :return: 定时任务日志id对应的信息 - """ - job_log = JobLogDao.get_job_log_detail_by_id(query_db, job_log_id=job_log_id) - - return job_log - - @classmethod - def clear_job_log_services(cls, query_db: Session, page_object: ClearJobLogModel): + def clear_job_log_services(cls, query_db: Session): """ 清除定时任务日志信息service :param query_db: orm对象 - :param page_object: 清除定时任务日志对象 :return: 清除定时任务日志校验结果 """ - if page_object.oper_type == 'clear': - try: - JobLogDao.clear_job_log_dao(query_db) - query_db.commit() - result = dict(is_success=True, message='清除成功') - except Exception as e: - query_db.rollback() - result = dict(is_success=False, message=str(e)) - else: - result = dict(is_success=False, message='清除标识不合法') + try: + JobLogDao.clear_job_log_dao(query_db) + query_db.commit() + result = dict(is_success=True, message='清除成功') + except Exception as e: + query_db.rollback() + raise e - return CrudJobResponse(**result) + return CrudResponseModel(**result) @staticmethod - def export_job_log_list_services(query_db, job_log_list: List): + async def export_job_log_list_services(request: Request, job_log_list: List): """ 导出定时任务日志信息service - :param query_db: orm对象 + :param request: Request对象 :param job_log_list: 定时任务日志信息列表 :return: 定时任务日志信息对应excel的二进制数据 """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "job_log_id": "任务日志编码", - "job_name": "任务名称", - "job_group": "任务组名", - "job_executor": "任务执行器", - "invoke_target": "调用目标字符串", - "job_args": "位置参数", - "job_kwargs": "关键字参数", - "job_trigger": "任务触发器", - "job_message": "日志信息", + "jobLogId": "任务日志编码", + "jobName": "任务名称", + "jobGroup": "任务组名", + "jobExecutor": "任务执行器", + "invokeTarget": "调用目标字符串", + "jobArgs": "位置参数", + "jobKwargs": "关键字参数", + "jobTrigger": "任务触发器", + "jobMessage": "日志信息", "status": "执行状态", - "exception_info": "异常信息", - "create_time": "创建时间", + "exceptionInfo": "异常信息", + "createTime": "创建时间", } - data = [JobLogModel(**vars(row)).dict() for row in job_log_list] - job_group_list = DictDataDao.query_dict_data_list(query_db, dict_type='sys_job_group') - job_group_option = [dict(label=item.dict_label, value=item.dict_value) for item in job_group_list] + 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_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_option_dict = {item.get('value'): item for item in job_executor_option} for item in data: if item.get('status') == '0': item['status'] = '正常' else: item['status'] = '暂停' - if str(item.get('job_group')) in job_group_option_dict.keys(): - item['job_group'] = job_group_option_dict.get(str(item.get('job_group'))).get('label') + if str(item.get('jobGroup')) in job_group_option_dict.keys(): + 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] binary_data = export_list2excel(new_data) diff --git a/ruoyi-fastapi/module_admin/service/job_service.py b/ruoyi-fastapi-backend/module_admin/service/job_service.py similarity index 69% rename from ruoyi-fastapi/module_admin/service/job_service.py rename to ruoyi-fastapi-backend/module_admin/service/job_service.py index d765ef975540851487f47fb647dd619da53a2241..62887e8424647845c8442a5e476bb5e9ee3f4217 100644 --- a/ruoyi-fastapi/module_admin/service/job_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/job_service.py @@ -1,7 +1,7 @@ -from module_admin.entity.vo.job_vo import * from module_admin.dao.job_dao import * from module_admin.service.dict_service import Request, DictDataService -from utils.common_util import export_list2excel +from module_admin.entity.vo.common_vo import CrudResponseModel +from utils.common_util import export_list2excel, CamelCaseUtil from config.get_scheduler import SchedulerUtil @@ -11,14 +11,15 @@ class JobService: """ @classmethod - def get_job_list_services(cls, query_db: Session, query_object: JobModel): + def get_job_list_services(cls, query_db: Session, 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) + job_list_result = JobDao.get_job_list(query_db, query_object, is_page) return job_list_result @@ -43,9 +44,9 @@ class JobService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudJobResponse(**result) + return CrudResponseModel(**result) @classmethod def edit_job_services(cls, query_db: Session, page_object: EditJobModel): @@ -55,16 +56,16 @@ class JobService: :param page_object: 编辑定时任务对象 :return: 编辑定时任务校验结果 """ - edit_job = page_object.dict(exclude_unset=True) + edit_job = page_object.model_dump(exclude_unset=True) if page_object.type == 'status': del edit_job['type'] - job_info = cls.detail_job_services(query_db, edit_job.get('job_id')) + job_info = cls.job_detail_services(query_db, edit_job.get('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 CrudJobResponse(**result) + return CrudResponseModel(**result) try: JobDao.edit_job_dao(query_db, edit_job) query_job = SchedulerUtil.get_scheduler_job(job_id=edit_job.get('job_id')) @@ -76,11 +77,11 @@ class JobService: result = dict(is_success=True, message='更新成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='定时任务不存在') - return CrudJobResponse(**result) + return CrudResponseModel(**result) @classmethod def execute_job_once_services(cls, query_db: Session, page_object: JobModel): @@ -93,14 +94,14 @@ class JobService: 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.detail_job_services(query_db, page_object.job_id) + job_info = 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='执行成功') else: result = dict(is_success=False, message='定时任务不存在') - return CrudJobResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_job_services(cls, query_db: Session, page_object: DeleteJobModel): @@ -114,19 +115,18 @@ class JobService: job_id_list = page_object.job_ids.split(',') try: for job_id in job_id_list: - job_id_dict = dict(job_id=job_id) - JobDao.delete_job_dao(query_db, JobModel(**job_id_dict)) + JobDao.delete_job_dao(query_db, JobModel(jobId=job_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入定时任务id为空') - return CrudJobResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_job_services(cls, query_db: Session, job_id: int): + def job_detail_services(cls, query_db: Session, job_id: int): """ 获取定时任务详细信息service :param query_db: orm对象 @@ -134,8 +134,9 @@ class JobService: :return: 定时任务id对应的信息 """ job = JobDao.get_job_detail_by_id(query_db, job_id=job_id) + result = JobModel(**CamelCaseUtil.transform_result(job)) - return job + return result @staticmethod async def export_job_list_services(request: Request, job_list: List): @@ -147,42 +148,47 @@ class JobService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "job_id": "任务编码", - "job_name": "任务名称", - "job_group": "任务组名", - "job_executor": "任务执行器", - "invoke_target": "调用目标字符串", - "job_args": "位置参数", - "job_kwargs": "关键字参数", - "cron_expression": "cron执行表达式", - "misfire_policy": "计划执行错误策略", + "jobId": "任务编码", + "jobName": "任务名称", + "jobGroup": "任务组名", + "jobExecutor": "任务执行器", + "invokeTarget": "调用目标字符串", + "jobArgs": "位置参数", + "jobKwargs": "关键字参数", + "cronExpression": "cron执行表达式", + "misfirePolicy": "计划执行错误策略", "concurrent": "是否并发执行", "status": "状态", - "create_by": "创建者", - "create_time": "创建时间", - "update_by": "更新者", - "update_time": "更新时间", + "createBy": "创建者", + "createTime": "创建时间", + "updateBy": "更新者", + "updateTime": "更新时间", "remark": "备注", } - data = [JobModel(**vars(row)).dict() for row in job_list] + 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_option = [dict(label=item.get('dict_label'), value=item.get('dict_value')) for item in job_group_list] + 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_option_dict = {item.get('value'): item for item in job_executor_option} for item in data: if item.get('status') == '0': item['status'] = '正常' else: item['status'] = '暂停' - if str(item.get('job_group')) in job_group_option_dict.keys(): - item['job_group'] = job_group_option_dict.get(str(item.get('job_group'))).get('label') - if item.get('misfire_policy') == '1': - item['misfire_policy'] = '立即执行' - elif item.get('misfire_policy') == '2': - item['misfire_policy'] = '执行一次' + if str(item.get('jobGroup')) in job_group_option_dict.keys(): + 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') + if item.get('misfirePolicy') == '1': + item['misfirePolicy'] = '立即执行' + elif item.get('misfirePolicy') == '2': + item['misfirePolicy'] = '执行一次' else: - item['misfire_policy'] = '放弃执行' + item['misfirePolicy'] = '放弃执行' if item.get('concurrent') == '0': item['concurrent'] = '允许' else: diff --git a/ruoyi-fastapi/module_admin/service/log_service.py b/ruoyi-fastapi-backend/module_admin/service/log_service.py similarity index 65% rename from ruoyi-fastapi/module_admin/service/log_service.py rename to ruoyi-fastapi-backend/module_admin/service/log_service.py index 16135dde67ed1a4b3a4bffa443d8258914379ebe..cbbb94e9314248ae39699561929efeb9d360977d 100644 --- a/ruoyi-fastapi/module_admin/service/log_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/log_service.py @@ -1,7 +1,7 @@ -from module_admin.entity.vo.log_vo import * from module_admin.dao.log_dao import * from module_admin.service.dict_service import Request, DictDataService -from utils.common_util import export_list2excel +from module_admin.entity.vo.common_vo import CrudResponseModel +from utils.common_util import export_list2excel, CamelCaseUtil class OperationLogService: @@ -10,14 +10,15 @@ class OperationLogService: """ @classmethod - def get_operation_log_list_services(cls, query_db: Session, query_object: OperLogQueryModel): + def get_operation_log_list_services(cls, query_db: Session, 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) + operation_log_list_result = OperationLogDao.get_operation_log_list(query_db, query_object, is_page) return operation_log_list_result @@ -37,7 +38,7 @@ class OperationLogService: query_db.rollback() result = dict(is_success=False, message=str(e)) - return CrudLogResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_operation_log_services(cls, query_db: Session, page_object: DeleteOperLogModel): @@ -51,49 +52,32 @@ class OperationLogService: oper_id_list = page_object.oper_ids.split(',') try: for oper_id in oper_id_list: - oper_id_dict = dict(oper_id=oper_id) - OperationLogDao.delete_operation_log_dao(query_db, OperLogModel(**oper_id_dict)) + OperationLogDao.delete_operation_log_dao(query_db, OperLogModel(operId=oper_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入操作日志id为空') - return CrudLogResponse(**result) + return CrudResponseModel(**result) @classmethod - def clear_operation_log_services(cls, query_db: Session, page_object: ClearOperLogModel): + def clear_operation_log_services(cls, query_db: Session): """ 清除操作日志信息service :param query_db: orm对象 - :param page_object: 清除操作日志对象 :return: 清除操作日志校验结果 """ - if page_object.oper_type == 'clear': - try: - OperationLogDao.clear_operation_log_dao(query_db) - query_db.commit() - result = dict(is_success=True, message='清除成功') - except Exception as e: - query_db.rollback() - result = dict(is_success=False, message=str(e)) - else: - result = dict(is_success=False, message='清除标识不合法') - - return CrudLogResponse(**result) - - @classmethod - def detail_operation_log_services(cls, query_db: Session, oper_id: int): - """ - 获取操作日志详细信息service - :param query_db: orm对象 - :param oper_id: 操作日志id - :return: 操作日志id对应的信息 - """ - operation_log = OperationLogDao.get_operation_log_detail_by_id(query_db, oper_id=oper_id) + try: + OperationLogDao.clear_operation_log_dao(query_db) + query_db.commit() + result = dict(is_success=True, message='清除成功') + except Exception as e: + query_db.rollback() + raise e - return operation_log + return CrudResponseModel(**result) @classmethod async def export_operation_log_list_services(cls, request: Request, operation_log_list: List): @@ -105,27 +89,27 @@ class OperationLogService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "oper_id": "日志编号", + "operId": "日志编号", "title": "系统模块", - "business_type": "操作类型", + "businessType": "操作类型", "method": "方法名称", - "request_method": "请求方式", - "oper_name": "操作人员", - "dept_name": "部门名称", - "oper_url": "请求URL", - "oper_ip": "操作地址", - "oper_location": "操作地点", - "oper_param": "请求参数", - "json_result": "返回参数", + "requestMethod": "请求方式", + "operName": "操作人员", + "deptName": "部门名称", + "operUrl": "请求URL", + "operIp": "操作地址", + "operLocation": "操作地点", + "operParam": "请求参数", + "jsonResult": "返回参数", "status": "操作状态", "error_msg": "错误消息", - "oper_time": "操作日期", - "cost_time": "消耗时间(毫秒)" + "operTime": "操作日期", + "costTime": "消耗时间(毫秒)" } - data = [OperLogModel(**vars(row)).dict() for row in operation_log_list] + 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('dict_label'), value=item.get('dict_value')) for item in operation_type_list] + 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: @@ -133,8 +117,8 @@ class OperationLogService: item['status'] = '成功' else: item['status'] = '失败' - if str(item.get('business_type')) in operation_type_option_dict.keys(): - item['business_type'] = operation_type_option_dict.get(str(item.get('business_type'))).get('label') + 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] binary_data = export_list2excel(new_data) @@ -148,14 +132,15 @@ class LoginLogService: """ @classmethod - def get_login_log_list_services(cls, query_db: Session, query_object: LoginLogQueryModel): + def get_login_log_list_services(cls, query_db: Session, 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) + operation_log_list_result = LoginLogDao.get_login_log_list(query_db, query_object, is_page) return operation_log_list_result @@ -175,7 +160,7 @@ class LoginLogService: query_db.rollback() result = dict(is_success=False, message=str(e)) - return CrudLogResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_login_log_services(cls, query_db: Session, page_object: DeleteLoginLogModel): @@ -189,37 +174,32 @@ class LoginLogService: info_id_list = page_object.info_ids.split(',') try: for info_id in info_id_list: - info_id_dict = dict(info_id=info_id) - LoginLogDao.delete_login_log_dao(query_db, LogininforModel(**info_id_dict)) + LoginLogDao.delete_login_log_dao(query_db, LogininforModel(infoId=info_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入登录日志id为空') - return CrudLogResponse(**result) + return CrudResponseModel(**result) @classmethod - def clear_login_log_services(cls, query_db: Session, page_object: ClearLoginLogModel): + def clear_login_log_services(cls, query_db: Session): """ 清除操作日志信息service :param query_db: orm对象 - :param page_object: 清除操作日志对象 :return: 清除操作日志校验结果 """ - if page_object.oper_type == 'clear': - try: - LoginLogDao.clear_login_log_dao(query_db) - query_db.commit() - result = dict(is_success=True, message='清除成功') - except Exception as e: - query_db.rollback() - result = dict(is_success=False, message=str(e)) - else: - result = dict(is_success=False, message='清除标识不合法') + try: + LoginLogDao.clear_login_log_dao(query_db) + query_db.commit() + result = dict(is_success=True, message='清除成功') + except Exception as e: + query_db.rollback() + raise e - return CrudLogResponse(**result) + return CrudResponseModel(**result) @classmethod async def unlock_user_services(cls, request: Request, unlock_user: UnlockUser): @@ -229,7 +209,7 @@ class LoginLogService: result = dict(is_success=True, message='解锁成功') else: result = dict(is_success=False, message='该用户未锁定') - return CrudLogResponse(**result) + return CrudResponseModel(**result) @staticmethod def export_login_log_list_services(login_log_list: List): @@ -240,18 +220,18 @@ class LoginLogService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "info_id": "访问编号", - "user_name": "用户名称", + "infoId": "访问编号", + "userName": "用户名称", "ipaddr": "登录地址", - "login_location": "登录地点", + "loginLocation": "登录地点", "browser": "浏览器", "os": "操作系统", "status": "登录状态", "msg": "操作信息", - "login_time": "登录日期" + "loginTime": "登录日期" } - data = [LogininforModel(**vars(row)).dict() for row in login_log_list] + data = login_log_list for item in data: if item.get('status') == '0': diff --git a/ruoyi-fastapi/module_admin/service/login_service.py b/ruoyi-fastapi-backend/module_admin/service/login_service.py similarity index 49% rename from ruoyi-fastapi/module_admin/service/login_service.py rename to ruoyi-fastapi-backend/module_admin/service/login_service.py index ac16489c84e4e2611c6d437a89b417709f35acac..f0ecaced1e230840f03eac0e73a863508a60a092 100644 --- a/ruoyi-fastapi/module_admin/service/login_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/login_service.py @@ -5,20 +5,19 @@ from jose import JWTError, jwt import random import uuid from datetime import timedelta -from typing import Dict -from module_admin.entity.vo.user_vo import * +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 module_admin.service.user_service import UserService -from module_admin.dao.user_dao import * -from config.env import JwtConfig, RedisInitKeyConfig +from exceptions.exception import LoginException, AuthException +from config.env import AppConfig, JwtConfig, RedisInitKeyConfig +from config.get_db import get_db from utils.common_util import CamelCaseUtil from utils.pwd_util import * from utils.response_util import * from utils.message_util import * -from config.get_db import get_db -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login/loginByAccount") +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login") class CustomOAuth2PasswordRequestForm(OAuth2PasswordRequestForm): @@ -62,8 +61,13 @@ class LoginService: if login_user.user_name == account_lock: logger.warning("账号已锁定,请稍后再试") raise LoginException(data="", message="账号已锁定,请稍后再试") - # 判断是否开启验证码,开启则验证,否则不验证 - if login_user.captcha_enabled: + # 判断请求是否来自于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 + # 判断是否开启验证码,开启则验证,否则不验证(dev模式下来自API文档的登录请求不检验) + 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) if not user: @@ -126,9 +130,9 @@ class LoginService: if expires_delta: expire = datetime.utcnow() + expires_delta else: - expire = datetime.utcnow() + timedelta(minutes=15) + expire = datetime.utcnow() + timedelta(minutes=30) to_encode.update({"exp": expire}) - encoded_jwt = jwt.encode(to_encode, JwtConfig.SECRET_KEY, algorithm=JwtConfig.ALGORITHM) + encoded_jwt = jwt.encode(to_encode, JwtConfig.jwt_secret_key, algorithm=JwtConfig.jwt_algorithm) return encoded_jwt @classmethod @@ -148,7 +152,7 @@ class LoginService: try: if token.startswith('Bearer'): token = token.split(' ')[1] - payload = jwt.decode(token, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM]) + 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: @@ -167,9 +171,9 @@ class LoginService: # redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info.user_id}") if token == redis_token: await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", redis_token, - ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) + ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes)) # await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info.user_id}", redis_token, - # ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) + # 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: @@ -224,14 +228,15 @@ class LoginService: router_list_data = {} if permission.menu_type == 'M': router_list_data['name'] = permission.path.capitalize() - router_list_data['path'] = f'/{permission.path}' router_list_data['hidden'] = False if permission.visible == '0' else True if permission.is_frame == 1: router_list_data['redirect'] = 'noRedirect' 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 children: router_list_data['alwaysShow'] = True router_list_data['children'] = children @@ -256,263 +261,104 @@ class LoginService: return router_list + @classmethod + async def register_user_services(cls, request: Request, query_db: Session, 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 + 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}") + if not captcha_value: + logger.warning("验证码已失效") + return CrudResponseModel(is_success=False, message='验证码已失效') + elif user_register.code != str(captcha_value): + logger.warning("验证码错误") + return CrudResponseModel(is_success=False, message='验证码错误') + add_user = AddUserModel( + userName=user_register.username, + nickName=user_register.username, + password=PwdUtil.get_password_hash(user_register.password) + ) + result = UserService.add_user_services(query_db, add_user) + return result + else: + result = dict(is_success=False, message='注册程序已关闭,禁止注册') + else: + result = dict(is_success=False, message='两次输入的密码不一致') -async def get_current_user(request: Request = Request, token: str = Depends(oauth2_scheme), - query_db: Session = Depends(get_db)): - """ - 根据token获取当前用户信息 - :param request: Request对象 - :param token: 用户token - :param query_db: orm对象 - :return: 当前用户信息对象 - :raise: 令牌异常AuthException - """ - # if token[:6] != 'Bearer': - # logger.warning("用户token不合法") - # raise AuthException(data="", message="用户token不合法") - try: - if token.startswith('Bearer'): - token = token.split(' ')[1] - payload = jwt.decode(token, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.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不合法") - token_data = TokenData(user_id=int(user_id)) - except JWTError: - logger.warning("用户token已失效,请重新登录") - raise AuthException(data="", message="用户token已失效,请重新登录") - user = UserDao.get_user_by_id(query_db, user_id=token_data.user_id) - if user is None: - logger.warning("用户token不合法") - raise AuthException(data="", message="用户token不合法") - 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.get('key')}:{user.user_basic_info.user_id}") - if token == redis_token: - await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", redis_token, - ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) - # await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info.user_id}", redis_token, - # ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) - - return CurrentUserInfoServiceResponse( - user=user.user_basic_info, - dept=user.user_dept_info, - role=user.user_role_info, - post=user.user_post_info, - menu=user.user_menu_info - ) - else: - logger.warning("用户token已失效,请重新登录") - raise AuthException(data="", message="用户token已失效,请重新登录") - - -async def get_sms_code_services(request: Request, query_db: Session, 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}") - 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) - 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)) - # 此处模拟调用短信服务 - message_service(sms_code) - - return SmsCode(**dict(is_success=True, sms_code=sms_code, session_id=session_id, message='获取成功')) - - return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='用户不存在')) - - -async def forget_user_services(request: Request, query_db: Session, 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}") - 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) - 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}") - result = dict(is_success=False, message='短信验证码不正确') - - return CrudUserResponse(**result) - - -async def logout_services(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'{current_user.user.user_id}_access_token') - # await request.app.state.redis.delete(f'{current_user.user.user_id}_session_id') - - return True - - -async def check_login_captcha(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.session_id}") - if not captcha_value: - logger.warning("验证码已失效") - raise LoginException(data="", message="验证码已失效") - if login_user.captcha != str(captcha_value): - logger.warning("验证码错误") - raise LoginException(data="", message="验证码错误") - return True - - -async def authenticate_user(request: Request, query_db: Session, login_user: UserLogin): - """ - 根据用户名密码校验用户登录 - :param request: Request对象 - :param query_db: orm对象 - :param login_user: 登录用户对象 - :return: 校验结果 - """ - account_lock = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCOUNT_LOCK.get('key')}:{login_user.user_name}") - if login_user.user_name == account_lock: - logger.warning("账号已锁定,请稍后再试") - raise LoginException(data="", message="账号已锁定,请稍后再试") - # 判断是否开启验证码,开启则验证,否则不验证 - if login_user.captcha_enabled: - await check_login_captcha(request, login_user) - user = login_by_account(query_db, login_user.user_name) - if not user: - 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}") - 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)) - if password_error_count > 5: - await request.app.state.redis.delete(f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('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="密码错误") - 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}") - return user - - -def create_access_token(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 - else: - expire = datetime.utcnow() + timedelta(minutes=15) - to_encode.update({"exp": expire}) - encoded_jwt = jwt.encode(to_encode, JwtConfig.SECRET_KEY, algorithm=JwtConfig.ALGORITHM) - return encoded_jwt - - -def deal_user_dept_info(db: Session, dept_info: DeptInfo): - tmp_dept_name = dept_info.dept_name - dept_ancestors = dept_info.ancestors.split(',') - tmp_dept_list = [] - for item in dept_ancestors: - dept_obj = UserDao.get_user_dept_info(db, int(item)) - if dept_obj: - tmp_dept_list.append(dept_obj.dept_name) - tmp_dept_list.append(tmp_dept_name) - user_dept_info = '/'.join(tmp_dept_list) - - return user_dept_info - + return CrudResponseModel(**result) -def deal_user_role_info(role_info: RoleInfo): - tmp_user_role_info = [] - for item in role_info.role_info: - tmp_user_role_info.append(item.role_name) - user_role_info = '/'.join(tmp_user_role_info) + @classmethod + async def get_sms_code_services(cls, request: Request, query_db: Session, 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}") + 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) + 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)) + # 此处模拟调用短信服务 + message_service(sms_code) + + return SmsCode(**dict(is_success=True, sms_code=sms_code, session_id=session_id, message='获取成功')) + + return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='用户不存在')) - return user_role_info + @classmethod + async def forget_user_services(cls, request: Request, query_db: Session, 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}") + 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) + 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}") + result = dict(is_success=False, message='短信验证码不正确') + return CrudResponseModel(**result) -def deal_user_menu_info(pid: int, permission_list: MenuList): - """ - 工具方法:根据菜单信息生成树形嵌套数据 - :param pid: 菜单id - :param permission_list: 菜单列表信息 - :return: 菜单树形嵌套数据 - """ - menu_list = [] - for permission in permission_list.menu_info: - if permission.parent_id == pid: - children = deal_user_menu_info(permission.menu_id, permission_list) - antd_menu_list_data = {} - if children and permission.menu_type == 'M': - antd_menu_list_data['component'] = 'SubMenu' - antd_menu_list_data['props'] = { - 'key': str(permission.menu_id), - 'title': permission.menu_name, - 'icon': permission.icon - } - antd_menu_list_data['children'] = children - elif children and permission.menu_type == 'C': - antd_menu_list_data['component'] = 'Item' - antd_menu_list_data['props'] = { - 'key': str(permission.menu_id), - 'title': permission.menu_name, - 'icon': permission.icon, - 'href': permission.path, - 'modules': permission.component - } - antd_menu_list_data['button'] = children - elif permission.menu_type == 'F': - antd_menu_list_data['component'] = 'Button' - antd_menu_list_data['props'] = { - 'key': str(permission.menu_id), - 'title': permission.menu_name, - 'icon': permission.icon - } - else: - antd_menu_list_data['component'] = 'Item' - antd_menu_list_data['props'] = { - 'key': str(permission.menu_id), - 'title': permission.menu_name, - 'icon': permission.icon, - 'href': permission.path, - } - menu_list.append(antd_menu_list_data) + @classmethod + 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'{current_user.user.user_id}_access_token') + # await request.app.state.redis.delete(f'{current_user.user.user_id}_session_id') - return menu_list + return True diff --git a/ruoyi-fastapi/module_admin/service/menu_service.py b/ruoyi-fastapi-backend/module_admin/service/menu_service.py similarity index 51% rename from ruoyi-fastapi/module_admin/service/menu_service.py rename to ruoyi-fastapi-backend/module_admin/service/menu_service.py index 3c24da2fb9008f1b82b9569caefa52653a0e42f1..10a295d904c9ae9366550b21588bf2683e878d77 100644 --- a/ruoyi-fastapi/module_admin/service/menu_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/menu_service.py @@ -1,6 +1,9 @@ -from module_admin.entity.vo.menu_vo import * +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 module_admin.dao.role_dao import RoleDao from module_admin.dao.menu_dao import * -from module_admin.entity.vo.user_vo import CurrentUserInfoServiceResponse +from utils.common_util import CamelCaseUtil class MenuService: @@ -9,42 +12,40 @@ class MenuService: """ @classmethod - def get_menu_tree_services(cls, query_db: Session, page_object: MenuTreeModel, current_user: Optional[CurrentUserInfoServiceResponse] = None): + def get_menu_tree_services(cls, query_db: Session, current_user: Optional[CurrentUserModel] = None): """ 获取菜单树信息service :param query_db: orm对象 - :param page_object: 查询参数对象 :param current_user: 当前用户对象 :return: 菜单树信息对象 """ - menu_tree_option = [] - menu_list_result = MenuDao.get_menu_list_for_tree(query_db, MenuModel(**page_object.dict()), current_user.user.user_id, current_user.role) - menu_tree_result = cls.get_menu_tree(0, MenuTree(menu_tree=menu_list_result)) - if page_object.type != 'role': - menu_tree_option.append(dict(title='主类目', value='0', key='0', children=menu_tree_result)) - else: - menu_tree_option = [menu_tree_result, menu_list_result] + 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) - return menu_tree_option + return menu_tree_result @classmethod - def get_menu_tree_for_edit_option_services(cls, query_db: Session, page_object: MenuModel, current_user: Optional[CurrentUserInfoServiceResponse] = None): + def get_role_menu_tree_services(cls, query_db: Session, role_id: int, current_user: Optional[CurrentUserModel] = None): """ - 获取菜单编辑菜单树信息service + 根据角色id获取菜单树信息service :param query_db: orm对象 - :param page_object: 查询参数对象 - :param current_user: 当前用户 - :return: 菜单树信息对象 + :param role_id: 角色id + :param current_user: 当前用户对象 + :return: 当前角色id的菜单树信息对象 """ - menu_tree_option = [] - menu_list_result = MenuDao.get_menu_info_for_edit_option(query_db, page_object, current_user.user.user_id, current_user.role) - menu_tree_result = cls.get_menu_tree(0, MenuTree(menu_tree=menu_list_result)) - menu_tree_option.append(dict(title='主类目', value='0', key='0', children=menu_tree_result)) + 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 + ) - return menu_tree_option + return result @classmethod - def get_menu_list_services(cls, query_db: Session, page_object: MenuModel, current_user: Optional[CurrentUserInfoServiceResponse] = None): + def get_menu_list_services(cls, query_db: Session, page_object: MenuQueryModel, current_user: Optional[CurrentUserModel] = None): """ 获取菜单列表信息service :param query_db: orm对象 @@ -52,9 +53,9 @@ class MenuService: :param current_user: 当前用户对象 :return: 菜单列表信息对象 """ - menu_list_result = MenuDao.get_menu_list(query_db, page_object, current_user.user.user_id, current_user.role) + menu_list_result = MenuDao.get_menu_list(query_db, page_object, current_user.user.user_id, current_user.user.role) - return menu_list_result + return CamelCaseUtil.transform_result(menu_list_result) @classmethod def add_menu_services(cls, query_db: Session, page_object: MenuModel): @@ -64,8 +65,7 @@ class MenuService: :param page_object: 新增菜单对象 :return: 新增菜单校验结果 """ - menu = MenuDao.get_menu_detail_by_info(query_db, MenuModel( - **dict(parent_id=page_object.parent_id, menu_name=page_object.menu_name, 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='同一目录下不允许存在同名同类型的菜单') else: @@ -75,9 +75,9 @@ class MenuService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudMenuResponse(**result) + return CrudResponseModel(**result) @classmethod def edit_menu_services(cls, query_db: Session, page_object: MenuModel): @@ -87,26 +87,25 @@ class MenuService: :param page_object: 编辑部门对象 :return: 编辑菜单校验结果 """ - edit_menu = page_object.dict(exclude_unset=True) - menu_info = cls.detail_menu_services(query_db, edit_menu.get('menu_id')) + 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( - **dict(parent_id=page_object.parent_id, menu_name=page_object.menu_name, 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 CrudMenuResponse(**result) + 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() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='菜单不存在') - return CrudMenuResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_menu_services(cls, query_db: Session, page_object: DeleteMenuModel): @@ -120,19 +119,18 @@ class MenuService: menu_id_list = page_object.menu_ids.split(',') try: for menu_id in menu_id_list: - menu_id_dict = dict(menu_id=menu_id) - MenuDao.delete_menu_dao(query_db, MenuModel(**menu_id_dict)) + MenuDao.delete_menu_dao(query_db, MenuModel(menuId=menu_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入菜单id为空') - return CrudMenuResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_menu_services(cls, query_db: Session, menu_id: int): + def menu_detail_services(cls, query_db: Session, menu_id: int): """ 获取菜单详细信息service :param query_db: orm对象 @@ -140,31 +138,34 @@ class MenuService: :return: 菜单id对应的信息 """ menu = MenuDao.get_menu_detail_by_id(query_db, menu_id=menu_id) + result = MenuModel(**CamelCaseUtil.transform_result(menu)) - return menu + return result @classmethod - def get_menu_tree(cls, pid: int, permission_list: MenuTree): + def list_to_tree(cls, permission_list: list) -> list: """ - 工具方法:根据菜单信息生成树形嵌套数据 - :param pid: 菜单id + 工具方法:根据菜单列表信息生成树形嵌套数据 :param permission_list: 菜单列表信息 :return: 菜单树形嵌套数据 """ - menu_list = [] - for permission in permission_list.menu_tree: - if permission.parent_id == pid: - children = cls.get_menu_tree(permission.menu_id, permission_list) - menu_list_data = {} - if children: - menu_list_data['title'] = permission.menu_name - menu_list_data['key'] = str(permission.menu_id) - menu_list_data['value'] = str(permission.menu_id) - menu_list_data['children'] = children - else: - menu_list_data['title'] = permission.menu_name - menu_list_data['key'] = str(permission.menu_id) - menu_list_data['value'] = str(permission.menu_id) - menu_list.append(menu_list_data) - - return menu_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)) + + # 树容器 + container: list = [] + + for d in permission_list: + # 如果找不到父级项,则是根节点 + parent: dict = mapping.get(d['parentId']) + if parent is None: + container.append(d) + else: + children: list = parent.get('children') + if not children: + children = [] + children.append(d) + parent.update({'children': children}) + + return container diff --git a/ruoyi-fastapi/module_admin/service/notice_service.py b/ruoyi-fastapi-backend/module_admin/service/notice_service.py similarity index 80% rename from ruoyi-fastapi/module_admin/service/notice_service.py rename to ruoyi-fastapi-backend/module_admin/service/notice_service.py index dbac52a1ca9a8526dabf556630431e35cb6e0198..1ca63a801d9e2570090338d0acd3b3dabca42df7 100644 --- a/ruoyi-fastapi/module_admin/service/notice_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/notice_service.py @@ -1,5 +1,6 @@ -from module_admin.entity.vo.notice_vo import * from module_admin.dao.notice_dao import * +from module_admin.entity.vo.common_vo import CrudResponseModel +from utils.common_util import export_list2excel, CamelCaseUtil class NoticeService: @@ -8,14 +9,15 @@ class NoticeService: """ @classmethod - def get_notice_list_services(cls, query_db: Session, query_object: NoticeQueryModel): + def get_notice_list_services(cls, query_db: Session, 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) + notice_list_result = NoticeDao.get_notice_list(query_db, query_object, is_page) return notice_list_result @@ -37,9 +39,9 @@ class NoticeService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudNoticeResponse(**result) + return CrudResponseModel(**result) @classmethod def edit_notice_services(cls, query_db: Session, page_object: NoticeModel): @@ -49,25 +51,25 @@ class NoticeService: :param page_object: 编辑通知公告对象 :return: 编辑通知公告校验结果 """ - edit_notice = page_object.dict(exclude_unset=True) - notice_info = cls.detail_notice_services(query_db, edit_notice.get('notice_id')) + 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 CrudNoticeResponse(**result) + 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() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='通知公告不存在') - return CrudNoticeResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_notice_services(cls, query_db: Session, page_object: DeleteNoticeModel): @@ -81,19 +83,18 @@ class NoticeService: notice_id_list = page_object.notice_ids.split(',') try: for notice_id in notice_id_list: - notice_id_dict = dict(notice_id=notice_id) - NoticeDao.delete_notice_dao(query_db, NoticeModel(**notice_id_dict)) + NoticeDao.delete_notice_dao(query_db, NoticeModel(noticeId=notice_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入通知公告id为空') - return CrudNoticeResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_notice_services(cls, query_db: Session, notice_id: int): + def notice_detail_services(cls, query_db: Session, notice_id: int): """ 获取通知公告详细信息service :param query_db: orm对象 @@ -101,5 +102,6 @@ class NoticeService: :return: 通知公告id对应的信息 """ notice = NoticeDao.get_notice_detail_by_id(query_db, notice_id=notice_id) + result = NoticeModel(**CamelCaseUtil.transform_result(notice)) - return notice + return result diff --git a/ruoyi-fastapi/module_admin/service/online_service.py b/ruoyi-fastapi-backend/module_admin/service/online_service.py similarity index 74% rename from ruoyi-fastapi/module_admin/service/online_service.py rename to ruoyi-fastapi-backend/module_admin/service/online_service.py index 47277ea8b58af8a36751abc9bd3e738d9d24a3d4..968aacb14dfa01a92d069ac3dc3a86513931e046 100644 --- a/ruoyi-fastapi/module_admin/service/online_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/online_service.py @@ -2,6 +2,8 @@ from fastapi import Request from jose import jwt from config.env import JwtConfig, RedisInitKeyConfig from module_admin.entity.vo.online_vo import * +from module_admin.entity.vo.common_vo import CrudResponseModel +from utils.common_util import CamelCaseUtil class OnlineService: @@ -10,7 +12,7 @@ class OnlineService: """ @classmethod - async def get_online_list_services(cls, request: Request, query_object: OnlinePageObject): + async def get_online_list_services(cls, request: Request, query_object: OnlineQueryModel): """ 获取在线用户表信息service :param request: Request对象 @@ -23,19 +25,19 @@ class OnlineService: access_token_values_list = [await request.app.state.redis.get(key) for key in access_token_keys] online_info_list = [] for item in access_token_values_list: - payload = jwt.decode(item, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM]) + payload = jwt.decode(item, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm]) online_dict = dict( - session_id=payload.get('session_id'), + token_id=payload.get('session_id'), user_name=payload.get('user_name'), dept_name=payload.get('dept_name'), ipaddr=payload.get('login_info').get('ipaddr'), - login_location=payload.get('login_info').get('login_location'), + 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('login_time') + 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('user_name'): + if query_object.user_name == payload.get('login_info').get('ipaddr'): online_info_list = [online_dict] break elif not query_object.user_name and query_object.ipaddr: @@ -43,13 +45,13 @@ class OnlineService: 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('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: online_info_list.append(online_dict) - return online_info_list + return CamelCaseUtil.transform_result(online_info_list) @classmethod async def delete_online_services(cls, request: Request, page_object: DeleteOnlineModel): @@ -59,11 +61,11 @@ class OnlineService: :param page_object: 强退在线用户对象 :return: 强退在线用户校验结果 """ - if page_object.session_ids.split(','): - session_id_list = page_object.session_ids.split(',') - for session_id in session_id_list: - await request.app.state.redis.delete(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}") + if page_object.token_ids.split(','): + 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='强退成功') else: result = dict(is_success=False, message='传入session_id为空') - return CrudOnlineResponse(**result) + return CrudResponseModel(**result) diff --git a/ruoyi-fastapi/module_admin/service/post_service.py b/ruoyi-fastapi-backend/module_admin/service/post_service.py similarity index 70% rename from ruoyi-fastapi/module_admin/service/post_service.py rename to ruoyi-fastapi-backend/module_admin/service/post_service.py index 0046a49d999d040cceb7d6ae9098b5e9cb054295..d6b097fef55872f53af574a57f616faac545de62 100644 --- a/ruoyi-fastapi/module_admin/service/post_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/post_service.py @@ -1,33 +1,22 @@ -from module_admin.entity.vo.post_vo import * from module_admin.dao.post_dao import * -from utils.common_util import export_list2excel +from module_admin.entity.vo.common_vo import CrudResponseModel +from utils.common_util import export_list2excel, CamelCaseUtil class PostService: """ 岗位管理模块服务层 """ - - @classmethod - def get_post_select_option_services(cls, query_db: Session): - """ - 获取岗位列表不分页信息service - :param query_db: orm对象 - :return: 岗位列表不分页信息对象 - """ - post_list_result = PostDao.get_post_select_option_dao(query_db) - - return post_list_result - @classmethod - def get_post_list_services(cls, query_db: Session, query_object: PostModel): + def get_post_list_services(cls, query_db: Session, 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) + post_list_result = PostDao.get_post_list(query_db, query_object, is_page) return post_list_result @@ -39,7 +28,7 @@ class PostService: :param page_object: 新增岗位对象 :return: 新增岗位校验结果 """ - post = PostDao.get_post_detail_by_info(query_db, PostModel(**dict(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='岗位名称已存在') else: @@ -49,9 +38,9 @@ class PostService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudPostResponse(**result) + return CrudResponseModel(**result) @classmethod def edit_post_services(cls, query_db: Session, page_object: PostModel): @@ -61,25 +50,25 @@ class PostService: :param page_object: 编辑岗位对象 :return: 编辑岗位校验结果 """ - edit_post = page_object.dict(exclude_unset=True) - post_info = cls.detail_post_services(query_db, edit_post.get('post_id')) + 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(**dict(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 CrudPostResponse(**result) + 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() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='岗位不存在') - return CrudPostResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_post_services(cls, query_db: Session, page_object: DeletePostModel): @@ -93,19 +82,18 @@ class PostService: post_id_list = page_object.post_ids.split(',') try: for post_id in post_id_list: - post_id_dict = dict(post_id=post_id) - PostDao.delete_post_dao(query_db, PostModel(**post_id_dict)) + PostDao.delete_post_dao(query_db, PostModel(postId=post_id)) query_db.commit() result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入岗位id为空') - return CrudPostResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_post_services(cls, query_db: Session, post_id: int): + def post_detail_services(cls, query_db: Session, post_id: int): """ 获取岗位详细信息service :param query_db: orm对象 @@ -113,8 +101,9 @@ class PostService: :return: 岗位id对应的信息 """ post = PostDao.get_post_detail_by_id(query_db, post_id=post_id) + result = PostModel(**CamelCaseUtil.transform_result(post)) - return post + return result @staticmethod def export_post_list_services(post_list: List): @@ -125,19 +114,19 @@ class PostService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "post_id": "岗位编号", - "post_code": "岗位编码", - "post_name": "岗位名称", - "post_sort": "显示顺序", + "postId": "岗位编号", + "postCode": "岗位编码", + "postName": "岗位名称", + "postSort": "显示顺序", "status": "状态", - "create_by": "创建者", - "create_time": "创建时间", - "update_by": "更新者", - "update_time": "更新时间", + "createBy": "创建者", + "createTime": "创建时间", + "updateBy": "更新者", + "updateTime": "更新时间", "remark": "备注", } - data = [PostModel(**vars(row)).dict() for row in post_list] + data = post_list for item in data: if item.get('status') == '0': diff --git a/ruoyi-fastapi/module_admin/service/role_service.py b/ruoyi-fastapi-backend/module_admin/service/role_service.py similarity index 48% rename from ruoyi-fastapi/module_admin/service/role_service.py rename to ruoyi-fastapi-backend/module_admin/service/role_service.py index cbf6eebbf3d233f9467b686dc53bcf353e067545..71c3381e5d12061d2ae2e8f614ef96f9b6a1379d 100644 --- a/ruoyi-fastapi/module_admin/service/role_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/role_service.py @@ -1,5 +1,8 @@ -from module_admin.entity.vo.role_vo import * +from module_admin.entity.vo.user_vo import UserInfoModel, UserRolePageQueryModel +from module_admin.entity.vo.common_vo import CrudResponseModel +from module_admin.dao.user_dao import UserDao from module_admin.dao.role_dao import * +from utils.page_util import PageResponseModel from utils.common_util import export_list2excel, CamelCaseUtil @@ -20,16 +23,33 @@ class RoleService: return CamelCaseUtil.transform_result(role_list_result) @classmethod - def get_role_list_services(cls, query_db: Session, query_object: RoleQueryModel): + def get_role_dept_tree_services(cls, query_db: Session, 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) + checked_keys = [row.dept_id for row in role_dept_list] + result = RoleDeptQueryModel( + checkedKeys=checked_keys + ) + + return result + + @classmethod + def get_role_list_services(cls, query_db: Session, query_object: RolePageQueryModel, is_page: bool = False): """ 获取角色列表信息service :param query_db: orm对象 :param query_object: 查询参数对象 + :param is_page: 是否开启分页 :return: 角色列表信息对象 """ - role_list_result = RoleDao.get_role_list(query_db, query_object) + role_list_result = RoleDao.get_role_list(query_db, query_object, is_page) - return CamelCaseUtil.transform_result(role_list_result) + return role_list_result @classmethod def add_role_services(cls, query_db: Session, page_object: AddRoleModel): @@ -39,26 +59,27 @@ class RoleService: :param page_object: 新增角色对象 :return: 新增角色校验结果 """ - add_role = RoleModel(**page_object.dict()) - role = RoleDao.get_role_by_info(query_db, RoleModel(**dict(role_name=page_object.role_name))) - if role: + 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='权限字符已存在') else: try: add_result = RoleDao.add_role_dao(query_db, add_role) role_id = add_result.role_id - if page_object.menu_id: - menu_id_list = page_object.menu_id.split(',') - for menu in menu_id_list: - menu_dict = dict(role_id=role_id, menu_id=menu) - RoleDao.add_role_menu_dao(query_db, RoleMenuModel(**menu_dict)) + 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='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudRoleResponse(**result) + return CrudResponseModel(**result) @classmethod def edit_role_services(cls, query_db: Session, page_object: AddRoleModel): @@ -68,73 +89,77 @@ class RoleService: :param page_object: 编辑角色对象 :return: 编辑角色校验结果 """ - edit_role = page_object.dict(exclude_unset=True) + edit_role = page_object.model_dump(exclude_unset=True, exclude={'admin'}) if page_object.type != 'status': - del edit_role['menu_id'] + del edit_role['menu_ids'] if page_object.type == 'status': del edit_role['type'] - role_info = cls.detail_role_services(query_db, edit_role.get('role_id')) + role_info = cls.role_detail_services(query_db, edit_role.get('role_id')) if role_info: - if page_object.type != 'status' and role_info.role.role_name != page_object.role_name: - role = RoleDao.get_role_by_info(query_db, RoleModel(**dict(role_name=page_object.role_name))) - if role: + 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 CrudRoleResponse(**result) + 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) try: RoleDao.edit_role_dao(query_db, edit_role) if page_object.type != 'status': - role_id_dict = dict(role_id=page_object.role_id) - RoleDao.delete_role_menu_dao(query_db, RoleMenuModel(**role_id_dict)) - if page_object.menu_id: - menu_id_list = page_object.menu_id.split(',') - for menu in menu_id_list: - menu_dict = dict(role_id=page_object.role_id, menu_id=menu) - RoleDao.add_role_menu_dao(query_db, RoleMenuModel(**menu_dict)) + 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='更新成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='角色不存在') - return CrudRoleResponse(**result) + return CrudResponseModel(**result) @classmethod - def role_datascope_services(cls, query_db: Session, page_object: RoleDataScopeModel): + def role_datascope_services(cls, query_db: Session, page_object: AddRoleModel): """ 分配角色数据权限service :param query_db: orm对象 :param page_object: 角色数据权限对象 :return: 分配角色数据权限结果 """ - edit_role = page_object.dict(exclude_unset=True) - del edit_role['dept_id'] - role_info = cls.detail_role_services(query_db, edit_role.get('role_id')) + 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.role_name != page_object.role_name: - role = RoleDao.get_role_by_info(query_db, RoleModel(**dict(role_name=page_object.role_name))) - if role: + 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 CrudRoleResponse(**result) + 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) try: RoleDao.edit_role_dao(query_db, edit_role) - role_id_dict = dict(role_id=page_object.role_id) - RoleDao.delete_role_dept_dao(query_db, RoleDeptModel(**role_id_dict)) - if page_object.dept_id and page_object.data_scope == '2': - dept_id_list = page_object.dept_id.split(',') - for dept in dept_id_list: - dept_dict = dict(role_id=page_object.role_id, dept_id=dept) - RoleDao.add_role_dept_dao(query_db, RoleDeptModel(**dept_dict)) + 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='分配成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='角色不存在') - return CrudRoleResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_role_services(cls, query_db: Session, page_object: DeleteRoleModel): @@ -148,20 +173,20 @@ class RoleService: role_id_list = page_object.role_ids.split(',') try: for role_id in role_id_list: - role_id_dict = dict(role_id=role_id, update_by=page_object.update_by, update_time=page_object.update_time) + 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='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入角色id为空') - return CrudRoleResponse(**result) + return CrudResponseModel(**result) @classmethod - def detail_role_services(cls, query_db: Session, role_id: int): + def role_detail_services(cls, query_db: Session, role_id: int): """ 获取角色详细信息service :param query_db: orm对象 @@ -169,8 +194,9 @@ class RoleService: :return: 角色id对应的信息 """ role = RoleDao.get_role_detail_by_id(query_db, role_id=role_id) + result = RoleModel(**CamelCaseUtil.transform_result(role)) - return role + return result @staticmethod def export_role_list_services(role_list: List): @@ -181,19 +207,19 @@ class RoleService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "role_id": "角色编号", - "role_name": "角色名称", - "role_key": "权限字符", - "role_sort": "显示顺序", + "roleId": "角色编号", + "roleName": "角色名称", + "roleKey": "权限字符", + "roleSort": "显示顺序", "status": "状态", - "create_by": "创建者", - "create_time": "创建时间", - "update_by": "更新者", - "update_time": "更新时间", + "createBy": "创建者", + "createTime": "创建时间", + "updateBy": "更新者", + "updateTime": "更新时间", "remark": "备注", } - data = [RoleModel(**vars(row)).dict() for row in role_list] + data = role_list for item in data: if item.get('status') == '0': @@ -204,3 +230,41 @@ class RoleService: 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): + """ + 根据角色id获取已分配用户列表 + :param query_db: orm对象 + :param page_object: 用户关联角色对象 + :param is_page: 是否开启分页 + :return: 已分配用户列表 + """ + query_user_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object, is_page) + allocated_list = PageResponseModel( + **{ + **query_user_list.model_dump(by_alias=True), + 'rows': [UserInfoModel(**row) for row in query_user_list.rows] + } + ) + + return allocated_list + + @classmethod + def get_role_user_unallocated_list_services(cls, query_db: Session, page_object: UserRolePageQueryModel, is_page: bool = False): + """ + 根据角色id获取未分配用户列表 + :param query_db: orm对象 + :param page_object: 用户关联角色对象 + :param is_page: 是否开启分页 + :return: 未分配用户列表 + """ + query_user_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object, is_page) + unallocated_list = PageResponseModel( + **{ + **query_user_list.model_dump(by_alias=True), + 'rows': [UserInfoModel(**row) for row in query_user_list.rows] + } + ) + + return unallocated_list diff --git a/ruoyi-fastapi/module_admin/service/server_service.py b/ruoyi-fastapi-backend/module_admin/service/server_service.py similarity index 53% rename from ruoyi-fastapi/module_admin/service/server_service.py rename to ruoyi-fastapi-backend/module_admin/service/server_service.py index 0c41c8eb864f152c31f2478d43cd865fd32f328c..760823bdd9df991f7a40a3ffec460215141dcd21 100644 --- a/ruoyi-fastapi/module_admin/service/server_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/server_service.py @@ -18,18 +18,18 @@ class ServerService: # 获取CPU总核心数 cpu_num = psutil.cpu_count(logical=True) cpu_usage_percent = psutil.cpu_times_percent() - cpu_used = f'{cpu_usage_percent.user}%' - cpu_sys = f'{cpu_usage_percent.system}%' - cpu_free = f'{cpu_usage_percent.idle}%' - cpu = CpuInfo(**dict(cpu_num=cpu_num, used=cpu_used, sys=cpu_sys, free=cpu_free)) + cpu_used = cpu_usage_percent.user + cpu_sys = cpu_usage_percent.system + cpu_free = cpu_usage_percent.idle + cpu = CpuInfo(cpuNum=cpu_num, used=cpu_used, sys=cpu_sys, free=cpu_free) # 内存信息 memory_info = psutil.virtual_memory() memory_total = bytes2human(memory_info.total) memory_used = bytes2human(memory_info.used) memory_free = bytes2human(memory_info.free) - memory_usage = f'{memory_info.percent}%' - mem = MemoryInfo(**dict(total=memory_total, used=memory_used, free=memory_free, usage=memory_usage)) + memory_usage = memory_info.percent + mem = MemoryInfo(total=memory_total, used=memory_used, free=memory_free, usage=memory_usage) # 主机信息 # 获取主机名 @@ -39,7 +39,8 @@ class ServerService: os_name = platform.platform() computer_name = platform.node() os_arch = platform.machine() - sys = SysInfo(**dict(computer_ip=computer_ip, computer_name=computer_name, os_arch=os_arch, os_name=os_name)) + user_dir = os.path.abspath(os.getcwd()) + sys = SysInfo(computerIp=computer_ip, computerName=computer_name, osArch=os_arch, osName=os_name, userDir=user_dir) # python解释器信息 current_pid = os.getpid() @@ -56,16 +57,20 @@ class ServerService: hours = int((difference % (24 * 60 * 60)) // (60 * 60)) # 每小时的秒数 minutes = int((difference % (60 * 60)) // 60) # 每分钟的秒数 run_time = f"{days}天{hours}小时{minutes}分钟" - project_dir = os.path.abspath(os.getcwd()) + # 获取当前Python程序的pid + pid = os.getpid() + # 获取该进程的内存信息 + current_process_memory_info = psutil.Process(pid).memory_info() py = PyInfo( - **dict( - name=python_name, - version=python_version, - start_time=start_time, - run_time=run_time, - home=python_home, - project_dir=project_dir - ) + name=python_name, + version=python_version, + startTime=start_time, + runTime=run_time, + home=python_home, + 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) ) # 磁盘信息 @@ -73,17 +78,17 @@ class ServerService: sys_files = [] for i in io: o = psutil.disk_usage(i.device) - disk_data = { - "dir_name": i.device, - "sys_type_name": i.fstype, - "disk_name": "本地固定磁盘(" + i.mountpoint.replace('\\', '') + ")", - "total": bytes2human(o.total), - "used": bytes2human(o.used), - "free": bytes2human(o.free), - "usage": f'{psutil.disk_usage(i.device).percent}%' - } - sys_files.append(SysFiles(**disk_data)) + disk_data = SysFiles( + dirName=i.device, + sysTypeName=i.fstype, + typeName="本地固定磁盘(" + i.mountpoint.replace('\\', '') + ")", + total=bytes2human(o.total), + used=bytes2human(o.used), + free=bytes2human(o.free), + usage=f'{psutil.disk_usage(i.device).percent}%' + ) + sys_files.append(disk_data) - result = dict(cpu=cpu, mem=mem, sys=sys, py=py, sys_files=sys_files) + result = ServerMonitorModel(cpu=cpu, mem=mem, sys=sys, py=py, sysFiles=sys_files) - return ServerMonitorModel(**result) + return result diff --git a/ruoyi-fastapi/module_admin/service/user_service.py b/ruoyi-fastapi-backend/module_admin/service/user_service.py similarity index 77% rename from ruoyi-fastapi/module_admin/service/user_service.py rename to ruoyi-fastapi-backend/module_admin/service/user_service.py index 6baa9c110b7c0f232c7ac20e383fbd90ad9bf1d7..29a04b6810bcefd0c76f99a13c74f5bb7b84ea8d 100644 --- a/ruoyi-fastapi/module_admin/service/user_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/user_service.py @@ -1,9 +1,9 @@ from fastapi import UploadFile from module_admin.service.role_service import RoleService -from module_admin.service.post_service import PostService -from module_admin.entity.vo.user_vo import * +from module_admin.service.post_service import PostService, PostPageQueryModel from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.dao.user_dao import * +from utils.page_util import PageResponseModel from utils.pwd_util import * from utils.common_util import * @@ -14,18 +14,27 @@ class UserService: """ @classmethod - def get_user_list_services(cls, query_db: Session, query_object: UserQueryModel, data_scope_sql: str): + def get_user_list_services(cls, query_db: Session, query_object: UserPageQueryModel, data_scope_sql: str, is_page: bool = False): """ 获取用户列表信息service :param query_db: orm对象 :param query_object: 查询参数对象 :param data_scope_sql: 数据权限对应的查询sql语句 + :param is_page: 是否开启分页 :return: 用户列表信息对象 """ - query_result = UserDao.get_user_list(query_db, query_object, data_scope_sql) - user_list_result = [] - if query_result: - user_list_result = [{**CamelCaseUtil.transform_result(row[0]), 'dept': CamelCaseUtil.transform_result(row[1])} for row in query_result] + query_result = UserDao.get_user_list(query_db, query_object, data_scope_sql, is_page) + if is_page: + user_list_result = PageResponseModel( + **{ + **query_result.model_dump(by_alias=True), + 'rows': [{**row[0], 'dept': row[1]} for row in query_result.rows] + } + ) + else: + user_list_result = [] + if query_result: + user_list_result = [{**row[0], 'dept': row[1]} for row in query_result] return user_list_result @@ -55,19 +64,19 @@ class UserService: result = dict(is_success=True, message='新增成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e return CrudResponseModel(**result) @classmethod - def edit_user_services(cls, query_db: Session, page_object: AddUserModel): + def edit_user_services(cls, query_db: Session, page_object: EditUserModel): """ 编辑用户信息service :param query_db: orm对象 :param page_object: 编辑用户对象 :return: 编辑用户校验结果 """ - edit_user = page_object.model_dump(exclude_unset=True) + edit_user = page_object.model_dump(exclude_unset=True, exclude={'admin'}) if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type != 'pwd': del edit_user['role_ids'] del edit_user['post_ids'] @@ -96,7 +105,7 @@ class UserService: result = dict(is_success=True, message='更新成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='用户不存在') @@ -122,7 +131,7 @@ class UserService: result = dict(is_success=True, message='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='传入用户id为空') return CrudResponseModel(**result) @@ -135,7 +144,7 @@ class UserService: :param user_id: 用户id :return: 用户id对应的信息 """ - posts = PostService.get_post_list_services(query_db, PostModel(**{})) + posts = PostService.get_post_list_services(query_db, PostPageQueryModel(**{}), is_page=False) roles = 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) @@ -197,12 +206,12 @@ class UserService: :param page_object: 重置用户对象 :return: 重置用户校验结果 """ - reset_user = page_object.dict(exclude_unset=True) + reset_user = page_object.model_dump(exclude_unset=True) if page_object.old_password: - user = UserDao.get_user_detail_by_id(query_db, user_id=page_object.user_id).user_basic_info + user = 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 CrudUserResponse(**result) + return CrudResponseModel(**result) else: del reset_user['old_password'] if page_object.sms_code and page_object.session_id: @@ -214,9 +223,9 @@ class UserService: result = dict(is_success=True, message='重置成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e - return CrudUserResponse(**result) + return CrudResponseModel(**result) @classmethod async def batch_import_user_services(cls, query_db: Session, file: UploadFile, update_support: bool, current_user: CurrentUserModel): @@ -291,7 +300,7 @@ class UserService: result = dict(is_success=True, message='\n'.join(add_error_result)) except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e return CrudResponseModel(**result) @@ -353,34 +362,32 @@ class UserService: @classmethod def get_user_role_allocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel): """ - 根据用户id获取已分配角色列表或根据角色id获取已分配用户列表 - :param query_db: orm对象 - :param page_object: 用户关联角色对象 - :return: 已分配角色列表或已分配用户列表 - """ - allocated_list = [] - if page_object.user_id: - allocated_list = UserDao.get_user_role_allocated_list_by_user_id(query_db, page_object) - if page_object.role_id: - allocated_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object) - - return allocated_list - - @classmethod - def get_user_role_unallocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel): - """ - 根据用户id获取未分配角色列表或根据角色id获取未分配用户列表 + 根据用户id获取已分配角色列表 :param query_db: orm对象 :param page_object: 用户关联角色对象 - :return: 未分配角色列表或未分配用户列表 + :return: 已分配角色列表 """ - unallocated_list = [] - if page_object.user_id: - unallocated_list = UserDao.get_user_role_unallocated_list_by_user_id(query_db, page_object) - if page_object.role_id: - unallocated_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object) + query_user = 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( + **CamelCaseUtil.transform_result(query_user.get('user_basic_info')), + 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')) + ) + query_role_list = [SelectedRoleModel(**row) for row in 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 + ) - return unallocated_list + return result @classmethod def add_user_role_services(cls, query_db: Session, page_object: CrudUserRoleModel): @@ -390,43 +397,46 @@ class UserService: :param page_object: 新增用户关联角色对象 :return: 新增用户关联角色校验结果 """ - if page_object.user_ids and page_object.role_ids: - user_id_list = page_object.user_ids.split(',') + if page_object.user_id and page_object.role_ids: role_id_list = page_object.role_ids.split(',') - if len(user_id_list) == 1 and len(role_id_list) >= 1: - try: - for role_id in role_id_list: - user_role_dict = dict(user_id=page_object.user_ids, role_id=role_id) - user_role = cls.detail_user_role_services(query_db, UserRoleModel(**user_role_dict)) - if user_role: - continue - else: - UserDao.add_user_role_dao(query_db, UserRoleModel(**user_role_dict)) - query_db.commit() - result = dict(is_success=True, message='新增成功') - except Exception as e: - query_db.rollback() - result = dict(is_success=False, message=str(e)) - elif len(user_id_list) >= 1 and len(role_id_list) == 1: - try: - for user_id in user_id_list: - user_role_dict = dict(user_id=user_id, role_id=page_object.role_ids) - user_role = cls.detail_user_role_services(query_db, UserRoleModel(**user_role_dict)) - if user_role: - continue - else: - UserDao.add_user_role_dao(query_db, UserRoleModel(**user_role_dict)) - query_db.commit() - result = dict(is_success=True, message='新增成功') - except Exception as e: - query_db.rollback() - result = dict(is_success=False, message=str(e)) - else: - result = dict(is_success=False, message='不满足新增条件') + try: + 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='分配成功') + except Exception as e: + 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='分配成功') + except Exception as e: + 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)) + 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='新增成功') + except Exception as e: + query_db.rollback() + raise e else: - result = dict(is_success=False, message='传入用户角色关联信息为空') + result = dict(is_success=False, message='不满足新增条件') - return CrudUserResponse(**result) + return CrudResponseModel(**result) @classmethod def delete_user_role_services(cls, query_db: Session, page_object: CrudUserRoleModel): @@ -436,33 +446,31 @@ class UserService: :param page_object: 删除用户关联角色对象 :return: 删除用户关联角色校验结果 """ - if page_object.user_ids and page_object.role_ids: - user_id_list = page_object.user_ids.split(',') - role_id_list = page_object.role_ids.split(',') - if len(user_id_list) == 1 and len(role_id_list) >= 1: + 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: - for role_id in role_id_list: - UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(**dict(user_id=page_object.user_ids, role_id=role_id))) + 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='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) - elif len(user_id_list) >= 1 and len(role_id_list) == 1: + 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(**dict(user_id=user_id, role_id=page_object.role_ids))) + 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='删除成功') except Exception as e: query_db.rollback() - result = dict(is_success=False, message=str(e)) + raise e else: result = dict(is_success=False, message='不满足删除条件') else: result = dict(is_success=False, message='传入用户角色关联信息为空') - return CrudUserResponse(**result) + return CrudResponseModel(**result) @classmethod def detail_user_role_services(cls, query_db: Session, page_object: UserRoleModel): diff --git a/ruoyi-fastapi/module_task/__init__.py b/ruoyi-fastapi-backend/module_task/__init__.py similarity index 100% rename from ruoyi-fastapi/module_task/__init__.py rename to ruoyi-fastapi-backend/module_task/__init__.py diff --git a/ruoyi-fastapi/module_task/scheduler_test.py b/ruoyi-fastapi-backend/module_task/scheduler_test.py similarity index 100% rename from ruoyi-fastapi/module_task/scheduler_test.py rename to ruoyi-fastapi-backend/module_task/scheduler_test.py diff --git a/ruoyi-fastapi-backend/requirements.txt b/ruoyi-fastapi-backend/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..535284aad15dbbb1c7189c3535dbb3e3a1b56d7e --- /dev/null +++ b/ruoyi-fastapi-backend/requirements.txt @@ -0,0 +1,15 @@ +APScheduler==3.10.4 +DateTime==5.4 +fastapi[all]==0.109.0 +loguru==0.7.2 +openpyxl==3.1.2 +pandas==2.1.4 +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 +user-agents==2.2.0 diff --git a/ruoyi-fastapi/app.py b/ruoyi-fastapi-backend/server.py similarity index 38% rename from ruoyi-fastapi/app.py rename to ruoyi-fastapi-backend/server.py index d55cad416b26f186503447c5c9d69ff4f9cb1b04..f7f85c20d6fc98ad3f5a1719f68ae1a20af9272c 100644 --- a/ruoyi-fastapi/app.py +++ b/ruoyi-fastapi-backend/server.py @@ -1,8 +1,8 @@ -from fastapi import FastAPI, Request -import uvicorn -from fastapi.exceptions import HTTPException -from fastapi.middleware.cors import CORSMiddleware +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 @@ -19,93 +19,65 @@ 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 config.env import AppConfig from config.get_redis import RedisUtil from config.get_db import init_create_table from config.get_scheduler import SchedulerUtil -from utils.response_util import * from utils.log_util import logger from utils.common_util import worship +# 生命周期事件 @asynccontextmanager async def lifespan(app: FastAPI): - logger.info("RuoYi-FastAPI开始启动") + 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("RuoYi-FastAPI启动成功") + logger.info(f"{AppConfig.app_name}启动成功") yield await RedisUtil.close_redis_pool(app) await SchedulerUtil.close_system_scheduler() +# 初始化FastAPI对象 app = FastAPI( - title='RuoYi-FastAPI', - description='RuoYi-FastAPI接口文档', - version='1.0.0', + title=AppConfig.app_name, + description=f'{AppConfig.app_name}接口文档', + version=AppConfig.app_version, lifespan=lifespan ) -# 前端页面url -origins = [ - "http://localhost:81", - "http://127.0.0.1:81", -] - -# 后台api允许跨域 -app.add_middleware( - CORSMiddleware, - allow_origins=origins, - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], -) - - -# 自定义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(PermissionException) -async def permission_exception_handler(request: Request, exc: PermissionException): - return ResponseUtil.forbidden(data=exc.data, msg=exc.message) - - -@app.exception_handler(HTTPException) -async def http_exception_handler(request: Request, exc: HTTPException): - return JSONResponse( - content=jsonable_encoder({"message": exc.detail, "code": exc.status_code}), - status_code=exc.status_code - ) +# 挂载子应用 +handle_sub_applications(app) +# 加载中间件处理方法 +handle_middleware(app) +# 加载全局异常处理方法 +handle_exception(app) +# 加载路由列表 controller_list = [ - {'router': loginController, 'prefix': '', 'tags': ['登录模块']}, - {'router': captchaController, 'prefix': '', 'tags': ['验证码模块']}, - {'router': userController, 'prefix': '/system', 'tags': ['系统管理-用户管理']}, - {'router': roleController, 'prefix': '/system', 'tags': ['系统管理-角色管理']}, - {'router': menuController, 'prefix': '/system', 'tags': ['系统管理-菜单管理']}, - {'router': deptController, 'prefix': '/system', 'tags': ['系统管理-部门管理']}, - {'router': postController, 'prefix': '/system', 'tags': ['系统管理-岗位管理']}, - {'router': dictController, 'prefix': '/system', 'tags': ['系统管理-字典管理']}, - {'router': configController, 'prefix': '/system', 'tags': ['系统管理-参数管理']}, - {'router': noticeController, 'prefix': '/system', 'tags': ['系统管理-通知公告管理']}, - {'router': logController, 'prefix': '/monitor', 'tags': ['系统管理-日志管理']}, - {'router': onlineController, 'prefix': '/monitor', 'tags': ['系统监控-在线用户']}, - {'router': jobController, 'prefix': '/monitor', 'tags': ['系统监控-定时任务']}, - {'router': serverController, 'prefix': '/monitor', 'tags': ['系统监控-菜单管理']}, - {'router': cacheController, 'prefix': '/monitor', 'tags': ['系统监控-缓存监控']}, - {'router': commonController, 'prefix': '/common', 'tags': ['通用模块']} + {'router': loginController, 'tags': ['登录模块']}, + {'router': captchaController, 'tags': ['验证码模块']}, + {'router': userController, 'tags': ['系统管理-用户管理']}, + {'router': roleController, 'tags': ['系统管理-角色管理']}, + {'router': menuController, 'tags': ['系统管理-菜单管理']}, + {'router': deptController, 'tags': ['系统管理-部门管理']}, + {'router': postController, 'tags': ['系统管理-岗位管理']}, + {'router': dictController, 'tags': ['系统管理-字典管理']}, + {'router': configController, 'tags': ['系统管理-参数管理']}, + {'router': noticeController, 'tags': ['系统管理-通知公告管理']}, + {'router': logController, 'tags': ['系统管理-日志管理']}, + {'router': onlineController, 'tags': ['系统监控-在线用户']}, + {'router': jobController, 'tags': ['系统监控-定时任务']}, + {'router': serverController, 'tags': ['系统监控-菜单管理']}, + {'router': cacheController, 'tags': ['系统监控-缓存监控']}, + {'router': commonController, 'tags': ['通用模块']} ] for controller in controller_list: - app.include_router(router=controller.get('router'), prefix=controller.get('prefix'), tags=controller.get('tags')) - -if __name__ == '__main__': - uvicorn.run(app='app:app', host="0.0.0.0", port=9099, reload=True) + app.include_router(router=controller.get('router'), tags=controller.get('tags')) diff --git a/ruoyi-fastapi-backend/sql/ruoyi-fastapi.sql b/ruoyi-fastapi-backend/sql/ruoyi-fastapi.sql new file mode 100644 index 0000000000000000000000000000000000000000..0541431652bc754f3b27e7ca44b6d3dd242d25ac --- /dev/null +++ b/ruoyi-fastapi-backend/sql/ruoyi-fastapi.sql @@ -0,0 +1,711 @@ +-- ---------------------------- +-- 1、部门表 +-- ---------------------------- +drop table if exists sys_dept; +create table sys_dept ( + dept_id bigint(20) not null auto_increment comment '部门id', + parent_id bigint(20) default 0 comment '父部门id', + ancestors varchar(50) default '' comment '祖级列表', + dept_name varchar(30) default '' comment '部门名称', + order_num int(4) default 0 comment '显示顺序', + leader varchar(20) default null comment '负责人', + phone varchar(11) default null comment '联系电话', + email varchar(50) default null comment '邮箱', + status char(1) default '0' comment '部门状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (dept_id) +) engine=innodb auto_increment=200 comment = '部门表'; + +-- ---------------------------- +-- 初始化-部门表数据 +-- ---------------------------- +insert into sys_dept values(100, 0, '0', '集团总公司', 0, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(101, 100, '0,100', '深圳分公司', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', sysdate(), '', null); + + +-- ---------------------------- +-- 2、用户信息表 +-- ---------------------------- +drop table if exists sys_user; +create table sys_user ( + user_id bigint(20) not null auto_increment comment '用户ID', + dept_id bigint(20) default null comment '部门ID', + user_name varchar(30) not null comment '用户账号', + nick_name varchar(30) not null comment '用户昵称', + user_type varchar(2) default '00' comment '用户类型(00系统用户)', + email varchar(50) default '' comment '用户邮箱', + phonenumber varchar(11) default '' comment '手机号码', + sex char(1) default '0' comment '用户性别(0男 1女 2未知)', + avatar varchar(100) default '' comment '头像地址', + password varchar(100) default '' comment '密码', + status char(1) default '0' comment '帐号状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + login_ip varchar(128) default '' comment '最后登录IP', + login_date datetime comment '最后登录时间', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (user_id) +) engine=innodb auto_increment=100 comment = '用户信息表'; + +-- ---------------------------- +-- 初始化-用户信息表数据 +-- ---------------------------- +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', sysdate(), 'admin', sysdate(), '', 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', sysdate(), 'admin', sysdate(), '', null, '测试员'); + + +-- ---------------------------- +-- 3、岗位信息表 +-- ---------------------------- +drop table if exists sys_post; +create table sys_post +( + post_id bigint(20) not null auto_increment comment '岗位ID', + post_code varchar(64) not null comment '岗位编码', + post_name varchar(50) not null comment '岗位名称', + post_sort int(4) not null comment '显示顺序', + status char(1) not null comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (post_id) +) engine=innodb comment = '岗位信息表'; + +-- ---------------------------- +-- 初始化-岗位信息表数据 +-- ---------------------------- +insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 4、角色信息表 +-- ---------------------------- +drop table if exists sys_role; +create table sys_role ( + role_id bigint(20) not null auto_increment comment '角色ID', + role_name varchar(30) not null comment '角色名称', + role_key varchar(100) not null comment '角色权限字符串', + role_sort int(4) not null comment '显示顺序', + data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', + dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示', + status char(1) not null comment '角色状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (role_id) +) engine=innodb auto_increment=100 comment = '角色信息表'; + +-- ---------------------------- +-- 初始化-角色信息表数据 +-- ---------------------------- +insert into sys_role values('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员'); +insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色'); + + +-- ---------------------------- +-- 5、菜单权限表 +-- ---------------------------- +drop table if exists sys_menu; +create table sys_menu ( + menu_id bigint(20) not null auto_increment comment '菜单ID', + menu_name varchar(50) not null comment '菜单名称', + parent_id bigint(20) default 0 comment '父菜单ID', + order_num int(4) default 0 comment '显示顺序', + path varchar(200) default '' comment '路由地址', + component varchar(255) default null comment '组件路径', + query varchar(255) default null 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按钮)', + visible char(1) default 0 comment '菜单状态(0显示 1隐藏)', + status char(1) default 0 comment '菜单状态(0正常 1停用)', + perms varchar(100) default null comment '权限标识', + icon varchar(100) default '#' comment '菜单图标', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注', + primary key (menu_id) +) engine=innodb auto_increment=2000 comment = '菜单权限表'; + +-- ---------------------------- +-- 初始化-菜单信息表数据 +-- ---------------------------- +-- 一级菜单 +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('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('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('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('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('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('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('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, ''); + + +-- ---------------------------- +-- 6、用户和角色关联表 用户N-1角色 +-- ---------------------------- +drop table if exists sys_user_role; +create table sys_user_role ( + user_id bigint(20) not null comment '用户ID', + role_id bigint(20) not null comment '角色ID', + primary key(user_id, role_id) +) engine=innodb comment = '用户和角色关联表'; + +-- ---------------------------- +-- 初始化-用户和角色关联表数据 +-- ---------------------------- +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(20) not null comment '角色ID', + menu_id bigint(20) not null comment '菜单ID', + primary key(role_id, menu_id) +) engine=innodb comment = '角色和菜单关联表'; + +-- ---------------------------- +-- 初始化-角色和菜单关联表数据 +-- ---------------------------- +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(20) not null comment '角色ID', + dept_id bigint(20) not null comment '部门ID', + primary key(role_id, dept_id) +) engine=innodb comment = '角色和部门关联表'; + +-- ---------------------------- +-- 初始化-角色和部门关联表数据 +-- ---------------------------- +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(20) not null comment '用户ID', + post_id bigint(20) not null comment '岗位ID', + primary key (user_id, post_id) +) engine=innodb comment = '用户与岗位关联表'; + +-- ---------------------------- +-- 初始化-用户与岗位关联表数据 +-- ---------------------------- +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 bigint(20) not null auto_increment comment '日志主键', + title varchar(50) default '' comment '模块标题', + business_type int(2) default 0 comment '业务类型(0其它 1新增 2修改 3删除)', + method varchar(100) default '' comment '方法名称', + request_method varchar(10) default '' comment '请求方式', + operator_type int(1) default 0 comment '操作类别(0其它 1后台用户 2手机端用户)', + oper_name varchar(50) default '' comment '操作人员', + dept_name varchar(50) default '' comment '部门名称', + oper_url varchar(255) default '' comment '请求URL', + oper_ip varchar(128) default '' comment '主机地址', + oper_location varchar(255) default '' comment '操作地点', + oper_param varchar(2000) default '' comment '请求参数', + json_result varchar(2000) default '' comment '返回参数', + status int(1) default 0 comment '操作状态(0正常 1异常)', + error_msg varchar(2000) default '' comment '错误消息', + oper_time datetime comment '操作时间', + cost_time bigint(20) default 0 comment '消耗时间', + primary key (oper_id), + key idx_sys_oper_log_bt (business_type), + key idx_sys_oper_log_s (status), + key idx_sys_oper_log_ot (oper_time) +) engine=innodb auto_increment=100 comment = '操作日志记录'; + + +-- ---------------------------- +-- 11、字典类型表 +-- ---------------------------- +drop table if exists sys_dict_type; +create table sys_dict_type +( + dict_id bigint(20) not null auto_increment comment '字典主键', + dict_name varchar(100) default '' comment '字典名称', + dict_type varchar(100) default '' comment '字典类型', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_id), + unique (dict_type) +) engine=innodb auto_increment=100 comment = '字典类型表'; + +insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表'); +insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表'); +insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表'); +insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate(), '', null, '任务状态列表'); +insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate(), '', null, '任务分组列表'); +insert into sys_dict_type values(6, '任务执行器', 'sys_job_executor', '0', 'admin', sysdate(), '', null, '任务执行器列表'); +insert into sys_dict_type values(7, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表'); +insert into sys_dict_type values(8, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表'); +insert into sys_dict_type values(9, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表'); +insert into sys_dict_type values(10, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表'); +insert into sys_dict_type values(11, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表'); + + +-- ---------------------------- +-- 12、字典数据表 +-- ---------------------------- +drop table if exists sys_dict_data; +create table sys_dict_data +( + dict_code bigint(20) not null auto_increment comment '字典编码', + dict_sort int(4) default 0 comment '字典排序', + dict_label varchar(100) default '' comment '字典标签', + dict_value varchar(100) default '' comment '字典键值', + dict_type varchar(100) default '' comment '字典类型', + css_class varchar(100) default null comment '样式属性(其他样式扩展)', + list_class varchar(100) default null comment '表格回显样式', + is_default char(1) default 'N' comment '是否默认(Y是 N否)', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_code) +) engine=innodb auto_increment=100 comment = '字典数据表'; + +insert into sys_dict_data values(1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate(), '', null, '性别男'); +insert into sys_dict_data values(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女'); +insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知'); +insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单'); +insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单'); +insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(10, 1, '默认', 'default', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate(), '', null, '默认分组'); +insert into sys_dict_data values(11, 2, '数据库', 'sqlalchemy', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate(), '', null, '数据库分组'); +insert into sys_dict_data values(12, 3, 'redis', 'redis', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate(), '', null, 'reids分组'); +insert into sys_dict_data values(13, 1, '默认', 'default', 'sys_job_executor', '', '', 'N', '0', 'admin', sysdate(), '', null, '线程池'); +insert into sys_dict_data values(14, 2, '进程池', 'processpool', 'sys_job_executor', '', '', 'N', '0', 'admin', sysdate(), '', null, '进程池'); +insert into sys_dict_data values(15, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是'); +insert into sys_dict_data values(16, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否'); +insert into sys_dict_data values(17, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知'); +insert into sys_dict_data values(18, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告'); +insert into sys_dict_data values(19, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(20, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态'); +insert into sys_dict_data values(21, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作'); +insert into sys_dict_data values(22, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作'); +insert into sys_dict_data values(23, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作'); +insert into sys_dict_data values(24, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作'); +insert into sys_dict_data values(25, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作'); +insert into sys_dict_data values(26, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作'); +insert into sys_dict_data values(27, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作'); +insert into sys_dict_data values(28, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作'); +insert into sys_dict_data values(29, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作'); +insert into sys_dict_data values(30, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作'); +insert into sys_dict_data values(31, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(32, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); + + +-- ---------------------------- +-- 13、参数配置表 +-- ---------------------------- +drop table if exists sys_config; +create table sys_config ( + config_id int(5) not null auto_increment comment '参数主键', + config_name varchar(100) default '' comment '参数名称', + config_key varchar(100) default '' comment '参数键名', + config_value varchar(500) default '' comment '参数键值', + config_type char(1) default 'N' comment '系统内置(Y是 N否)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (config_id) +) engine=innodb auto_increment=100 comment = '参数配置表'; + +insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' ); +insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' ); +insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' ); +insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能(true开启,false关闭)'); +insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)'); +insert into sys_config values(6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); + + +-- ---------------------------- +-- 14、系统访问记录 +-- ---------------------------- +drop table if exists sys_logininfor; +create table sys_logininfor ( + info_id bigint(20) not null auto_increment comment '访问ID', + user_name varchar(50) default '' comment '用户账号', + ipaddr varchar(128) default '' comment '登录IP地址', + login_location varchar(255) default '' comment '登录地点', + browser varchar(50) default '' comment '浏览器类型', + os varchar(50) default '' comment '操作系统', + status char(1) default '0' comment '登录状态(0成功 1失败)', + msg varchar(255) default '' comment '提示消息', + login_time datetime comment '访问时间', + primary key (info_id), + key idx_sys_logininfor_s (status), + key idx_sys_logininfor_lt (login_time) +) engine=innodb auto_increment=100 comment = '系统访问记录'; + + +-- ---------------------------- +-- 15、定时任务调度表 +-- ---------------------------- +drop table if exists sys_job; +create table sys_job ( + job_id bigint(20) not null auto_increment comment '任务ID', + job_name varchar(64) default '' comment '任务名称', + job_group varchar(64) default 'default' comment '任务组名', + job_executor varchar(64) default 'default' comment '任务执行器', + invoke_target varchar(500) not null comment '调用目标字符串', + job_args varchar(255) default '' comment '位置参数', + job_kwargs varchar(255) default '' comment '关键字参数', + cron_expression varchar(255) default '' comment 'cron执行表达式', + misfire_policy varchar(20) default '3' comment '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + concurrent char(1) default '1' comment '是否并发执行(0允许 1禁止)', + status char(1) default '0' comment '状态(0正常 1暂停)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注信息', + primary key (job_id, job_name, job_group) +) engine=innodb auto_increment=100 comment = '定时任务调度表'; + +insert into sys_job values(1, '系统默认(无参)', 'default', 'default', 'module_task.scheduler_test.job', NULL, NULL, '0/10 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(2, '系统默认(有参)', 'default', 'default', 'module_task.scheduler_test.job', 'test', NULL, '0/15 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(3, '系统默认(多参)', 'default', 'default', 'module_task.scheduler_test.job', 'new', '{\"test\": 111}', '0/20 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 16、定时任务调度日志表 +-- ---------------------------- +drop table if exists sys_job_log; +create table sys_job_log ( + job_log_id bigint(20) not null auto_increment comment '任务日志ID', + job_name varchar(64) not null comment '任务名称', + job_group varchar(64) not null comment '任务组名', + job_executor varchar(64) not null comment '任务执行器', + invoke_target varchar(500) not null comment '调用目标字符串', + job_args varchar(255) default '' comment '位置参数', + job_kwargs varchar(255) default '' comment '关键字参数', + job_trigger varchar(255) default '' comment '任务触发器', + job_message varchar(500) comment '日志信息', + status char(1) default '0' comment '执行状态(0正常 1失败)', + exception_info varchar(2000) default '' comment '异常信息', + create_time datetime comment '创建时间', + primary key (job_log_id) +) engine=innodb comment = '定时任务调度日志表'; + + +-- ---------------------------- +-- 17、通知公告表 +-- ---------------------------- +drop table if exists sys_notice; +create table sys_notice ( + notice_id int(4) not null auto_increment comment '公告ID', + notice_title varchar(50) not null comment '公告标题', + notice_type char(1) not null comment '公告类型(1通知 2公告)', + notice_content longblob default null comment '公告内容', + status char(1) default '0' comment '公告状态(0正常 1关闭)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(255) default null comment '备注', + primary key (notice_id) +) engine=innodb auto_increment=10 comment = '通知公告表'; + +-- ---------------------------- +-- 初始化-公告信息表数据 +-- ---------------------------- +insert into sys_notice values('1', '温馨提醒:2018-07-01 vfadmin新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员'); +insert into sys_notice values('2', '维护通知:2018-07-01 vfadmin系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员'); + + +-- ---------------------------- +-- 18、代码生成业务表 +-- ---------------------------- +drop table if exists gen_table; +create table gen_table ( + table_id bigint(20) not null auto_increment comment '编号', + table_name varchar(200) default '' comment '表名称', + table_comment varchar(500) default '' comment '表描述', + sub_table_name varchar(64) default null comment '关联子表的表名', + sub_table_fk_name varchar(64) default null comment '子表关联的外键名', + class_name varchar(100) default '' comment '实体类名称', + tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)', + tpl_web_type varchar(30) default '' comment '前端模板类型(element-ui模版 element-plus模版)', + package_name varchar(100) comment '生成包路径', + module_name varchar(30) comment '生成模块名', + business_name varchar(30) comment '生成业务名', + function_name varchar(50) comment '生成功能名', + function_author varchar(50) comment '生成功能作者', + gen_type char(1) default '0' comment '生成代码方式(0zip压缩包 1自定义路径)', + gen_path varchar(200) default '/' comment '生成路径(不填默认项目路径)', + options varchar(1000) comment '其它生成选项', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (table_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表'; + + +-- ---------------------------- +-- 19、代码生成业务表字段 +-- ---------------------------- +drop table if exists gen_table_column; +create table gen_table_column ( + column_id bigint(20) not null auto_increment comment '编号', + table_id bigint(20) comment '归属表编号', + column_name varchar(200) comment '列名称', + column_comment varchar(500) comment '列描述', + column_type varchar(100) comment '列类型', + java_type varchar(500) comment 'JAVA类型', + java_field varchar(200) comment 'JAVA字段名', + is_pk char(1) comment '是否主键(1是)', + is_increment char(1) comment '是否自增(1是)', + is_required char(1) comment '是否必填(1是)', + is_insert char(1) comment '是否为插入字段(1是)', + is_edit char(1) comment '是否编辑字段(1是)', + is_list char(1) comment '是否列表字段(1是)', + is_query char(1) comment '是否查询字段(1是)', + query_type varchar(200) default 'EQ' comment '查询方式(等于、不等于、大于、小于、范围)', + html_type varchar(200) comment '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + dict_type varchar(200) default '' comment '字典类型', + sort int comment '排序', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (column_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表字段'; \ No newline at end of file diff --git a/ruoyi-fastapi-backend/sub_applications/handle.py b/ruoyi-fastapi-backend/sub_applications/handle.py new file mode 100644 index 0000000000000000000000000000000000000000..df2a5f481a56afa59be84e9aa9490b794600dd60 --- /dev/null +++ b/ruoyi-fastapi-backend/sub_applications/handle.py @@ -0,0 +1,10 @@ +from fastapi import FastAPI +from sub_applications.staticfiles import mount_staticfiles + + +def handle_sub_applications(app: FastAPI): + """ + 全局处理子应用挂载 + """ + # 挂载静态文件 + mount_staticfiles(app) diff --git a/ruoyi-fastapi-backend/sub_applications/staticfiles.py b/ruoyi-fastapi-backend/sub_applications/staticfiles.py new file mode 100644 index 0000000000000000000000000000000000000000..6899035d82bdc211c9a3942847a918f969e8c17f --- /dev/null +++ b/ruoyi-fastapi-backend/sub_applications/staticfiles.py @@ -0,0 +1,10 @@ +from fastapi import FastAPI +from fastapi.staticfiles import StaticFiles +from config.env import UploadConfig + + +def mount_staticfiles(app: FastAPI): + """ + 挂载静态文件 + """ + app.mount(f"{UploadConfig.UPLOAD_PREFIX}", StaticFiles(directory=f"{UploadConfig.UPLOAD_PATH}"), name="profile") diff --git a/ruoyi-fastapi/utils/common_util.py b/ruoyi-fastapi-backend/utils/common_util.py similarity index 93% rename from ruoyi-fastapi/utils/common_util.py rename to ruoyi-fastapi-backend/utils/common_util.py index a45d2661a7aa9fa478dea9ab658709a572b709bf..f8f8dcadbb9fac51f3b7bd996d033562d593c350 100644 --- a/ruoyi-fastapi/utils/common_util.py +++ b/ruoyi-fastapi-backend/utils/common_util.py @@ -5,6 +5,7 @@ from openpyxl import Workbook from openpyxl.styles import Alignment, PatternFill from openpyxl.utils import get_column_letter from openpyxl.worksheet.datavalidation import DataValidation +from sqlalchemy.engine.row import Row from typing import List from config.env import CachePathConfig @@ -66,7 +67,10 @@ class CamelCaseUtil: return {cls.__to_camel_case(k): v for k, v in result.items()} # 如果是一组字典或其他类型的列表,遍历列表进行转换 elif isinstance(result, list): - return [cls.transform_result(row) if isinstance(row, dict) else cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) for row in result] + return [cls.transform_result(row) if isinstance(row, (dict, Row)) else (cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) if row else row) for row in result] + # 如果是sqlalchemy的Row实例,遍历Row进行转换 + elif isinstance(result, Row): + return [cls.transform_result(row) if isinstance(row, dict) else (cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) if row else row) for row in result] # 如果是其他类型,如模型实例,先转换为字典 else: return cls.transform_result({c.name: getattr(result, c.name) for c in result.__table__.columns}) diff --git a/ruoyi-fastapi/utils/log_util.py b/ruoyi-fastapi-backend/utils/log_util.py similarity index 100% rename from ruoyi-fastapi/utils/log_util.py rename to ruoyi-fastapi-backend/utils/log_util.py diff --git a/ruoyi-fastapi/utils/message_util.py b/ruoyi-fastapi-backend/utils/message_util.py similarity index 100% rename from ruoyi-fastapi/utils/message_util.py rename to ruoyi-fastapi-backend/utils/message_util.py diff --git a/ruoyi-fastapi/utils/page_util.py b/ruoyi-fastapi-backend/utils/page_util.py similarity index 33% rename from ruoyi-fastapi/utils/page_util.py rename to ruoyi-fastapi-backend/utils/page_util.py index 53fb54fdb950b99c53f81403d99cf277806049fe..cf2da9b0d224e163abaad82329cd3dccf172ddb8 100644 --- a/ruoyi-fastapi/utils/page_util.py +++ b/ruoyi-fastapi-backend/utils/page_util.py @@ -1,30 +1,9 @@ import math -from typing import List - +from typing import Optional, List +from sqlalchemy.orm.query import Query from pydantic import BaseModel, ConfigDict from pydantic.alias_generators import to_camel - - -class PageModel(BaseModel): - """ - 分页模型 - """ - offset: int - page_num: int - page_size: int - total: int - has_next: bool - - -class PageObjectResponse(BaseModel): - """ - 用户管理列表分页查询返回模型 - """ - rows: List = [] - page_num: int - page_size: int - total: int - has_next: bool +from utils.common_util import CamelCaseUtil class PageResponseModel(BaseModel): @@ -34,39 +13,70 @@ class PageResponseModel(BaseModel): model_config = ConfigDict(alias_generator=to_camel) rows: List = [] - page_num: int - page_size: int + page_num: Optional[int] = None + page_size: Optional[int] = None total: int - has_next: bool + has_next: Optional[bool] = None -def get_page_info(offset: int, page_num: int, page_size: int, count: int): +class PageUtil: """ - 根据分页参数获取分页信息 - :param offset: 起始数据位置 - :param page_num: 当前页码 - :param page_size: 当前页面数据量 - :param count: 数据总数 - :return: 分页信息对象 + 分页工具类 """ - has_next = False - if offset >= count: - res_offset_1 = (page_num - 2) * page_size - if res_offset_1 < 0: - res_offset = 0 - res_page_num = 1 - else: - res_offset = res_offset_1 - res_page_num = page_num - 1 - else: - res_offset = offset - if (res_offset + page_size) < count: - has_next = True - res_page_num = page_num - result = dict(offset=res_offset, page_num=res_page_num, page_size=page_size, total=count, has_next=has_next) + @classmethod + def get_page_obj(cls, data_list: List, page_num: int, page_size: int): + """ + 输入数据列表data_list和分页信息,返回分页数据列表结果 + :param data_list: 原始数据列表 + :param page_num: 当前页码 + :param page_size: 当前页面数据量 + :return: 分页数据对象 + """ + # 计算起始索引和结束索引 + start = (page_num - 1) * page_size + end = page_num * page_size + + # 根据计算得到的起始索引和结束索引对数据列表进行切片 + paginated_data = data_list[start:end] + has_next = True if math.ceil(len(data_list) / page_size) > page_num else False + + result = PageResponseModel( + rows=paginated_data, + pageNum=page_num, + pageSize=page_size, + total=len(data_list), + hasNext=has_next + ) + + return result + + @classmethod + def paginate(cls, query: Query, page_num: int, page_size: int, is_page: bool = False): + """ + 输入查询语句和分页信息,返回分页数据列表结果 + :param query: sqlalchemy查询语句 + :param page_num: 当前页码 + :param page_size: 当前页面数据量 + :param is_page: 是否开启分页 + :return: 分页数据对象 + """ + if is_page: + total = query.count() + paginated_data = query.offset((page_num - 1) * page_size).limit(page_size).all() + has_next = True if math.ceil(len(paginated_data) / page_size) > page_num else False + result = PageResponseModel( + rows=CamelCaseUtil.transform_result(paginated_data), + pageNum=page_num, + pageSize=page_size, + total=total, + hasNext=has_next + ) + else: + no_paginated_data = query.all() + result = CamelCaseUtil.transform_result(no_paginated_data) - return PageModel(**result) + return result def get_page_obj(data_list: List, page_num: int, page_size: int): @@ -94,5 +104,3 @@ def get_page_obj(data_list: List, page_num: int, page_size: int): ) return result - - diff --git a/ruoyi-fastapi/utils/pwd_util.py b/ruoyi-fastapi-backend/utils/pwd_util.py similarity index 100% rename from ruoyi-fastapi/utils/pwd_util.py rename to ruoyi-fastapi-backend/utils/pwd_util.py diff --git a/ruoyi-fastapi/utils/response_util.py b/ruoyi-fastapi-backend/utils/response_util.py similarity index 70% rename from ruoyi-fastapi/utils/response_util.py rename to ruoyi-fastapi-backend/utils/response_util.py index 7b223da8b0ae3e249b9782b391e897f5fc1d5ef3..a741074ad03ef7e93e659c877b7acf301ae2b8fb 100644 --- a/ruoyi-fastapi/utils/response_util.py +++ b/ruoyi-fastapi-backend/utils/response_util.py @@ -178,119 +178,12 @@ class ResponseUtil: @classmethod def streaming(cls, *, data: Any = None): + """ + 流式响应方法 + :param data: 流式传输的内容 + :return: 流式响应结果 + """ return StreamingResponse( status_code=status.HTTP_200_OK, content=data ) - - -def response_200(*, data: Any = None, message="获取成功") -> Response: - return JSONResponse( - status_code=status.HTTP_200_OK, - content=jsonable_encoder( - { - 'code': 200, - 'message': message, - 'data': data, - 'success': 'true', - 'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S") - } - ) - ) - - -def response_400(*, data: Any = None, message: str = "获取失败") -> Response: - return JSONResponse( - status_code=status.HTTP_400_BAD_REQUEST, - content=jsonable_encoder( - { - 'code': 400, - 'message': message, - 'data': data, - 'success': 'false', - 'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S") - } - ) - ) - - -def response_401(*, data: Any = None, message: str = "获取失败") -> Response: - return JSONResponse( - status_code=status.HTTP_401_UNAUTHORIZED, - content=jsonable_encoder( - { - 'code': 401, - 'message': message, - 'data': data, - 'success': 'false', - 'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S") - } - ) - ) - - -def response_403(*, data: Any = None, message: str = "获取失败") -> Response: - return JSONResponse( - status_code=status.HTTP_403_FORBIDDEN, - content=jsonable_encoder( - { - 'code': 403, - 'message': message, - 'data': data, - 'success': 'false', - 'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S") - } - ) - ) - - -def response_500(*, data: Any = None, message: str = "接口异常") -> Response: - return JSONResponse( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - content=jsonable_encoder( - { - 'code': 500, - 'message': message, - 'data': data, - 'success': 'false', - 'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S") - } - ) - ) - - -def streaming_response_200(*, data: Any = None): - return StreamingResponse( - status_code=status.HTTP_200_OK, - content=data, - ) - - -class AuthException(Exception): - """ - 自定义令牌异常AuthException - """ - - def __init__(self, data: str = None, message: str = None): - self.data = data - self.message = message - - -class PermissionException(Exception): - """ - 自定义权限异常PermissionException - """ - - def __init__(self, data: str = None, message: str = None): - self.data = data - self.message = message - - -class LoginException(Exception): - """ - 自定义登录异常LoginException - """ - - def __init__(self, data: str = None, message: str = None): - self.data = data - self.message = message diff --git a/ruoyi-fastapi/utils/time_format_util.py b/ruoyi-fastapi-backend/utils/time_format_util.py similarity index 100% rename from ruoyi-fastapi/utils/time_format_util.py rename to ruoyi-fastapi-backend/utils/time_format_util.py diff --git a/ruoyi-fastapi-backend/utils/upload_util.py b/ruoyi-fastapi-backend/utils/upload_util.py new file mode 100644 index 0000000000000000000000000000000000000000..dc71255a931bf0b3894ec8d39a2c8f1b8bce36ac --- /dev/null +++ b/ruoyi-fastapi-backend/utils/upload_util.py @@ -0,0 +1,83 @@ +import random +import os +from fastapi import UploadFile +from datetime import datetime +from config.env import UploadConfig + + +class UploadUtil: + """ + 上传工具类 + """ + + @classmethod + def generate_random_number(cls): + """ + 生成3位数字构成的字符串 + """ + random_number = random.randint(1, 999) + + return f'{random_number:03}' + + @classmethod + def check_file_exists(cls, filepath): + """ + 检查文件是否存在 + """ + return os.path.exists(filepath) + + @classmethod + def check_file_extension(cls, file: UploadFile): + """ + 检查文件后缀是否合法 + """ + file_extension = file.filename.rsplit('.', 1)[-1] + if file_extension in UploadConfig.DEFAULT_ALLOWED_EXTENSION: + return True + return False + + @classmethod + def check_file_timestamp(cls, filename): + """ + 校验文件时间戳是否合法 + """ + timestamp = filename.rsplit('.', 1)[0].split('_')[-1].split(UploadConfig.UPLOAD_MACHINE)[0] + try: + datetime.strptime(timestamp, '%Y%m%d%H%M%S') + return True + except ValueError: + return False + + @classmethod + def check_file_machine(cls, filename): + """ + 校验文件机器码是否合法 + """ + if filename.rsplit('.', 1)[0][-4] == UploadConfig.UPLOAD_MACHINE: + return True + return False + + @classmethod + def check_file_random_code(cls, filename): + """ + 校验文件随机码是否合法 + """ + valid_code_list = [f"{i:03}" for i in range(1, 999)] + if filename.rsplit('.', 1)[0][-3:] in valid_code_list: + return True + return False + + @classmethod + def generate_file(cls, filepath): + """ + 根据文件生成二进制数据 + """ + with open(filepath, 'rb') as response_file: + yield from response_file + + @classmethod + def delete_file(cls, filepath: str): + """ + 根据文件路径删除对应文件 + """ + os.remove(filepath) diff --git a/ruoyi-ui/.editorconfig b/ruoyi-fastapi-frontend/.editorconfig similarity index 100% rename from ruoyi-ui/.editorconfig rename to ruoyi-fastapi-frontend/.editorconfig diff --git a/ruoyi-ui/.env.development b/ruoyi-fastapi-frontend/.env.development similarity index 83% rename from ruoyi-ui/.env.development rename to ruoyi-fastapi-frontend/.env.development index 302ecd1ab0320e185d6d917ef3e90f651f5906b9..b3763cd0813fc7e5777ae2caa9c4350c55f3521c 100644 --- a/ruoyi-ui/.env.development +++ b/ruoyi-fastapi-frontend/.env.development @@ -1,5 +1,5 @@ # 页面标题 -VUE_APP_TITLE = 若依管理系统 +VUE_APP_TITLE = vfadmin管理系统 # 开发环境配置 ENV = 'development' diff --git a/ruoyi-ui/.env.production b/ruoyi-fastapi-frontend/.env.production similarity index 77% rename from ruoyi-ui/.env.production rename to ruoyi-fastapi-frontend/.env.production index b4893b0d9eb70e7c6d0fd7792916f6f2b0a3de03..4e3d5b46ada9ca065f7508fc1fbe9c312a15bc0c 100644 --- a/ruoyi-ui/.env.production +++ b/ruoyi-fastapi-frontend/.env.production @@ -1,5 +1,5 @@ # 页面标题 -VUE_APP_TITLE = 若依管理系统 +VUE_APP_TITLE = vfadmin管理系统 # 生产环境配置 ENV = 'production' diff --git a/ruoyi-ui/.env.staging b/ruoyi-fastapi-frontend/.env.staging similarity index 100% rename from ruoyi-ui/.env.staging rename to ruoyi-fastapi-frontend/.env.staging diff --git a/ruoyi-ui/.eslintignore b/ruoyi-fastapi-frontend/.eslintignore similarity index 100% rename from ruoyi-ui/.eslintignore rename to ruoyi-fastapi-frontend/.eslintignore diff --git a/ruoyi-ui/.eslintrc.js b/ruoyi-fastapi-frontend/.eslintrc.js similarity index 100% rename from ruoyi-ui/.eslintrc.js rename to ruoyi-fastapi-frontend/.eslintrc.js diff --git a/ruoyi-ui/.gitignore b/ruoyi-fastapi-frontend/.gitignore similarity index 100% rename from ruoyi-ui/.gitignore rename to ruoyi-fastapi-frontend/.gitignore diff --git a/ruoyi-ui/README.md b/ruoyi-fastapi-frontend/README.md similarity index 100% rename from ruoyi-ui/README.md rename to ruoyi-fastapi-frontend/README.md diff --git a/ruoyi-ui/babel.config.js b/ruoyi-fastapi-frontend/babel.config.js similarity index 73% rename from ruoyi-ui/babel.config.js rename to ruoyi-fastapi-frontend/babel.config.js index c8267b2ddf4d74b926d2fe7f19d5c69ff5868590..62187c1f48403175dee9f00263967b4251e92ea2 100644 --- a/ruoyi-ui/babel.config.js +++ b/ruoyi-fastapi-frontend/babel.config.js @@ -7,7 +7,10 @@ module.exports = { 'development': { // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. - 'plugins': ['dynamic-import-node'] + 'plugins': ['dynamic-import-node', [ + "import", + { libraryName: "ant-design-vue", libraryDirectory: "es", style: true } + ]] } } } \ No newline at end of file diff --git a/ruoyi-ui/bin/build.bat b/ruoyi-fastapi-frontend/bin/build.bat similarity index 100% rename from ruoyi-ui/bin/build.bat rename to ruoyi-fastapi-frontend/bin/build.bat diff --git a/ruoyi-ui/bin/package.bat b/ruoyi-fastapi-frontend/bin/package.bat similarity index 100% rename from ruoyi-ui/bin/package.bat rename to ruoyi-fastapi-frontend/bin/package.bat diff --git a/ruoyi-ui/bin/run-web.bat b/ruoyi-fastapi-frontend/bin/run-web.bat similarity index 100% rename from ruoyi-ui/bin/run-web.bat rename to ruoyi-fastapi-frontend/bin/run-web.bat diff --git a/ruoyi-fastapi-frontend/build/index.js b/ruoyi-fastapi-frontend/build/index.js new file mode 100644 index 0000000000000000000000000000000000000000..0c57de2aad9ee533046b71c08b56943be304d867 --- /dev/null +++ b/ruoyi-fastapi-frontend/build/index.js @@ -0,0 +1,35 @@ +const { run } = require('runjs') +const chalk = require('chalk') +const config = require('../vue.config.js') +const rawArgv = process.argv.slice(2) +const args = rawArgv.join(' ') + +if (process.env.npm_config_preview || rawArgv.includes('--preview')) { + const report = rawArgv.includes('--report') + + run(`vue-cli-service build ${args}`) + + const port = 9526 + const publicPath = config.publicPath + + var connect = require('connect') + var serveStatic = require('serve-static') + const app = connect() + + app.use( + publicPath, + serveStatic('./dist', { + index: ['index.html', '/'] + }) + ) + + app.listen(port, function () { + console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) + if (report) { + console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) + } + + }) +} else { + run(`vue-cli-service build ${args}`) +} diff --git a/ruoyi-ui/package.json b/ruoyi-fastapi-frontend/package.json similarity index 80% rename from ruoyi-ui/package.json rename to ruoyi-fastapi-frontend/package.json index d3fbe255e1b11de63ebc56d720d5a9829c07b67c..b619047ee427d12eb6d05738664e4b2a01e9063e 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-fastapi-frontend/package.json @@ -1,8 +1,8 @@ { - "name": "ruoyi", - "version": "3.8.5", - "description": "若依管理系统", - "author": "若依", + "name": "vfadmin", + "version": "1.0.0", + "description": "vfadmin管理系统", + "author": "insistence", "license": "MIT", "scripts": { "dev": "vue-cli-service serve", @@ -33,15 +33,17 @@ ], "repository": { "type": "git", - "url": "https://gitee.com/y_project/RuoYi-Vue.git" + "url": "https://gitee.com/insistence2022/RuoYi-Vue-FastAPI.git" }, "dependencies": { + "@antv/g2plot": "^2.4.31", "@riophae/vue-treeselect": "0.4.0", + "ant-design-vue": "^1.7.8", "axios": "0.24.0", "clipboard": "2.0.8", "core-js": "3.25.3", "echarts": "5.4.0", - "element-ui": "2.15.12", + "element-ui": "2.15.14", "file-saver": "2.0.5", "fuse.js": "6.4.3", "highlight.js": "9.18.5", @@ -52,6 +54,7 @@ "quill": "1.3.7", "screenfull": "5.0.2", "sortablejs": "1.10.2", + "viser-vue": "^2.4.8", "vue": "2.6.12", "vue-count-to": "1.0.13", "vue-cropper": "0.5.5", @@ -66,18 +69,22 @@ "@vue/cli-service": "4.4.6", "babel-eslint": "10.1.0", "babel-plugin-dynamic-import-node": "2.3.3", + "babel-plugin-import": "^1.13.8", "chalk": "4.1.0", "compression-webpack-plugin": "5.0.2", "connect": "3.6.6", "eslint": "7.15.0", "eslint-plugin-vue": "7.2.0", + "less": "^3.13.1", + "less-loader": "^5.0.0", "lint-staged": "10.5.3", "runjs": "4.4.2", "sass": "1.32.13", "sass-loader": "10.1.1", "script-ext-html-webpack-plugin": "2.1.5", "svg-sprite-loader": "5.1.1", - "vue-template-compiler": "2.6.12" + "vue-template-compiler": "2.6.12", + "webpack-theme-color-replacer": "^1.3.26" }, "engines": { "node": ">=8.9", diff --git a/ruoyi-ui/public/favicon.ico b/ruoyi-fastapi-frontend/public/favicon.ico similarity index 100% rename from ruoyi-ui/public/favicon.ico rename to ruoyi-fastapi-frontend/public/favicon.ico diff --git a/ruoyi-ui/public/html/ie.html b/ruoyi-fastapi-frontend/public/html/ie.html similarity index 100% rename from ruoyi-ui/public/html/ie.html rename to ruoyi-fastapi-frontend/public/html/ie.html diff --git a/ruoyi-ui/public/index.html b/ruoyi-fastapi-frontend/public/index.html similarity index 100% rename from ruoyi-ui/public/index.html rename to ruoyi-fastapi-frontend/public/index.html diff --git a/ruoyi-ui/public/robots.txt b/ruoyi-fastapi-frontend/public/robots.txt similarity index 100% rename from ruoyi-ui/public/robots.txt rename to ruoyi-fastapi-frontend/public/robots.txt diff --git a/ruoyi-ui/src/App.vue b/ruoyi-fastapi-frontend/src/App.vue similarity index 50% rename from ruoyi-ui/src/App.vue rename to ruoyi-fastapi-frontend/src/App.vue index 29de49f15c6244e8437ac0c816c33a8049585593..b92ea37928e578d8c81a11bdbaed98508b01e597 100644 --- a/ruoyi-ui/src/App.vue +++ b/ruoyi-fastapi-frontend/src/App.vue @@ -11,14 +11,14 @@ import ThemePicker from "@/components/ThemePicker"; export default { name: "App", components: { ThemePicker }, - metaInfo() { - return { - title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title, - titleTemplate: title => { - return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE - } - } + metaInfo() { + return { + title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title, + titleTemplate: title => { + return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE + } } + } }; diff --git a/ruoyi-ui/src/components/Pagination/index.vue b/ruoyi-fastapi-frontend/src/components/Pagination/index.vue similarity index 100% rename from ruoyi-ui/src/components/Pagination/index.vue rename to ruoyi-fastapi-frontend/src/components/Pagination/index.vue diff --git a/ruoyi-ui/src/components/PanThumb/index.vue b/ruoyi-fastapi-frontend/src/components/PanThumb/index.vue similarity index 100% rename from ruoyi-ui/src/components/PanThumb/index.vue rename to ruoyi-fastapi-frontend/src/components/PanThumb/index.vue diff --git a/ruoyi-ui/src/components/ParentView/index.vue b/ruoyi-fastapi-frontend/src/components/ParentView/index.vue similarity index 100% rename from ruoyi-ui/src/components/ParentView/index.vue rename to ruoyi-fastapi-frontend/src/components/ParentView/index.vue diff --git a/ruoyi-ui/src/components/RightPanel/index.vue b/ruoyi-fastapi-frontend/src/components/RightPanel/index.vue similarity index 100% rename from ruoyi-ui/src/components/RightPanel/index.vue rename to ruoyi-fastapi-frontend/src/components/RightPanel/index.vue diff --git a/ruoyi-ui/src/components/RightToolbar/index.vue b/ruoyi-fastapi-frontend/src/components/RightToolbar/index.vue similarity index 65% rename from ruoyi-ui/src/components/RightToolbar/index.vue rename to ruoyi-fastapi-frontend/src/components/RightToolbar/index.vue index 527e07c174bebafc5f2617b038c915c5aeb56c9a..67da293008e3a22f644ee40fad97e4fe7ff53c22 100644 --- a/ruoyi-ui/src/components/RightToolbar/index.vue +++ b/ruoyi-fastapi-frontend/src/components/RightToolbar/index.vue @@ -8,7 +8,17 @@ - + + + + + + + @@ -35,17 +45,26 @@ export default { }; }, props: { + /* 是否显示检索条件 */ showSearch: { type: Boolean, default: true, }, + /* 显隐列信息 */ columns: { type: Array, }, + /* 是否显示检索图标 */ search: { type: Boolean, default: true, }, + /* 显隐列类型(transfer穿梭框、checkbox复选框) */ + showColumnsType: { + type: String, + default: "checkbox", + }, + /* 右外边距 */ gutter: { type: Number, default: 10, @@ -61,10 +80,12 @@ export default { } }, created() { - // 显隐列初始默认隐藏列 - for (let item in this.columns) { - if (this.columns[item].visible === false) { - this.value.push(parseInt(item)); + if (this.showColumnsType == 'transfer') { + // 显隐列初始默认隐藏列 + for (let item in this.columns) { + if (this.columns[item].visible === false) { + this.value.push(parseInt(item)); + } } } }, @@ -88,6 +109,10 @@ export default { showColumn() { this.open = true; }, + // 勾选 + checkboxChange(event, label) { + this.columns.filter(item => item.label == label)[0].visible = event; + } }, }; diff --git a/ruoyi-ui/src/components/RuoYi/Doc/index.vue b/ruoyi-fastapi-frontend/src/components/RuoYi/Doc/index.vue similarity index 100% rename from ruoyi-ui/src/components/RuoYi/Doc/index.vue rename to ruoyi-fastapi-frontend/src/components/RuoYi/Doc/index.vue diff --git a/ruoyi-ui/src/components/RuoYi/Git/index.vue b/ruoyi-fastapi-frontend/src/components/RuoYi/Git/index.vue similarity index 79% rename from ruoyi-ui/src/components/RuoYi/Git/index.vue rename to ruoyi-fastapi-frontend/src/components/RuoYi/Git/index.vue index bdafbaefabe9fcc0ba0fbe0bac21fca6cc66bb56..a323ad9b44ef3dbedcf897ecb683c2c5ad2da114 100644 --- a/ruoyi-ui/src/components/RuoYi/Git/index.vue +++ b/ruoyi-fastapi-frontend/src/components/RuoYi/Git/index.vue @@ -9,7 +9,7 @@ export default { name: 'RuoYiGit', data() { return { - url: 'https://gitee.com/y_project/RuoYi-Vue' + url: 'https://gitee.com/insistence2022/RuoYi-Vue-FastAPI' } }, methods: { diff --git a/ruoyi-ui/src/components/Screenfull/index.vue b/ruoyi-fastapi-frontend/src/components/Screenfull/index.vue similarity index 100% rename from ruoyi-ui/src/components/Screenfull/index.vue rename to ruoyi-fastapi-frontend/src/components/Screenfull/index.vue diff --git a/ruoyi-ui/src/components/SizeSelect/index.vue b/ruoyi-fastapi-frontend/src/components/SizeSelect/index.vue similarity index 100% rename from ruoyi-ui/src/components/SizeSelect/index.vue rename to ruoyi-fastapi-frontend/src/components/SizeSelect/index.vue diff --git a/ruoyi-ui/src/components/SvgIcon/index.vue b/ruoyi-fastapi-frontend/src/components/SvgIcon/index.vue similarity index 100% rename from ruoyi-ui/src/components/SvgIcon/index.vue rename to ruoyi-fastapi-frontend/src/components/SvgIcon/index.vue diff --git a/ruoyi-ui/src/components/ThemePicker/index.vue b/ruoyi-fastapi-frontend/src/components/ThemePicker/index.vue similarity index 100% rename from ruoyi-ui/src/components/ThemePicker/index.vue rename to ruoyi-fastapi-frontend/src/components/ThemePicker/index.vue diff --git a/ruoyi-ui/src/components/TopNav/index.vue b/ruoyi-fastapi-frontend/src/components/TopNav/index.vue similarity index 91% rename from ruoyi-ui/src/components/TopNav/index.vue rename to ruoyi-fastapi-frontend/src/components/TopNav/index.vue index 9fb8dd81d5f7eb7799c6b450d22687ca877e7ca6..86a91c4cf7a033e614ee7a8f9be1869d9c962e8f 100644 --- a/ruoyi-ui/src/components/TopNav/index.vue +++ b/ruoyi-fastapi-frontend/src/components/TopNav/index.vue @@ -5,10 +5,12 @@ @select="handleSelect" > @@ -18,10 +20,12 @@ - {{ item.meta.title }} + v-if="index >= visibleNumber"> + + {{ item.meta.title }} + @@ -53,9 +57,9 @@ export default { if (menu.hidden !== true) { // 兼容顶部栏一级菜单内部跳转 if (menu.path === "/") { - topMenus.push(menu.children[0]); + topMenus.push(menu.children[0]); } else { - topMenus.push(menu); + topMenus.push(menu); } } }); diff --git a/ruoyi-ui/src/components/iFrame/index.vue b/ruoyi-fastapi-frontend/src/components/iFrame/index.vue similarity index 100% rename from ruoyi-ui/src/components/iFrame/index.vue rename to ruoyi-fastapi-frontend/src/components/iFrame/index.vue diff --git a/ruoyi-ui/src/directive/dialog/drag.js b/ruoyi-fastapi-frontend/src/directive/dialog/drag.js similarity index 100% rename from ruoyi-ui/src/directive/dialog/drag.js rename to ruoyi-fastapi-frontend/src/directive/dialog/drag.js diff --git a/ruoyi-fastapi-frontend/src/directive/dialog/dragHeight.js b/ruoyi-fastapi-frontend/src/directive/dialog/dragHeight.js new file mode 100644 index 0000000000000000000000000000000000000000..97e5305447220df4d207c1c345fcb93cc578b99a --- /dev/null +++ b/ruoyi-fastapi-frontend/src/directive/dialog/dragHeight.js @@ -0,0 +1,34 @@ +/** + * v-dialogDragWidth 可拖动弹窗高度(右下角) + * Copyright (c) 2019 ruoyi + */ + +export default { + bind(el) { + const dragDom = el.querySelector('.el-dialog'); + const lineEl = document.createElement('div'); + lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;'; + lineEl.addEventListener('mousedown', + function(e) { + // 鼠标按下,计算当前元素距离可视区的距离 + const disX = e.clientX - el.offsetLeft; + const disY = e.clientY - el.offsetTop; + // 当前宽度 高度 + const curWidth = dragDom.offsetWidth; + const curHeight = dragDom.offsetHeight; + document.onmousemove = function(e) { + e.preventDefault(); // 移动时禁用默认事件 + // 通过事件委托,计算移动的距离 + const xl = e.clientX - disX; + const yl = e.clientY - disY + dragDom.style.width = `${curWidth + xl}px`; + dragDom.style.height = `${curHeight + yl}px`; + }; + document.onmouseup = function(e) { + document.onmousemove = null; + document.onmouseup = null; + }; + }, false); + dragDom.appendChild(lineEl); + } +} diff --git a/ruoyi-fastapi-frontend/src/directive/dialog/dragWidth.js b/ruoyi-fastapi-frontend/src/directive/dialog/dragWidth.js new file mode 100644 index 0000000000000000000000000000000000000000..2df0867307b5314d7e8bde5f6a3030e1d99d50b5 --- /dev/null +++ b/ruoyi-fastapi-frontend/src/directive/dialog/dragWidth.js @@ -0,0 +1,30 @@ +/** + * v-dialogDragWidth 可拖动弹窗宽度(右侧边) + * Copyright (c) 2019 ruoyi + */ + +export default { + bind(el) { + const dragDom = el.querySelector('.el-dialog'); + const lineEl = document.createElement('div'); + lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;'; + lineEl.addEventListener('mousedown', + function (e) { + // 鼠标按下,计算当前元素距离可视区的距离 + const disX = e.clientX - el.offsetLeft; + // 当前宽度 + const curWidth = dragDom.offsetWidth; + document.onmousemove = function (e) { + e.preventDefault(); // 移动时禁用默认事件 + // 通过事件委托,计算移动的距离 + const l = e.clientX - disX; + dragDom.style.width = `${curWidth + l}px`; + }; + document.onmouseup = function (e) { + document.onmousemove = null; + document.onmouseup = null; + }; + }, false); + dragDom.appendChild(lineEl); + } +} diff --git a/ruoyi-ui/src/directive/index.js b/ruoyi-fastapi-frontend/src/directive/index.js similarity index 100% rename from ruoyi-ui/src/directive/index.js rename to ruoyi-fastapi-frontend/src/directive/index.js diff --git a/ruoyi-ui/src/directive/module/clipboard.js b/ruoyi-fastapi-frontend/src/directive/module/clipboard.js similarity index 100% rename from ruoyi-ui/src/directive/module/clipboard.js rename to ruoyi-fastapi-frontend/src/directive/module/clipboard.js diff --git a/ruoyi-ui/src/directive/permission/hasPermi.js b/ruoyi-fastapi-frontend/src/directive/permission/hasPermi.js similarity index 99% rename from ruoyi-ui/src/directive/permission/hasPermi.js rename to ruoyi-fastapi-frontend/src/directive/permission/hasPermi.js index 719536cb11bfe430912f72fc69ac47653d762c4d..7101e3e8368e2292700b7feb8365b549abb33070 100644 --- a/ruoyi-ui/src/directive/permission/hasPermi.js +++ b/ruoyi-fastapi-frontend/src/directive/permission/hasPermi.js @@ -2,7 +2,7 @@ * v-hasPermi 操作权限处理 * Copyright (c) 2019 ruoyi */ - + import store from '@/store' export default { diff --git a/ruoyi-ui/src/directive/permission/hasRole.js b/ruoyi-fastapi-frontend/src/directive/permission/hasRole.js similarity index 99% rename from ruoyi-ui/src/directive/permission/hasRole.js rename to ruoyi-fastapi-frontend/src/directive/permission/hasRole.js index eec4a5b31d46bb91ec8dc0462360453915d233f6..ad9d4d79d07595917be0f6f150a6ac2c076b6512 100644 --- a/ruoyi-ui/src/directive/permission/hasRole.js +++ b/ruoyi-fastapi-frontend/src/directive/permission/hasRole.js @@ -2,7 +2,7 @@ * v-hasRole 角色权限处理 * Copyright (c) 2019 ruoyi */ - + import store from '@/store' export default { diff --git a/ruoyi-ui/src/layout/components/AppMain.vue b/ruoyi-fastapi-frontend/src/layout/components/AppMain.vue similarity index 100% rename from ruoyi-ui/src/layout/components/AppMain.vue rename to ruoyi-fastapi-frontend/src/layout/components/AppMain.vue diff --git a/ruoyi-ui/src/layout/components/IframeToggle/index.vue b/ruoyi-fastapi-frontend/src/layout/components/IframeToggle/index.vue similarity index 50% rename from ruoyi-ui/src/layout/components/IframeToggle/index.vue rename to ruoyi-fastapi-frontend/src/layout/components/IframeToggle/index.vue index 26e17c15ab8564a36d3479f6ce126d5ce23d8ffe..39ad15bb5542ddd9de173a5f56b94069c2048b05 100644 --- a/ruoyi-ui/src/layout/components/IframeToggle/index.vue +++ b/ruoyi-fastapi-frontend/src/layout/components/IframeToggle/index.vue @@ -5,19 +5,28 @@ :key="item.path" :iframeId="'iframe' + index" v-show="$route.path === item.path" - :src="item.meta.link" + :src="iframeUrl(item.meta.link, item.query)" > + + diff --git a/ruoyi-ui/src/views/dashboard/RaddarChart.vue b/ruoyi-fastapi-frontend/src/views/dashboard/RaddarChart.vue similarity index 98% rename from ruoyi-ui/src/views/dashboard/RaddarChart.vue rename to ruoyi-fastapi-frontend/src/views/dashboard/RaddarChart.vue index b1790ca81ef6df676e68e8385ba64dc3551a7ec5..312e018a59ab83a167b0beb9d99dfaf8d3d47ed6 100644 --- a/ruoyi-ui/src/views/dashboard/RaddarChart.vue +++ b/ruoyi-fastapi-frontend/src/views/dashboard/RaddarChart.vue @@ -3,7 +3,7 @@ + + + \ No newline at end of file diff --git a/ruoyi-ui/src/views/dashboard/mixins/resize.js b/ruoyi-fastapi-frontend/src/views/dashboard/mixins/resize.js similarity index 100% rename from ruoyi-ui/src/views/dashboard/mixins/resize.js rename to ruoyi-fastapi-frontend/src/views/dashboard/mixins/resize.js diff --git a/ruoyi-ui/src/views/error/401.vue b/ruoyi-fastapi-frontend/src/views/error/401.vue similarity index 100% rename from ruoyi-ui/src/views/error/401.vue rename to ruoyi-fastapi-frontend/src/views/error/401.vue diff --git a/ruoyi-ui/src/views/error/404.vue b/ruoyi-fastapi-frontend/src/views/error/404.vue similarity index 100% rename from ruoyi-ui/src/views/error/404.vue rename to ruoyi-fastapi-frontend/src/views/error/404.vue diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-fastapi-frontend/src/views/index.vue similarity index 90% rename from ruoyi-ui/src/views/index.vue rename to ruoyi-fastapi-frontend/src/views/index.vue index 20f99f31ad62bba56dd8255f54057550636fd997..9a197cae96d240ad3d167fc6c562972b0c185ece 100644 --- a/ruoyi-ui/src/views/index.vue +++ b/ruoyi-fastapi-frontend/src/views/index.vue @@ -122,7 +122,7 @@ 满180251782 满104180207 满186866453 满201396349 满101456076 满101539465 满264312783 满167385320 满104748341 满160110482 满170801498 满108482800 - 满101046199
136919097 + 满101046199 满136919097 满143961921 满174951577 161281055

微信:更新日志 + +

    +
  1. 操作日志记录部门名称
  2. +
  3. 全局数据存储用户编号
  4. +
  5. 新增编程式判断资源访问权限
  6. +
  7. 操作日志列表新增IP地址查询
  8. +
  9. 定时任务新增页去除状态选项
  10. +
  11. 代码生成支持选择前端模板类型
  12. +
  13. 显隐列组件支持复选框弹出类型
  14. +
  15. 通用排序属性orderBy参数限制长度
  16. +
  17. Excel自定义数据处理器增加单元格/工作簿对象
  18. +
  19. 升级oshi到最新版本6.4.8
  20. +
  21. 升级druid到最新版本1.2.20
  22. +
  23. 升级fastjson到最新版2.0.43
  24. +
  25. 升级pagehelper到最新版1.4.7
  26. +
  27. 升级commons.io到最新版本2.13.0
  28. +
  29. 升级element-ui到最新版本2.15.14
  30. +
  31. 修复五级路由缓存无效问题
  32. +
  33. 修复外链带端口出现的异常
  34. +
  35. 修复树模板父级编码变量错误
  36. +
  37. 修复字典表详情页面搜索问题
  38. +
  39. 修复内链iframe没有传递参数问题
  40. +
  41. 修复自定义字典样式不生效的问题
  42. +
  43. 修复字典缓存删除方法参数错误问题
  44. +
  45. 修复Excel导入数据临时文件无法删除问题
  46. +
  47. 修复未登录带参数访问成功后参数丢失问题
  48. +
  49. 修复HeaderSearch组件跳转query参数丢失问题
  50. +
  51. 修复代码生成导入后必填项与数据库不匹配问题
  52. +
  53. 修复Excels导入时无法获取到dictType字典值问题
  54. +
  55. 优化下载zip方法新增遮罩层
  56. +
  57. 优化头像上传参数新增文件名称
  58. +
  59. 优化字典标签支持自定义分隔符
  60. +
  61. 优化菜单管理类型为按钮状态可选
  62. +
  63. 优化前端防重复提交数据大小限制
  64. +
  65. 优化TopNav菜单没有图标svg不显示
  66. +
  67. 优化数字金额大写转换精度丢失问题
  68. +
  69. 优化富文本Editor组件检验图片格式
  70. +
  71. 优化页签在Firefox浏览器被遮挡的问题
  72. +
  73. 优化个人中心/基本资料修改时数据显示问题
  74. +
  75. 优化缓存监控图表支持跟随屏幕大小自适应调整
  76. +
  77. 其他细节优化
  78. +
+ + +
    +
  1. 支持登录IP黑名单限制
  2. +
  3. 新增监控页面图标显示
  4. +
  5. 操作日志新增消耗时间属性
  6. +
  7. 屏蔽定时任务bean违规的字符
  8. +
  9. 日志管理使用索引提升查询性能
  10. +
  11. 日志注解支持排除指定的请求参数
  12. +
  13. 支持自定义隐藏属性列过滤子对象
  14. +
  15. 升级oshi到最新版本6.4.3
  16. +
  17. 升级druid到最新版本1.2.16
  18. +
  19. 升级fastjson到最新版2.0.34
  20. +
  21. 升级spring-boot到最新版本2.5.15
  22. +
  23. 升级element-ui到最新版本2.15.13
  24. +
  25. 移除apache/commons-fileupload依赖
  26. +
  27. 修复页面切换时布局错乱的问题
  28. +
  29. 修复匿名注解Anonymous空指针问题
  30. +
  31. 修复路由跳转被阻止时内部产生报错信息问题
  32. +
  33. 修复isMatchedIp的参数判断产生空指针的问题
  34. +
  35. 修复用户多角色数据权限可能出现权限抬升的情况
  36. +
  37. 修复开启TopNav后一级菜单路由参数设置无效问题
  38. +
  39. 修复DictTag组件value没有匹配的值时则展示value
  40. +
  41. 优化文件下载出现的异常
  42. +
  43. 优化选择图标组件高亮回显
  44. +
  45. 优化弹窗后导航栏偏移的问题
  46. +
  47. 优化修改密码日志存储明文问题
  48. +
  49. 优化页签栏关闭其他出现的异常问题
  50. +
  51. 优化页签关闭左侧选项排除首页选项
  52. +
  53. 优化关闭当前tab页跳转最右侧tab页
  54. +
  55. 优化缓存列表清除操作提示不变的问题
  56. +
  57. 优化字符未使用下划线不进行驼峰式处理
  58. +
  59. 优化用户导入更新时需获取用户编号问题
  60. +
  61. 优化侧边栏的平台标题与VUE_APP_TITLE保持同步
  62. +
  63. 优化导出Excel时设置dictType属性重复查缓存问题
  64. +
  65. 连接池Druid支持新的配置connectTimeout和socketTimeout
  66. +
  67. 其他细节优化
  68. +
+
  1. 定时任务违规的字符
  2. @@ -881,14 +962,14 @@ - + @@ -908,7 +989,7 @@ export default { data() { return { // 版本号 - version: "3.8.5" + version: "3.8.7" }; }, methods: { diff --git a/ruoyi-ui/src/views/index_v1.vue b/ruoyi-fastapi-frontend/src/views/index_v1.vue similarity index 100% rename from ruoyi-ui/src/views/index_v1.vue rename to ruoyi-fastapi-frontend/src/views/index_v1.vue diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-fastapi-frontend/src/views/login.vue similarity index 95% rename from ruoyi-ui/src/views/login.vue rename to ruoyi-fastapi-frontend/src/views/login.vue index 95cff50fa6bb6bbc377b68330560acb4d6e14f17..86423e5469015d1182b16794053c77d1af646c15 100644 --- a/ruoyi-ui/src/views/login.vue +++ b/ruoyi-fastapi-frontend/src/views/login.vue @@ -1,7 +1,7 @@ @@ -72,8 +72,8 @@ export default { return { codeUrl: "", loginForm: { - username: "admin", - password: "admin123", + username: "", + password: "", rememberMe: false, code: "", uuid: "" @@ -111,6 +111,7 @@ export default { getCode() { getCodeImg().then(res => { this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled; + this.register = res.registerEnabled === undefined ? false : res.registerEnabled; if (this.captchaEnabled) { this.codeUrl = "data:image/gif;base64," + res.img; this.loginForm.uuid = res.uuid; diff --git a/ruoyi-ui/src/views/monitor/cache/index.vue b/ruoyi-fastapi-frontend/src/views/monitor/cache/index.vue similarity index 97% rename from ruoyi-ui/src/views/monitor/cache/index.vue rename to ruoyi-fastapi-frontend/src/views/monitor/cache/index.vue index e81da2e8f4b5079ab19f3258be2c5a19f9fc2ed4..8d2f378406707f1b7b4922f47d2318e9abec36e1 100644 --- a/ruoyi-ui/src/views/monitor/cache/index.vue +++ b/ruoyi-fastapi-frontend/src/views/monitor/cache/index.vue @@ -133,6 +133,10 @@ export default { } ] }); + window.addEventListener("resize", () => { + this.commandstats.resize(); + this.usedmemory.resize(); + }); }); }, // 打开加载层 diff --git a/ruoyi-ui/src/views/monitor/cache/list.vue b/ruoyi-fastapi-frontend/src/views/monitor/cache/list.vue similarity index 100% rename from ruoyi-ui/src/views/monitor/cache/list.vue rename to ruoyi-fastapi-frontend/src/views/monitor/cache/list.vue diff --git a/ruoyi-ui/src/views/monitor/druid/index.vue b/ruoyi-fastapi-frontend/src/views/monitor/druid/index.vue similarity index 74% rename from ruoyi-ui/src/views/monitor/druid/index.vue rename to ruoyi-fastapi-frontend/src/views/monitor/druid/index.vue index c6ad585c17a026c09d509b81ba8b255512e6e3b4..5013f567e3d49890b70dddcf3f49e123f05cf123 100644 --- a/ruoyi-ui/src/views/monitor/druid/index.vue +++ b/ruoyi-fastapi-frontend/src/views/monitor/druid/index.vue @@ -1,5 +1,8 @@ diff --git a/ruoyi-fastapi-frontend/src/views/tool/build/DraggableItem.vue b/ruoyi-fastapi-frontend/src/views/tool/build/DraggableItem.vue new file mode 100644 index 0000000000000000000000000000000000000000..e881778f05ad81e1da4097d32b665fcdb362438a --- /dev/null +++ b/ruoyi-fastapi-frontend/src/views/tool/build/DraggableItem.vue @@ -0,0 +1,100 @@ + diff --git a/ruoyi-fastapi-frontend/src/views/tool/build/IconsDialog.vue b/ruoyi-fastapi-frontend/src/views/tool/build/IconsDialog.vue new file mode 100644 index 0000000000000000000000000000000000000000..958be50c56f1897854da18498db9788a4a3f5a53 --- /dev/null +++ b/ruoyi-fastapi-frontend/src/views/tool/build/IconsDialog.vue @@ -0,0 +1,123 @@ + + + diff --git a/ruoyi-fastapi-frontend/src/views/tool/build/RightPanel.vue b/ruoyi-fastapi-frontend/src/views/tool/build/RightPanel.vue new file mode 100644 index 0000000000000000000000000000000000000000..c2760eb5eab3cf4bb6f02dba47c60c0ee3a14d29 --- /dev/null +++ b/ruoyi-fastapi-frontend/src/views/tool/build/RightPanel.vue @@ -0,0 +1,946 @@ + + + + + diff --git a/ruoyi-fastapi-frontend/src/views/tool/build/TreeNodeDialog.vue b/ruoyi-fastapi-frontend/src/views/tool/build/TreeNodeDialog.vue new file mode 100644 index 0000000000000000000000000000000000000000..fa7f0b2856cc0911e2514521c98373b94aff8345 --- /dev/null +++ b/ruoyi-fastapi-frontend/src/views/tool/build/TreeNodeDialog.vue @@ -0,0 +1,149 @@ + + diff --git a/ruoyi-fastapi-frontend/src/views/tool/build/index.vue b/ruoyi-fastapi-frontend/src/views/tool/build/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..2bd298b8f573796d598c3f2b8a87b1432c55e022 --- /dev/null +++ b/ruoyi-fastapi-frontend/src/views/tool/build/index.vue @@ -0,0 +1,768 @@ + + + + + diff --git a/ruoyi-ui/src/views/tool/gen/basicInfoForm.vue b/ruoyi-fastapi-frontend/src/views/tool/gen/basicInfoForm.vue similarity index 100% rename from ruoyi-ui/src/views/tool/gen/basicInfoForm.vue rename to ruoyi-fastapi-frontend/src/views/tool/gen/basicInfoForm.vue diff --git a/ruoyi-ui/src/views/tool/gen/editTable.vue b/ruoyi-fastapi-frontend/src/views/tool/gen/editTable.vue similarity index 100% rename from ruoyi-ui/src/views/tool/gen/editTable.vue rename to ruoyi-fastapi-frontend/src/views/tool/gen/editTable.vue diff --git a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue b/ruoyi-fastapi-frontend/src/views/tool/gen/genInfoForm.vue similarity index 95% rename from ruoyi-ui/src/views/tool/gen/genInfoForm.vue rename to ruoyi-fastapi-frontend/src/views/tool/gen/genInfoForm.vue index 3f8d67f5cb7c349c357c3edbf0ec61aa6ce732e9..98daf6d528c65ba723d2ff77f4641df724cc374a 100644 --- a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue +++ b/ruoyi-fastapi-frontend/src/views/tool/gen/genInfoForm.vue @@ -11,6 +11,15 @@ + + + 前端类型 + + + + + + @@ -59,6 +68,19 @@ + + + + 生成代码方式 + + + + + zip压缩包 + 自定义路径 + + + @@ -78,19 +100,6 @@ - - - - 生成代码方式 - - - - - zip压缩包 - 自定义路径 - - - @@ -255,10 +264,14 @@ export default { } }; }, - created() {}, watch: { 'info.subTableName': function(val) { this.setSubTableColumns(val); + }, + 'info.tplWebType': function(val) { + if (val === '') { + this.info.tplWebType = "element-ui"; + } } }, methods: { diff --git a/ruoyi-ui/src/views/tool/gen/importTable.vue b/ruoyi-fastapi-frontend/src/views/tool/gen/importTable.vue similarity index 100% rename from ruoyi-ui/src/views/tool/gen/importTable.vue rename to ruoyi-fastapi-frontend/src/views/tool/gen/importTable.vue diff --git a/ruoyi-ui/src/views/tool/gen/index.vue b/ruoyi-fastapi-frontend/src/views/tool/gen/index.vue similarity index 96% rename from ruoyi-ui/src/views/tool/gen/index.vue rename to ruoyi-fastapi-frontend/src/views/tool/gen/index.vue index 3f1f9308a42b082b246b3046865565eaa21aff77..b6943357b9eaee1653fa4ce5638d7e62822efd83 100644 --- a/ruoyi-ui/src/views/tool/gen/index.vue +++ b/ruoyi-fastapi-frontend/src/views/tool/gen/index.vue @@ -1,6 +1,7 @@ @@ -229,7 +230,7 @@ export default { }; }, created() { - this.getList(); + // this.getList(); }, activated() { const time = this.$route.query.t; diff --git a/ruoyi-ui/src/views/tool/swagger/index.vue b/ruoyi-fastapi-frontend/src/views/tool/swagger/index.vue similarity index 76% rename from ruoyi-ui/src/views/tool/swagger/index.vue rename to ruoyi-fastapi-frontend/src/views/tool/swagger/index.vue index b8becc67cf42f8f24024700b6faf2594972ed3fb..fc943404ec22c3f338eafde0e76ca1682591862b 100644 --- a/ruoyi-ui/src/views/tool/swagger/index.vue +++ b/ruoyi-fastapi-frontend/src/views/tool/swagger/index.vue @@ -8,7 +8,7 @@ export default { components: { iFrame }, data() { return { - url: process.env.VUE_APP_BASE_API + "/swagger-ui/index.html" + url: process.env.VUE_APP_BASE_API + "/docs" }; }, }; diff --git a/ruoyi-ui/vue.config.js b/ruoyi-fastapi-frontend/vue.config.js similarity index 72% rename from ruoyi-ui/vue.config.js rename to ruoyi-fastapi-frontend/vue.config.js index 059d975b55b09a89fae75b34f3a31e27ed1065a6..80eb27e0b49f908e7e604940a8d926fbaf2dd7d5 100644 --- a/ruoyi-ui/vue.config.js +++ b/ruoyi-fastapi-frontend/vue.config.js @@ -48,6 +48,9 @@ module.exports = { loaderOptions: { sass: { sassOptions: { outputStyle: "expanded" } + }, + less:{ + javascriptEnabled: true } } }, @@ -90,9 +93,7 @@ module.exports = { }) .end() - config - .when(process.env.NODE_ENV !== 'development', - config => { + config.when(process.env.NODE_ENV !== 'development', config => { config .plugin('ScriptExtHtmlWebpackPlugin') .after('html') @@ -101,36 +102,31 @@ module.exports = { inline: /runtime\..*\.js$/ }]) .end() - config - .optimization.splitChunks({ - chunks: 'all', - cacheGroups: { - libs: { - name: 'chunk-libs', - test: /[\\/]node_modules[\\/]/, - priority: 10, - chunks: 'initial' // only package third parties that are initially dependent - }, - elementUI: { - name: 'chunk-elementUI', // split elementUI into a single package - priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app - test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm - }, - commons: { - name: 'chunk-commons', - test: resolve('src/components'), // can customize your rules - minChunks: 3, // minimum common number - priority: 5, - reuseExistingChunk: true - } + + config.optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial' // only package third parties that are initially dependent + }, + elementUI: { + name: 'chunk-elementUI', // split elementUI into a single package + test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm + priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), // can customize your rules + minChunks: 3, // minimum common number + priority: 5, + reuseExistingChunk: true } - }) - config.optimization.runtimeChunk('single'), - { - from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件 - to: './' //到根目录下 - } - } - ) + } + }) + config.optimization.runtimeChunk('single') + }) } } diff --git a/ruoyi-fastapi/config/env.py b/ruoyi-fastapi/config/env.py deleted file mode 100644 index 3f104db6b471f454e3523f3adae2697af18b68bf..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/config/env.py +++ /dev/null @@ -1,54 +0,0 @@ -import os - - -class JwtConfig: - """ - Jwt配置 - """ - SECRET_KEY = "b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55" - ALGORITHM = "HS256" - ACCESS_TOKEN_EXPIRE_MINUTES = 1440 - REDIS_TOKEN_EXPIRE_MINUTES = 30 - - -class DataBaseConfig: - """ - 数据库配置 - """ - HOST = "127.0.0.1" - PORT = 3306 - USERNAME = 'root' - PASSWORD = 'mysqlroot' - DB = 'ruoyi-fastapi' - - -class RedisConfig: - """ - Redis配置 - """ - HOST = "127.0.0.1" - PORT = 6379 - USERNAME = '' - PASSWORD = '' - DB = 2 - - -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': '短信验证码'} diff --git a/ruoyi-fastapi/module_admin/controller/common_controller.py b/ruoyi-fastapi/module_admin/controller/common_controller.py deleted file mode 100644 index 210774c9461ef6de37b267b018be65d254c89f80..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/controller/common_controller.py +++ /dev/null @@ -1,87 +0,0 @@ -from fastapi import APIRouter, Request -from fastapi import Depends, File, Form -from sqlalchemy.orm import Session -from config.env import CachePathConfig -from config.get_db import get_db -from module_admin.service.login_service import get_current_user -from module_admin.service.common_service import * -from module_admin.service.config_service import ConfigService -from utils.response_util import * -from utils.log_util import * -from module_admin.aspect.interface_auth import CheckUserInterfaceAuth -from typing import Optional - - -commonController = APIRouter() - - -@commonController.post("/upload", dependencies=[Depends(get_current_user), Depends(CheckUserInterfaceAuth('common'))]) -async def common_upload(request: Request, taskPath: str = Form(), uploadId: str = Form(), file: UploadFile = File(...)): - try: - try: - os.makedirs(os.path.join(CachePathConfig.PATH, taskPath, uploadId)) - except FileExistsError: - pass - CommonService.upload_service(CachePathConfig.PATH, taskPath, uploadId, file) - logger.info('上传成功') - return response_200(data={'filename': file.filename, 'path': f'/common/{CachePathConfig.PATHSTR}?taskPath={taskPath}&taskId={uploadId}&filename={file.filename}'}, message="上传成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@commonController.post("/uploadForEditor", dependencies=[Depends(get_current_user), Depends(CheckUserInterfaceAuth('common'))]) -async def editor_upload(request: Request, baseUrl: str = Form(), uploadId: str = Form(), taskPath: str = Form(), file: UploadFile = File(...)): - try: - try: - os.makedirs(os.path.join(CachePathConfig.PATH, taskPath, uploadId)) - except FileExistsError: - pass - CommonService.upload_service(CachePathConfig.PATH, taskPath, uploadId, file) - logger.info('上传成功') - return JSONResponse( - status_code=status.HTTP_200_OK, - content=jsonable_encoder( - { - 'errno': 0, - 'data': { - 'url': f'{baseUrl}/common/{CachePathConfig.PATHSTR}?taskPath={taskPath}&taskId={uploadId}&filename={file.filename}' - }, - } - ) - ) - except Exception as e: - logger.exception(e) - return JSONResponse( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - content=jsonable_encoder( - { - 'errno': 1, - 'message': str(e), - } - ) - ) - - -@commonController.get(f"/{CachePathConfig.PATHSTR}") -async def common_download(request: Request, taskPath: str, taskId: str, filename: str): - try: - def generate_file(): - with open(os.path.join(CachePathConfig.PATH, taskPath, taskId, filename), 'rb') as response_file: - yield from response_file - return streaming_response_200(data=generate_file()) - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) - - -@commonController.get("/config/query/{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 response_200(data=config_query_result, message="获取成功") - except Exception as e: - logger.exception(e) - return response_500(data="", message=str(e)) diff --git a/ruoyi-fastapi/module_admin/entity/vo/common_vo.py b/ruoyi-fastapi/module_admin/entity/vo/common_vo.py deleted file mode 100644 index 072269ed7431546b591170be491ecabb0fb9c63b..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/common_vo.py +++ /dev/null @@ -1,9 +0,0 @@ -from pydantic import BaseModel - - -class CrudResponseModel(BaseModel): - """ - 操作响应模型 - """ - is_success: bool - message: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/dict_vo.py b/ruoyi-fastapi/module_admin/entity/vo/dict_vo.py deleted file mode 100644 index a76116c3540c00cee779a280326efba4082ebe87..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/dict_vo.py +++ /dev/null @@ -1,111 +0,0 @@ -from pydantic import BaseModel -from typing import Union, Optional, List - - -class DictTypeModel(BaseModel): - """ - 字典类型表对应pydantic模型 - """ - dict_id: Optional[int] - dict_name: Optional[str] - dict_type: Optional[str] - status: Optional[str] - create_by: Optional[str] - create_time: Optional[str] - update_by: Optional[str] - update_time: Optional[str] - remark: Optional[str] - - class Config: - from_attributes = True - - -class DictDataModel(BaseModel): - """ - 字典数据表对应pydantic模型 - """ - dict_code: Optional[int] - dict_sort: Optional[int] - dict_label: Optional[str] - dict_value: Optional[str] - dict_type: Optional[str] - css_class: Optional[str] - list_class: Optional[str] - is_default: Optional[str] - status: Optional[str] - create_by: Optional[str] - create_time: Optional[str] - update_by: Optional[str] - update_time: Optional[str] - remark: Optional[str] - - class Config: - from_attributes = True - - -class DictTypeQueryModel(DictTypeModel): - """ - 字典类型管理不分页查询模型 - """ - create_time_start: Optional[str] - create_time_end: Optional[str] - - -class DictTypePageObject(DictTypeQueryModel): - """ - 字典类型管理分页查询模型 - """ - page_num: int - page_size: int - - -class DictTypePageObjectResponse(BaseModel): - """ - 字典类型管理列表分页查询返回模型 - """ - rows: List[Union[DictTypeModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class DeleteDictTypeModel(BaseModel): - """ - 删除字典类型模型 - """ - dict_ids: str - - -class DictDataPageObject(DictDataModel): - """ - 字典数据管理分页查询模型 - """ - page_num: int - page_size: int - - -class DictDataPageObjectResponse(BaseModel): - """ - 字典数据管理列表分页查询返回模型 - """ - rows: List[Union[DictDataModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class DeleteDictDataModel(BaseModel): - """ - 删除字典数据模型 - """ - dict_codes: str - - -class CrudDictResponse(BaseModel): - """ - 操作字典响应模型 - """ - is_success: bool - message: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/job_vo.py b/ruoyi-fastapi/module_admin/entity/vo/job_vo.py deleted file mode 100644 index 8df4ea8aaec56708f28e9bd8738c7721a5f71211..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/job_vo.py +++ /dev/null @@ -1,130 +0,0 @@ -from pydantic import BaseModel -from typing import Union, Optional, List - - -class JobModel(BaseModel): - """ - 定时任务调度表对应pydantic模型 - """ - job_id: Optional[int] - job_name: Optional[str] - job_group: Optional[str] - job_executor: Optional[str] - invoke_target: Optional[str] - job_args: Optional[str] - job_kwargs: Optional[str] - cron_expression: Optional[str] - misfire_policy: Optional[str] - concurrent: Optional[str] - status: Optional[str] - create_by: Optional[str] - create_time: Optional[str] - update_by: Optional[str] - update_time: Optional[str] - remark: Optional[str] - - class Config: - from_attributes = True - - -class JobLogModel(BaseModel): - """ - 定时任务调度日志表对应pydantic模型 - """ - job_log_id: Optional[int] - job_name: Optional[str] - job_group: Optional[str] - job_executor: Optional[str] - invoke_target: Optional[str] - job_args: Optional[str] - job_kwargs: Optional[str] - job_trigger: Optional[str] - job_message: Optional[str] - status: Optional[str] - exception_info: Optional[str] - create_time: Optional[str] - - class Config: - from_attributes = True - - -class JobPageObject(JobModel): - """ - 定时任务管理分页查询模型 - """ - page_num: int - page_size: int - - -class JobPageObjectResponse(BaseModel): - """ - 定时任务管理列表分页查询返回模型 - """ - rows: List[Union[JobModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class CrudJobResponse(BaseModel): - """ - 操作定时任务及日志响应模型 - """ - is_success: bool - message: str - - -class EditJobModel(JobModel): - """ - 编辑定时任务模型 - """ - type: Optional[str] - - -class DeleteJobModel(BaseModel): - """ - 删除定时任务模型 - """ - job_ids: str - - -class JobLogQueryModel(JobLogModel): - """ - 定时任务日志不分页查询模型 - """ - create_time_start: Optional[str] - create_time_end: Optional[str] - - -class JobLogPageObject(JobLogQueryModel): - """ - 定时任务日志管理分页查询模型 - """ - page_num: int - page_size: int - - -class JobLogPageObjectResponse(BaseModel): - """ - 定时任务日志管理列表分页查询返回模型 - """ - rows: List[Union[JobLogModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class DeleteJobLogModel(BaseModel): - """ - 删除定时任务日志模型 - """ - job_log_ids: str - - -class ClearJobLogModel(BaseModel): - """ - 清除定时任务日志模型 - """ - oper_type: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/menu_vo.py b/ruoyi-fastapi/module_admin/entity/vo/menu_vo.py deleted file mode 100644 index d6a0fccfbd43e17816b626c5281642b89cdb9477..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/menu_vo.py +++ /dev/null @@ -1,85 +0,0 @@ -from pydantic import BaseModel -from typing import Union, Optional, List - - -class MenuModel(BaseModel): - """ - 菜单表对应pydantic模型 - """ - menu_id: Optional[int] - menu_name: Optional[str] - parent_id: Optional[int] - order_num: Optional[int] - path: Optional[str] - component: Optional[str] - query: Optional[str] - is_frame: Optional[int] - is_cache: Optional[int] - menu_type: Optional[str] - visible: Optional[str] - status: Optional[str] - perms: Optional[str] - icon: Optional[str] - create_by: Optional[str] - create_time: Optional[str] - update_by: Optional[str] - update_time: Optional[str] - remark: Optional[str] - - class Config: - from_attributes = True - - -class MenuTreeModel(MenuModel): - """ - 菜单树查询模型 - """ - type: Optional[str] - - -class MenuPageObject(MenuModel): - """ - 菜单管理分页查询模型 - """ - page_num: int - page_size: int - - -class MenuPageObjectResponse(BaseModel): - """ - 菜单管理列表分页查询返回模型 - """ - rows: List[Union[MenuModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class MenuResponse(BaseModel): - """ - 菜单管理列表不分页查询返回模型 - """ - rows: List[Union[MenuModel, None]] = [] - - -class MenuTree(BaseModel): - """ - 菜单树响应模型 - """ - menu_tree: Union[List, None] - - -class CrudMenuResponse(BaseModel): - """ - 操作菜单响应模型 - """ - is_success: bool - message: str - - -class DeleteMenuModel(BaseModel): - """ - 删除菜单模型 - """ - menu_ids: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/online_vo.py b/ruoyi-fastapi/module_admin/entity/vo/online_vo.py deleted file mode 100644 index eeef4d371d5c26fe88de1b802ccc0c29bdc01d6d..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/online_vo.py +++ /dev/null @@ -1,50 +0,0 @@ -from pydantic import BaseModel -from typing import Union, Optional, List - - -class OnlineModel(BaseModel): - """ - 在线用户对应pydantic模型 - """ - session_id: Optional[str] - user_name: Optional[str] - dept_name: Optional[str] - ipaddr: Optional[str] - login_location: Optional[str] - browser: Optional[str] - os: Optional[str] - login_time: Optional[str] - - -class OnlinePageObject(OnlineModel): - """ - 在线用户分页查询模型 - """ - page_num: int - page_size: int - - -class OnlinePageObjectResponse(BaseModel): - """ - 在线用户列表分页查询返回模型 - """ - rows: List[Union[OnlineModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class CrudOnlineResponse(BaseModel): - """ - 操作在线用户响应模型 - """ - is_success: bool - message: str - - -class DeleteOnlineModel(BaseModel): - """ - 强退在线用户模型 - """ - session_ids: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/post_vo.py b/ruoyi-fastapi/module_admin/entity/vo/post_vo.py deleted file mode 100644 index a7a7abecc7990a26c527e0779039eecf8027fb9d..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/post_vo.py +++ /dev/null @@ -1,44 +0,0 @@ -from pydantic import BaseModel -from typing import Union, List -from module_admin.entity.vo.user_vo import PostModel - - -class PostPageObject(PostModel): - """ - 岗位管理分页查询模型 - """ - page_num: int - page_size: int - - -class PostPageObjectResponse(BaseModel): - """ - 岗位管理列表分页查询返回模型 - """ - rows: List[Union[PostModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class PostSelectOptionResponseModel(BaseModel): - """ - 岗位管理不分页查询模型 - """ - post: List[Union[PostModel, None]] - - -class CrudPostResponse(BaseModel): - """ - 操作岗位响应模型 - """ - is_success: bool - message: str - - -class DeletePostModel(BaseModel): - """ - 删除岗位模型 - """ - post_ids: str diff --git a/ruoyi-fastapi/module_admin/entity/vo/role_vo.py b/ruoyi-fastapi/module_admin/entity/vo/role_vo.py deleted file mode 100644 index 10558c3eec22ce5077c182e2e7450f6cab631bff..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/role_vo.py +++ /dev/null @@ -1,102 +0,0 @@ -from pydantic import BaseModel -from typing import Union, Optional, List -from module_admin.entity.vo.user_vo import RoleModel -from module_admin.entity.vo.dept_vo import DeptModel -from module_admin.entity.vo.menu_vo import MenuModel - - -class RoleMenuModel(BaseModel): - """ - 角色和菜单关联表对应pydantic模型 - """ - role_id: Optional[int] - menu_id: Optional[int] - - class Config: - from_attributes = True - - -class RoleDeptModel(BaseModel): - """ - 角色和部门关联表对应pydantic模型 - """ - role_id: Optional[int] - dept_id: Optional[int] - - class Config: - from_attributes = True - - -class RoleQueryModel(RoleModel): - """ - 角色管理不分页查询模型 - """ - create_time_start: Optional[str] = None - create_time_end: Optional[str] = None - - -class RolePageObject(RoleQueryModel): - """ - 角色管理分页查询模型 - """ - page_num: int - page_size: int - - -class RolePageObjectResponse(BaseModel): - """ - 角色管理列表分页查询返回模型 - """ - rows: List[Union[RoleModel, None]] = [] - page_num: int - page_size: int - total: int - has_next: bool - - -class RoleSelectOptionResponseModel(BaseModel): - """ - 角色管理不分页查询模型 - """ - role: List[Union[RoleModel, None]] - - -class CrudRoleResponse(BaseModel): - """ - 操作角色响应模型 - """ - is_success: bool - message: str - - -class AddRoleModel(RoleModel): - """ - 新增角色模型 - """ - menu_id: Optional[str] - type: Optional[str] - - -class RoleDataScopeModel(RoleModel): - """ - 角色数据权限模型 - """ - dept_id: Optional[str] - - -class DeleteRoleModel(BaseModel): - """ - 删除角色模型 - """ - role_ids: str - update_by: Optional[str] - update_time: Optional[str] - - -class RoleDetailModel(BaseModel): - """ - 获取角色详情信息响应模型 - """ - role: Union[RoleModel, None] - menu: List[Union[MenuModel, None]] - dept: List[Union[DeptModel, None]] diff --git a/ruoyi-fastapi/module_admin/entity/vo/server_vo.py b/ruoyi-fastapi/module_admin/entity/vo/server_vo.py deleted file mode 100644 index 36715968510aff174737cf82a97844bc62efb505..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/entity/vo/server_vo.py +++ /dev/null @@ -1,53 +0,0 @@ -from pydantic import BaseModel -from typing import Optional, List - - -class CpuInfo(BaseModel): - cpu_num: Optional[int] - used: Optional[str] - sys: Optional[str] - free: Optional[str] - - -class MemoryInfo(BaseModel): - total: Optional[str] - used: Optional[str] - free: Optional[str] - usage: Optional[str] - - -class SysInfo(BaseModel): - computer_ip: Optional[str] - computer_name: Optional[str] - os_arch: Optional[str] - os_name: Optional[str] - - -class PyInfo(BaseModel): - name: Optional[str] - version: Optional[str] - start_time: Optional[str] - run_time: Optional[str] - home: Optional[str] - project_dir: Optional[str] - - -class SysFiles(BaseModel): - dir_name: Optional[str] - sys_type_name: Optional[str] - disk_name: Optional[str] - total: Optional[str] - used: Optional[str] - free: Optional[str] - usage: Optional[str] - - -class ServerMonitorModel(BaseModel): - """ - 服务监控对应pydantic模型 - """ - cpu: Optional[CpuInfo] - py: Optional[PyInfo] - mem: Optional[MemoryInfo] - sys: Optional[SysInfo] - sys_files: Optional[List[SysFiles]] diff --git a/ruoyi-fastapi/module_admin/service/common_service.py b/ruoyi-fastapi/module_admin/service/common_service.py deleted file mode 100644 index 447f28add007cc13551c7f6dbe5b8d71e099c736..0000000000000000000000000000000000000000 --- a/ruoyi-fastapi/module_admin/service/common_service.py +++ /dev/null @@ -1,18 +0,0 @@ -import os -from fastapi import UploadFile - - -class CommonService: - """ - 通用模块服务层 - """ - - @classmethod - def upload_service(cls, path: str, task_path: str, upload_id: str, file: UploadFile): - - filepath = os.path.join(path, task_path, upload_id, f'{file.filename}') - with open(filepath, 'wb') as f: - # 流式写出大型文件,这里的10代表10MB - for chunk in iter(lambda: file.file.read(1024 * 1024 * 10), b''): - f.write(chunk) - diff --git a/ruoyi-ui/src/assets/images/profile.jpg b/ruoyi-ui/src/assets/images/profile.jpg deleted file mode 100644 index b3a940b21cc9dcea01e62d94e243eebcf76d96bc..0000000000000000000000000000000000000000 Binary files a/ruoyi-ui/src/assets/images/profile.jpg and /dev/null differ diff --git a/ruoyi-ui/src/directive/dialog/dragHeight.js b/ruoyi-ui/src/directive/dialog/dragHeight.js deleted file mode 100644 index d1590f8df06305193c1458ee0b0a2b4557b2a5c9..0000000000000000000000000000000000000000 --- a/ruoyi-ui/src/directive/dialog/dragHeight.js +++ /dev/null @@ -1,34 +0,0 @@ -/** -* v-dialogDragWidth 可拖动弹窗高度(右下角) -* Copyright (c) 2019 ruoyi -*/ - -export default { - bind(el) { - const dragDom = el.querySelector('.el-dialog'); - const lineEl = document.createElement('div'); - lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;'; - lineEl.addEventListener('mousedown', - function(e) { - // 鼠标按下,计算当前元素距离可视区的距离 - const disX = e.clientX - el.offsetLeft; - const disY = e.clientY - el.offsetTop; - // 当前宽度 高度 - const curWidth = dragDom.offsetWidth; - const curHeight = dragDom.offsetHeight; - document.onmousemove = function(e) { - e.preventDefault(); // 移动时禁用默认事件 - // 通过事件委托,计算移动的距离 - const xl = e.clientX - disX; - const yl = e.clientY - disY - dragDom.style.width = `${curWidth + xl}px`; - dragDom.style.height = `${curHeight + yl}px`; - }; - document.onmouseup = function(e) { - document.onmousemove = null; - document.onmouseup = null; - }; - }, false); - dragDom.appendChild(lineEl); - } -} \ No newline at end of file diff --git a/ruoyi-ui/src/directive/dialog/dragWidth.js b/ruoyi-ui/src/directive/dialog/dragWidth.js deleted file mode 100644 index d5cda3adb1a9c99017dd373090c7a66c58473b40..0000000000000000000000000000000000000000 --- a/ruoyi-ui/src/directive/dialog/dragWidth.js +++ /dev/null @@ -1,30 +0,0 @@ -/** -* v-dialogDragWidth 可拖动弹窗宽度(右侧边) -* Copyright (c) 2019 ruoyi -*/ - -export default { - bind(el) { - const dragDom = el.querySelector('.el-dialog'); - const lineEl = document.createElement('div'); - lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;'; - lineEl.addEventListener('mousedown', - function (e) { - // 鼠标按下,计算当前元素距离可视区的距离 - const disX = e.clientX - el.offsetLeft; - // 当前宽度 - const curWidth = dragDom.offsetWidth; - document.onmousemove = function (e) { - e.preventDefault(); // 移动时禁用默认事件 - // 通过事件委托,计算移动的距离 - const l = e.clientX - disX; - dragDom.style.width = `${curWidth + l}px`; - }; - document.onmouseup = function (e) { - document.onmousemove = null; - document.onmouseup = null; - }; - }, false); - dragDom.appendChild(lineEl); - } -} \ No newline at end of file diff --git a/ruoyi-ui/src/views/components/icons/element-icons.js b/ruoyi-ui/src/views/components/icons/element-icons.js deleted file mode 100644 index 9ea4d63fdeed8af3c21c728e9fbfc5153d8ecd46..0000000000000000000000000000000000000000 --- a/ruoyi-ui/src/views/components/icons/element-icons.js +++ /dev/null @@ -1,3 +0,0 @@ -const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round'] - -export default elementIcons diff --git a/ruoyi-ui/src/views/components/icons/index.vue b/ruoyi-ui/src/views/components/icons/index.vue deleted file mode 100644 index d3c9a7190c28fdb1b8d1940e73fb276f81486e73..0000000000000000000000000000000000000000 --- a/ruoyi-ui/src/views/components/icons/index.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - - - diff --git a/ruoyi-ui/src/views/components/icons/svg-icons.js b/ruoyi-ui/src/views/components/icons/svg-icons.js deleted file mode 100644 index 724cd8e9d102215564db0f2c07404659343b6c42..0000000000000000000000000000000000000000 --- a/ruoyi-ui/src/views/components/icons/svg-icons.js +++ /dev/null @@ -1,10 +0,0 @@ -const req = require.context('../../../assets/icons/svg', false, /\.svg$/) -const requireAll = requireContext => requireContext.keys() - -const re = /\.\/(.*)\.svg/ - -const svgIcons = requireAll(req).map(i => { - return i.match(re)[1] -}) - -export default svgIcons