!1 RuoYi-Vue3-FastAPI v1.0.0
Merge pull request !1 from insistence/develop
This commit is contained in:
36
README.en.md
36
README.en.md
@@ -1,36 +0,0 @@
|
|||||||
# RuoYi-Vue3-FastAPI
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
|
|
||||||
|
|
||||||
#### 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/)
|
|
199
README.md
199
README.md
@@ -1,39 +1,184 @@
|
|||||||
# RuoYi-Vue3-FastAPI
|
<p align="center">
|
||||||
|
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
|
||||||
|
</p>
|
||||||
|
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi-Vue3-FastAPI v1.0.0</h1>
|
||||||
|
<h4 align="center">基于RuoYi-Vue3+FastAPI前后端分离的快速开发框架</h4>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI/stargazers"><img src="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI/badge/star.svg?theme=dark"></a>
|
||||||
|
<a href="https://github.com/insistence/RuoYi-Vue3-FastAPI"><img src="https://img.shields.io/github/stars/insistence/RuoYi-Vue3-FastAPI?style=social"></a>
|
||||||
|
<a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI"><img src="https://img.shields.io/badge/RuoYiVue3FastAPI-v1.0.0-brightgreen.svg"></a>
|
||||||
|
<a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
||||||
|
<img src="https://img.shields.io/badge/python-≥3.8-blue">
|
||||||
|
<img src="https://img.shields.io/badge/MySQL-≥5.7-blue">
|
||||||
|
</p>
|
||||||
|
|
||||||
#### 介绍
|
## 平台简介
|
||||||
{**以下是 Gitee 平台说明,您可以替换此简介**
|
|
||||||
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
|
||||||
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
|
||||||
|
|
||||||
#### 软件架构
|
RuoYi-Vue-FastAPI是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
|
||||||
软件架构说明
|
|
||||||
|
|
||||||
|
* 前端采用Vue、Element Plus,基于<u>[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3)</u>前端项目修改。
|
||||||
|
* 后端采用FastAPI、sqlalchemy、MySQL、Redis、OAuth2 & Jwt。
|
||||||
|
* 权限认证使用OAuth2 & Jwt,支持多终端认证系统。
|
||||||
|
* 支持加载动态权限菜单,多方式轻松权限控制。
|
||||||
|
* Vue2版本:
|
||||||
|
- Gitte仓库地址:https://gitee.com/insistence2022/RuoYi-Vue-FastAPI。
|
||||||
|
- GitHub仓库地址:https://github.com/insistence/RuoYi-Vue-FastAPI。
|
||||||
|
* 纯Python版本:
|
||||||
|
- Gitte仓库地址:https://gitee.com/insistence2022/dash-fastapi-admin。
|
||||||
|
- GitHub仓库地址:https://github.com/insistence/Dash-FastAPI-Admin。
|
||||||
|
* 特别鸣谢:<u>[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3)</u>。
|
||||||
|
|
||||||
#### 安装教程
|
## 内置功能
|
||||||
|
|
||||||
1. xxxx
|
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
|
||||||
2. xxxx
|
2. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
|
||||||
3. xxxx
|
3. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
|
||||||
|
4. 部门管理:配置系统组织机构(公司、部门、小组)。
|
||||||
|
5. 岗位管理:配置系统用户所属担任职务。
|
||||||
|
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
|
||||||
|
7. 参数管理:对系统动态配置常用参数。
|
||||||
|
8. 通知公告:系统通知公告信息发布维护。
|
||||||
|
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
|
||||||
|
10. 登录日志:系统登录日志记录查询包含登录异常。
|
||||||
|
11. 在线用户:当前系统中活跃用户状态监控。
|
||||||
|
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
|
||||||
|
13. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
|
||||||
|
14. 缓存监控:对系统的缓存信息查询,命令统计等。
|
||||||
|
15. 系统接口:根据业务代码自动生成相关的api接口文档。
|
||||||
|
|
||||||
#### 使用说明
|
## 演示图
|
||||||
|
|
||||||
1. xxxx
|
<table>
|
||||||
2. xxxx
|
<tr>
|
||||||
3. xxxx
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/login.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/dashboard.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/user.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/role.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/menu.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/dept.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/post.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/dict.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/config.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/notice.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/operLog.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/loginLog.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/online.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/job.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/server.png"/></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/cache.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/cacheList.png"></td>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/api.png"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/profile.png"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
#### 参与贡献
|
## 在线体验
|
||||||
|
- *账号:admin*
|
||||||
|
- *密码:admin123*
|
||||||
|
- 演示地址:<a href="https://vfadmin.insistence.tech">vfadmin管理系统<a>
|
||||||
|
|
||||||
1. Fork 本仓库
|
## 项目开发及发布相关
|
||||||
2. 新建 Feat_xxx 分支
|
|
||||||
3. 提交代码
|
|
||||||
4. 新建 Pull Request
|
|
||||||
|
|
||||||
|
### 开发
|
||||||
|
|
||||||
#### 特技
|
```bash
|
||||||
|
# 克隆项目
|
||||||
|
git clone https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI.git
|
||||||
|
|
||||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
# 进入项目根目录
|
||||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
cd RuoYi-Vue3-FastAPI
|
||||||
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/)
|
```bash
|
||||||
|
# 进入前端目录
|
||||||
|
cd ruoyi-fastapi-frontend
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
npm install 或 yarn --registry=https://registry.npmmirror.com
|
||||||
|
|
||||||
|
# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
|
||||||
|
npm install --registry=https://registry.npmmirror.com
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
npm run dev 或 yarn 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 或 yarn build:stage
|
||||||
|
|
||||||
|
# 构建生产环境
|
||||||
|
npm run build:prod 或 yarn build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 后端
|
||||||
|
```bash
|
||||||
|
# 配置环境
|
||||||
|
在.env.prod文件中配置生产环境的数据库和redis
|
||||||
|
|
||||||
|
# 运行后端
|
||||||
|
python3 app.py --env=prod
|
||||||
|
```
|
||||||
|
|
||||||
|
## 交流与赞助
|
||||||
|
如果有对本项目及FastAPI感兴趣的朋友,欢迎加入知识星球一起交流学习,让我们一起变得更强。如果你觉得这个项目帮助到了你,你可以请作者喝杯咖啡表示鼓励☕。扫描下面微信二维码添加微信备注VF-Admin即可进群。
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><img alt="zsxq" src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/zsxq.jpg"></td>
|
||||||
|
<td><img alt="zanzhu" src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/zanzhu.jpg"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><img alt="wxcode" src="https://gitee.com/insistence2022/RuoYi-Vue-FastAPI/raw/master/demo-pictures/wxcode.jpg"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
50
ruoyi-fastapi-backend/.env.dev
Normal file
50
ruoyi-fastapi-backend/.env.dev
Normal file
@@ -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
|
50
ruoyi-fastapi-backend/.env.prod
Normal file
50
ruoyi-fastapi-backend/.env.prod
Normal file
@@ -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
|
@@ -1,119 +1,12 @@
|
|||||||
from fastapi import FastAPI, Request
|
|
||||||
from fastapi.exceptions import HTTPException
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
|
||||||
from fastapi.staticfiles import StaticFiles
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from contextlib import asynccontextmanager
|
from server import app, AppConfig
|
||||||
from module_admin.controller.login_controller import loginController
|
|
||||||
from module_admin.controller.captcha_controller import captchaController
|
|
||||||
from module_admin.controller.user_controller import userController
|
|
||||||
from module_admin.controller.menu_controller import menuController
|
|
||||||
from module_admin.controller.dept_controller import deptController
|
|
||||||
from module_admin.controller.role_controller import roleController
|
|
||||||
from module_admin.controller.post_controler import postController
|
|
||||||
from module_admin.controller.dict_controller import dictController
|
|
||||||
from module_admin.controller.config_controller import configController
|
|
||||||
from module_admin.controller.notice_controller import noticeController
|
|
||||||
from module_admin.controller.log_controller import logController
|
|
||||||
from module_admin.controller.online_controller import onlineController
|
|
||||||
from module_admin.controller.job_controller import jobController
|
|
||||||
from module_admin.controller.server_controller import serverController
|
|
||||||
from module_admin.controller.cache_controller import cacheController
|
|
||||||
from module_admin.controller.common_controller import commonController
|
|
||||||
from config.env import UploadConfig
|
|
||||||
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开始启动")
|
|
||||||
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启动成功")
|
|
||||||
yield
|
|
||||||
await RedisUtil.close_redis_pool(app)
|
|
||||||
await SchedulerUtil.close_system_scheduler()
|
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(
|
|
||||||
title='RuoYi-FastAPI',
|
|
||||||
description='RuoYi-FastAPI接口文档',
|
|
||||||
version='1.0.0',
|
|
||||||
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=["*"],
|
|
||||||
)
|
|
||||||
|
|
||||||
# 实例化UploadConfig,确保应用启动时上传目录存在
|
|
||||||
upload_config = UploadConfig()
|
|
||||||
|
|
||||||
# 挂载静态文件路径
|
|
||||||
app.mount(f"{upload_config.UPLOAD_PREFIX}", StaticFiles(directory=f"{upload_config.UPLOAD_PATH}"), name="profile")
|
|
||||||
|
|
||||||
|
|
||||||
# 自定义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
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
controller_list = [
|
|
||||||
{'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'), tags=controller.get('tags'))
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
uvicorn.run(app='app:app', host="0.0.0.0", port=9099, root_path='/dev-api', reload=True)
|
uvicorn.run(
|
||||||
|
app='app:app',
|
||||||
|
host=AppConfig.app_host,
|
||||||
|
port=AppConfig.app_port,
|
||||||
|
root_path=AppConfig.app_root_path,
|
||||||
|
reload=AppConfig.app_reload
|
||||||
|
)
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 79 KiB |
@@ -4,8 +4,8 @@ from sqlalchemy.orm import sessionmaker
|
|||||||
from urllib.parse import quote_plus
|
from urllib.parse import quote_plus
|
||||||
from config.env import DataBaseConfig
|
from config.env import DataBaseConfig
|
||||||
|
|
||||||
SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.USERNAME}:{quote_plus(DataBaseConfig.PASSWORD)}@" \
|
SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.db_username}:{quote_plus(DataBaseConfig.db_password)}@" \
|
||||||
f"{DataBaseConfig.HOST}:{DataBaseConfig.PORT}/{DataBaseConfig.DB}"
|
f"{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}"
|
||||||
|
|
||||||
engine = create_engine(
|
engine = create_engine(
|
||||||
SQLALCHEMY_DATABASE_URL, echo=True
|
SQLALCHEMY_DATABASE_URL, echo=True
|
||||||
|
@@ -1,39 +1,57 @@
|
|||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
from pydantic_settings import BaseSettings
|
||||||
|
from functools import lru_cache
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
|
||||||
class JwtConfig:
|
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 = "b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55"
|
jwt_secret_key: str = 'b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55'
|
||||||
ALGORITHM = "HS256"
|
jwt_algorithm: str = 'HS256'
|
||||||
ACCESS_TOKEN_EXPIRE_MINUTES = 1440
|
jwt_expire_minutes: int = 1440
|
||||||
REDIS_TOKEN_EXPIRE_MINUTES = 30
|
jwt_redis_expire_minutes: int = 30
|
||||||
|
|
||||||
|
|
||||||
class DataBaseConfig:
|
class DataBaseSettings(BaseSettings):
|
||||||
"""
|
"""
|
||||||
数据库配置
|
数据库配置
|
||||||
"""
|
"""
|
||||||
HOST = "127.0.0.1"
|
db_host: str = '127.0.0.1'
|
||||||
PORT = 3306
|
db_port: int = 3306
|
||||||
USERNAME = 'root'
|
db_username: str = 'root'
|
||||||
PASSWORD = 'mysqlroot'
|
db_password: str = 'mysqlroot'
|
||||||
DB = 'ruoyi-fastapi'
|
db_database: str = 'ruoyi-fastapi'
|
||||||
|
|
||||||
|
|
||||||
class RedisConfig:
|
class RedisSettings(BaseSettings):
|
||||||
"""
|
"""
|
||||||
Redis配置
|
Redis配置
|
||||||
"""
|
"""
|
||||||
HOST = "127.0.0.1"
|
redis_host: str = '127.0.0.1'
|
||||||
PORT = 6379
|
redis_port: int = 6379
|
||||||
USERNAME = ''
|
redis_username: str = ''
|
||||||
PASSWORD = ''
|
redis_password: str = ''
|
||||||
DB = 2
|
redis_database: int = 2
|
||||||
|
|
||||||
|
|
||||||
class UploadConfig:
|
class UploadSettings:
|
||||||
"""
|
"""
|
||||||
上传配置
|
上传配置
|
||||||
"""
|
"""
|
||||||
@@ -80,3 +98,92 @@ class RedisInitKeyConfig:
|
|||||||
ACCOUNT_LOCK = {'key': 'account_lock', 'remark': '用户锁定'}
|
ACCOUNT_LOCK = {'key': 'account_lock', 'remark': '用户锁定'}
|
||||||
PASSWORD_ERROR_COUNT = {'key': 'password_error_count', 'remark': '密码错误次数'}
|
PASSWORD_ERROR_COUNT = {'key': 'password_error_count', 'remark': '密码错误次数'}
|
||||||
SMS_CODE = {'key': 'sms_code', '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()
|
||||||
|
@@ -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.dict_service import DictDataService
|
||||||
from module_admin.service.config_service import ConfigService
|
from module_admin.service.config_service import ConfigService
|
||||||
from config.env import RedisConfig
|
from config.env import RedisConfig
|
||||||
@@ -19,15 +20,26 @@ class RedisUtil:
|
|||||||
"""
|
"""
|
||||||
logger.info("开始连接redis...")
|
logger.info("开始连接redis...")
|
||||||
redis = await aioredis.from_url(
|
redis = await aioredis.from_url(
|
||||||
url=f"redis://{RedisConfig.HOST}",
|
url=f"redis://{RedisConfig.redis_host}",
|
||||||
port=RedisConfig.PORT,
|
port=RedisConfig.redis_port,
|
||||||
username=RedisConfig.USERNAME,
|
username=RedisConfig.redis_username,
|
||||||
password=RedisConfig.PASSWORD,
|
password=RedisConfig.redis_password,
|
||||||
db=RedisConfig.DB,
|
db=RedisConfig.redis_database,
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
decode_responses=True
|
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
|
return redis
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@@ -70,11 +70,11 @@ job_stores = {
|
|||||||
'sqlalchemy': SQLAlchemyJobStore(url=SQLALCHEMY_DATABASE_URL, engine=engine),
|
'sqlalchemy': SQLAlchemyJobStore(url=SQLALCHEMY_DATABASE_URL, engine=engine),
|
||||||
'redis': RedisJobStore(
|
'redis': RedisJobStore(
|
||||||
**dict(
|
**dict(
|
||||||
host=RedisConfig.HOST,
|
host=RedisConfig.redis_host,
|
||||||
port=RedisConfig.PORT,
|
port=RedisConfig.redis_port,
|
||||||
username=RedisConfig.USERNAME,
|
username=RedisConfig.redis_username,
|
||||||
password=RedisConfig.PASSWORD,
|
password=RedisConfig.redis_password,
|
||||||
db=RedisConfig.DB
|
db=RedisConfig.redis_database
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
28
ruoyi-fastapi-backend/exceptions/exception.py
Normal file
28
ruoyi-fastapi-backend/exceptions/exception.py
Normal file
@@ -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
|
27
ruoyi-fastapi-backend/exceptions/handle.py
Normal file
27
ruoyi-fastapi-backend/exceptions/handle.py
Normal file
@@ -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
|
||||||
|
)
|
19
ruoyi-fastapi-backend/middlewares/cors_middleware.py
Normal file
19
ruoyi-fastapi-backend/middlewares/cors_middleware.py
Normal file
@@ -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=["*"],
|
||||||
|
)
|
10
ruoyi-fastapi-backend/middlewares/handle.py
Normal file
10
ruoyi-fastapi-backend/middlewares/handle.py
Normal file
@@ -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)
|
@@ -1,7 +1,7 @@
|
|||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from module_admin.entity.vo.user_vo import CurrentUserModel
|
from module_admin.entity.vo.user_vo import CurrentUserModel
|
||||||
from module_admin.service.login_service import LoginService
|
from module_admin.service.login_service import LoginService
|
||||||
from utils.response_util import PermissionException
|
from exceptions.exception import PermissionException
|
||||||
|
|
||||||
|
|
||||||
class CheckUserInterfaceAuth:
|
class CheckUserInterfaceAuth:
|
||||||
|
@@ -15,6 +15,8 @@ captchaController = APIRouter()
|
|||||||
async def get_captcha_image(request: Request):
|
async def get_captcha_image(request: Request):
|
||||||
try:
|
try:
|
||||||
captcha_enabled = True if await request.app.state.redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.captchaEnabled") == 'true' else False
|
captcha_enabled = True if await request.app.state.redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.captchaEnabled") == 'true' else False
|
||||||
|
register_enabled = True if await request.app.state.redis.get(
|
||||||
|
f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.registerUser") == 'true' else False
|
||||||
session_id = str(uuid.uuid4())
|
session_id = str(uuid.uuid4())
|
||||||
captcha_result = CaptchaService.create_captcha_image_service()
|
captcha_result = CaptchaService.create_captcha_image_service()
|
||||||
image = captcha_result[0]
|
image = captcha_result[0]
|
||||||
@@ -22,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))
|
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}的会话获取图片验证码成功')
|
logger.info(f'编号为{session_id}的会话获取图片验证码成功')
|
||||||
return ResponseUtil.success(
|
return ResponseUtil.success(
|
||||||
model_content=CaptchaCode(captchaEnabled=captcha_enabled, img=image, uuid=session_id)
|
model_content=CaptchaCode(captchaEnabled=captcha_enabled, registerEnabled=register_enabled, img=image, uuid=session_id)
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
|
@@ -17,11 +17,8 @@ configController = APIRouter(prefix='/system/config', dependencies=[Depends(Logi
|
|||||||
@configController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:config:list'))])
|
@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)):
|
async def get_system_config_list(request: Request, config_page_query: ConfigPageQueryModel = Depends(ConfigPageQueryModel.as_query), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
config_query = ConfigQueryModel(**config_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
config_page_query_result = ConfigService.get_config_list_services(query_db, config_page_query, is_page=True)
|
||||||
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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=config_page_query_result)
|
return ResponseUtil.success(model_content=config_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -125,9 +122,8 @@ async def query_system_config(request: Request, config_key: str):
|
|||||||
@log_decorator(title='参数管理', business_type=5)
|
@log_decorator(title='参数管理', business_type=5)
|
||||||
async def export_system_config_list(request: Request, config_page_query: ConfigPageQueryModel = Depends(ConfigPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
async def export_system_config_list(request: Request, config_page_query: ConfigPageQueryModel = Depends(ConfigPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
config_query = ConfigQueryModel(**config_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
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)
|
config_export_result = ConfigService.export_config_list_services(config_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(config_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(config_export_result))
|
||||||
|
@@ -5,7 +5,7 @@ from module_admin.service.login_service import LoginService, CurrentUserModel
|
|||||||
from module_admin.service.dict_service import *
|
from module_admin.service.dict_service import *
|
||||||
from utils.response_util import *
|
from utils.response_util import *
|
||||||
from utils.log_util import *
|
from utils.log_util import *
|
||||||
from utils.page_util import *
|
from utils.page_util import PageResponseModel
|
||||||
from utils.common_util import bytes2file_response
|
from utils.common_util import bytes2file_response
|
||||||
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
|
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
|
||||||
from module_admin.annotation.log_annotation import log_decorator
|
from module_admin.annotation.log_annotation import log_decorator
|
||||||
@@ -17,11 +17,8 @@ dictController = APIRouter(prefix='/system/dict', dependencies=[Depends(LoginSer
|
|||||||
@dictController.get("/type/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))])
|
@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)):
|
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:
|
try:
|
||||||
dict_type_query = DictTypeQueryModel(**dict_type_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
dict_type_page_query_result = DictTypeService.get_dict_type_list_services(query_db, dict_type_page_query, is_page=True)
|
||||||
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('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=dict_type_page_query_result)
|
return ResponseUtil.success(model_content=dict_type_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -101,7 +98,7 @@ async def delete_system_dict_type(request: Request, dict_ids: str, query_db: Ses
|
|||||||
@dictController.get("/type/optionselect", response_model=List[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)):
|
async def query_system_dict_type_options(request: Request, query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
dict_type_query_result = DictTypeService.get_dict_type_list_services(query_db, DictTypeQueryModel(**dict()))
|
dict_type_query_result = DictTypeService.get_dict_type_list_services(query_db, DictTypePageQueryModel(**dict()), is_page=False)
|
||||||
logger.info(f'获取成功')
|
logger.info(f'获取成功')
|
||||||
return ResponseUtil.success(data=dict_type_query_result)
|
return ResponseUtil.success(data=dict_type_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -124,9 +121,8 @@ async def query_detail_system_dict_type(request: Request, dict_id: int, query_db
|
|||||||
@log_decorator(title='字典管理', business_type=5)
|
@log_decorator(title='字典管理', business_type=5)
|
||||||
async def export_system_dict_type_list(request: Request, dict_type_page_query: DictTypePageQueryModel = Depends(DictTypePageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
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:
|
try:
|
||||||
dict_type_query = DictTypeQueryModel(**dict_type_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
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)
|
dict_type_export_result = DictTypeService.export_dict_type_list_services(dict_type_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(dict_type_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(dict_type_export_result))
|
||||||
@@ -150,11 +146,8 @@ async def query_system_dict_type_data(request: Request, dict_type: str, query_db
|
|||||||
@dictController.get("/data/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))])
|
@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)):
|
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:
|
try:
|
||||||
dict_data_query = DictDataModel(**dict_data_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
dict_data_page_query_result = DictDataService.get_dict_data_list_services(query_db, dict_data_page_query, is_page=True)
|
||||||
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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=dict_data_page_query_result)
|
return ResponseUtil.success(model_content=dict_data_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -230,9 +223,8 @@ async def query_detail_system_dict_data(request: Request, dict_code: int, query_
|
|||||||
@log_decorator(title='字典管理', business_type=5)
|
@log_decorator(title='字典管理', business_type=5)
|
||||||
async def export_system_dict_data_list(request: Request, dict_data_page_query: DictDataPageQueryModel = Depends(DictDataPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
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:
|
try:
|
||||||
dict_data_query = DictDataModel(**dict_data_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
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)
|
dict_data_export_result = DictDataService.export_dict_data_list_services(dict_data_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(dict_data_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(dict_data_export_result))
|
||||||
|
@@ -18,11 +18,8 @@ jobController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.
|
|||||||
@jobController.get("/job/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))])
|
@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)):
|
async def get_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
job_query = JobModel(**job_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
notice_page_query_result = JobService.get_job_list_services(query_db, job_page_query, is_page=True)
|
||||||
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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=notice_page_query_result)
|
return ResponseUtil.success(model_content=notice_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -133,9 +130,8 @@ async def query_detail_system_job(request: Request, job_id: int, query_db: Sessi
|
|||||||
@log_decorator(title='定时任务管理', business_type=5)
|
@log_decorator(title='定时任务管理', business_type=5)
|
||||||
async def export_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
async def export_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
job_query = JobModel(**job_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
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)
|
job_export_result = await JobService.export_job_list_services(request, job_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(job_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(job_export_result))
|
||||||
@@ -147,13 +143,10 @@ async def export_system_job_list(request: Request, job_page_query: JobPageQueryM
|
|||||||
@jobController.get("/jobLog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))])
|
@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)):
|
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:
|
try:
|
||||||
job_log_query = JobLogQueryModel(**job_log_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
job_log_page_query_result = JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=True)
|
||||||
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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=notice_page_query_result)
|
return ResponseUtil.success(model_content=job_log_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
return ResponseUtil.error(msg=str(e))
|
return ResponseUtil.error(msg=str(e))
|
||||||
@@ -196,10 +189,9 @@ async def clear_system_job_log(request: Request, query_db: Session = Depends(get
|
|||||||
@log_decorator(title='定时任务日志管理', business_type=5)
|
@log_decorator(title='定时任务日志管理', business_type=5)
|
||||||
async def export_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
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:
|
try:
|
||||||
job_log_query = JobLogQueryModel(**job_log_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
job_log_query_result = JobLogService.get_job_log_list_services(query_db, job_log_query)
|
job_log_query_result = JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=False)
|
||||||
job_log_export_result = JobLogService.export_job_log_list_services(query_db, job_log_query_result)
|
job_log_export_result = await JobLogService.export_job_log_list_services(request, job_log_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@@ -17,11 +17,8 @@ logController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.
|
|||||||
@logController.get("/operlog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:list'))])
|
@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)):
|
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:
|
try:
|
||||||
operation_log_query = OperLogQueryModel(**operation_log_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
operation_log_page_query_result = OperationLogService.get_operation_log_list_services(query_db, operation_log_page_query, is_page=True)
|
||||||
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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=operation_log_page_query_result)
|
return ResponseUtil.success(model_content=operation_log_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -66,9 +63,8 @@ async def delete_system_operation_log(request: Request, oper_ids: str, query_db:
|
|||||||
@log_decorator(title='操作日志管理', business_type=5)
|
@log_decorator(title='操作日志管理', business_type=5)
|
||||||
async def export_system_operation_log_list(request: Request, operation_log_page_query: OperLogPageQueryModel = Depends(OperLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
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:
|
try:
|
||||||
operation_log_query = OperLogQueryModel(**operation_log_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
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)
|
operation_log_export_result = await OperationLogService.export_operation_log_list_services(request, operation_log_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(operation_log_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(operation_log_export_result))
|
||||||
@@ -80,11 +76,8 @@ async def export_system_operation_log_list(request: Request, operation_log_page_
|
|||||||
@logController.get("/logininfor/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:list'))])
|
@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)):
|
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:
|
try:
|
||||||
login_log_query = LoginLogQueryModel(**login_log_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
login_log_page_query_result = LoginLogService.get_login_log_list_services(query_db, login_log_page_query, is_page=True)
|
||||||
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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=login_log_page_query_result)
|
return ResponseUtil.success(model_content=login_log_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -146,9 +139,8 @@ async def clear_system_login_log(request: Request, user_name: str, query_db: Ses
|
|||||||
@log_decorator(title='登录日志管理', business_type=5)
|
@log_decorator(title='登录日志管理', business_type=5)
|
||||||
async def export_system_login_log_list(request: Request, login_log_page_query: LoginLogPageQueryModel = Depends(LoginLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
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:
|
try:
|
||||||
login_log_query = LoginLogQueryModel(**login_log_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
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)
|
login_log_export_result = LoginLogService.export_login_log_list_services(login_log_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(login_log_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(login_log_export_result))
|
||||||
|
@@ -2,10 +2,10 @@ from fastapi import APIRouter
|
|||||||
from module_admin.service.login_service import *
|
from module_admin.service.login_service import *
|
||||||
from module_admin.entity.vo.login_vo import *
|
from module_admin.entity.vo.login_vo import *
|
||||||
from module_admin.dao.login_dao import *
|
from module_admin.dao.login_dao import *
|
||||||
from config.env import JwtConfig, RedisInitKeyConfig
|
|
||||||
from utils.response_util import *
|
|
||||||
from utils.log_util import *
|
|
||||||
from module_admin.annotation.log_annotation import log_decorator
|
from module_admin.annotation.log_annotation import log_decorator
|
||||||
|
from config.env import JwtConfig, RedisInitKeyConfig
|
||||||
|
from utils.response_util import ResponseUtil
|
||||||
|
from utils.log_util import *
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = D
|
|||||||
except LoginException as e:
|
except LoginException as e:
|
||||||
return ResponseUtil.failure(msg=e.message)
|
return ResponseUtil.failure(msg=e.message)
|
||||||
try:
|
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())
|
session_id = str(uuid.uuid4())
|
||||||
access_token = LoginService.create_access_token(
|
access_token = LoginService.create_access_token(
|
||||||
data={
|
data={
|
||||||
@@ -42,10 +42,11 @@ async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = D
|
|||||||
expires_delta=access_token_expires
|
expires_delta=access_token_expires
|
||||||
)
|
)
|
||||||
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", access_token,
|
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,
|
# 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('登录成功')
|
logger.info('登录成功')
|
||||||
# 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug
|
# 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug
|
||||||
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
|
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
|
||||||
@@ -82,42 +83,57 @@ async def get_login_user_routers(request: Request, current_user: CurrentUserMode
|
|||||||
return ResponseUtil.error(msg=str(e))
|
return ResponseUtil.error(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
@loginController.post("/getSmsCode", response_model=SmsCode)
|
@loginController.post("/register", response_model=CrudResponseModel)
|
||||||
async def get_sms_code(request: Request, user: ResetUserModel, query_db: Session = Depends(get_db)):
|
async def register_user(request: Request, user_register: UserRegister, query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
sms_result = await get_sms_code_services(request, query_db, user)
|
user_register_result = await LoginService.register_user_services(request, query_db, user_register)
|
||||||
if sms_result.is_success:
|
if user_register_result.is_success:
|
||||||
logger.info('获取成功')
|
logger.info(user_register_result.message)
|
||||||
return response_200(data=sms_result, message='获取成功')
|
return ResponseUtil.success(data=user_register_result, msg=user_register_result.message)
|
||||||
else:
|
else:
|
||||||
logger.warning(sms_result.message)
|
logger.warning(user_register_result.message)
|
||||||
return response_400(data='', message=sms_result.message)
|
return ResponseUtil.failure(msg=user_register_result.message)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
return response_500(data="", message=str(e))
|
return ResponseUtil.error(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
@loginController.post("/forgetPwd", response_model=CrudResponseModel)
|
# @loginController.post("/getSmsCode", response_model=SmsCode)
|
||||||
async def forget_user_pwd(request: Request, forget_user: ResetUserModel, query_db: Session = Depends(get_db)):
|
# async def get_sms_code(request: Request, user: ResetUserModel, query_db: Session = Depends(get_db)):
|
||||||
try:
|
# try:
|
||||||
forget_user_result = await forget_user_services(request, query_db, forget_user)
|
# sms_result = await LoginService.get_sms_code_services(request, query_db, user)
|
||||||
if forget_user_result.is_success:
|
# if sms_result.is_success:
|
||||||
logger.info(forget_user_result.message)
|
# logger.info('获取成功')
|
||||||
return response_200(data=forget_user_result, message=forget_user_result.message)
|
# return ResponseUtil.success(data=sms_result)
|
||||||
else:
|
# else:
|
||||||
logger.warning(forget_user_result.message)
|
# logger.warning(sms_result.message)
|
||||||
return response_400(data="", message=forget_user_result.message)
|
# return ResponseUtil.failure(msg=sms_result.message)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logger.exception(e)
|
# logger.exception(e)
|
||||||
return response_500(data="", message=str(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")
|
@loginController.post("/logout")
|
||||||
async def logout(request: Request, token: Optional[str] = Depends(oauth2_scheme)):
|
async def logout(request: Request, token: Optional[str] = Depends(oauth2_scheme)):
|
||||||
try:
|
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")
|
session_id: str = payload.get("session_id")
|
||||||
await logout_services(request, session_id)
|
await LoginService.logout_services(request, session_id)
|
||||||
logger.info('退出成功')
|
logger.info('退出成功')
|
||||||
return ResponseUtil.success(msg="退出成功")
|
return ResponseUtil.success(msg="退出成功")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@@ -16,11 +16,8 @@ noticeController = APIRouter(prefix='/system/notice', dependencies=[Depends(Logi
|
|||||||
@noticeController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:list'))])
|
@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)):
|
async def get_system_notice_list(request: Request, notice_page_query: NoticePageQueryModel = Depends(NoticePageQueryModel.as_query), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
notice_query = NoticeQueryModel(**notice_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
notice_page_query_result = NoticeService.get_notice_list_services(query_db, notice_page_query, is_page=True)
|
||||||
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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=notice_page_query_result)
|
return ResponseUtil.success(model_content=notice_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@@ -18,11 +18,8 @@ postController = APIRouter(prefix='/system/post', dependencies=[Depends(LoginSer
|
|||||||
@postController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:post:list'))])
|
@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)):
|
async def get_system_post_list(request: Request, post_page_query: PostPageQueryModel = Depends(PostPageQueryModel.as_query), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
post_query = PostModel(**post_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
post_page_query_result = PostService.get_post_list_services(query_db, post_page_query, is_page=True)
|
||||||
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('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=post_page_query_result)
|
return ResponseUtil.success(model_content=post_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -98,9 +95,8 @@ async def query_detail_system_post(request: Request, post_id: int, query_db: Ses
|
|||||||
@log_decorator(title='岗位管理', business_type=5)
|
@log_decorator(title='岗位管理', business_type=5)
|
||||||
async def export_system_post_list(request: Request, post_page_query: PostPageQueryModel = Depends(PostPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
async def export_system_post_list(request: Request, post_page_query: PostPageQueryModel = Depends(PostPageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
post_query = PostModel(**post_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
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)
|
post_export_result = PostService.export_post_list_services(post_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(post_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(post_export_result))
|
||||||
|
@@ -7,7 +7,7 @@ from module_admin.service.dept_service import DeptService, DeptModel
|
|||||||
from module_admin.service.user_service import UserService, UserRoleQueryModel, UserRolePageQueryModel, CrudUserRoleModel
|
from module_admin.service.user_service import UserService, UserRoleQueryModel, UserRolePageQueryModel, CrudUserRoleModel
|
||||||
from utils.response_util import *
|
from utils.response_util import *
|
||||||
from utils.log_util import *
|
from utils.log_util import *
|
||||||
from utils.page_util import *
|
from utils.page_util import PageResponseModel
|
||||||
from utils.common_util import bytes2file_response
|
from utils.common_util import bytes2file_response
|
||||||
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
|
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
|
||||||
from module_admin.aspect.data_scope import GetDataScope
|
from module_admin.aspect.data_scope import GetDataScope
|
||||||
@@ -33,10 +33,7 @@ async def get_system_role_dept_tree(request: Request, role_id: int, query_db: Se
|
|||||||
@roleController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))])
|
@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)):
|
async def get_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_query), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
role_query = RoleQueryModel(**role_page_query.model_dump(by_alias=True))
|
role_page_query_result = RoleService.get_role_list_services(query_db, role_page_query, is_page=True)
|
||||||
role_query_result = RoleService.get_role_list_services(query_db, role_query)
|
|
||||||
# 分页操作
|
|
||||||
role_page_query_result = get_page_obj(role_query_result, role_page_query.page_num, role_page_query.page_size)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=role_page_query_result)
|
return ResponseUtil.success(model_content=role_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -134,9 +131,8 @@ async def query_detail_system_role(request: Request, role_id: int, query_db: Ses
|
|||||||
@log_decorator(title='角色管理', business_type=5)
|
@log_decorator(title='角色管理', business_type=5)
|
||||||
async def export_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
async def export_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_form), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
role_query = RoleQueryModel(**role_page_query.model_dump(by_alias=True))
|
|
||||||
# 获取全量数据
|
# 获取全量数据
|
||||||
role_query_result = RoleService.get_role_list_services(query_db, role_query)
|
role_query_result = RoleService.get_role_list_services(query_db, role_page_query, is_page=False)
|
||||||
role_export_result = RoleService.export_role_list_services(role_query_result)
|
role_export_result = RoleService.export_role_list_services(role_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(role_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(role_export_result))
|
||||||
@@ -167,10 +163,7 @@ async def reset_system_role_status(request: Request, edit_role: AddRoleModel, qu
|
|||||||
@roleController.get("/authUser/allocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))])
|
@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)):
|
async def get_system_allocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
role_user_query = UserRoleQueryModel(**user_role.model_dump(by_alias=True))
|
role_user_allocated_page_query_result = RoleService.get_role_user_allocated_list_services(query_db, user_role, is_page=True)
|
||||||
role_user_allocated_query_result = RoleService.get_role_user_allocated_list_services(query_db, role_user_query)
|
|
||||||
# 分页操作
|
|
||||||
role_user_allocated_page_query_result = get_page_obj(role_user_allocated_query_result, user_role.page_num, user_role.page_size)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=role_user_allocated_page_query_result)
|
return ResponseUtil.success(model_content=role_user_allocated_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -181,10 +174,7 @@ async def get_system_allocated_user_list(request: Request, user_role: UserRolePa
|
|||||||
@roleController.get("/authUser/unallocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))])
|
@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)):
|
async def get_system_unallocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
role_user_query = UserRoleQueryModel(**user_role.model_dump(by_alias=True))
|
role_user_unallocated_page_query_result = RoleService.get_role_user_unallocated_list_services(query_db, user_role, is_page=True)
|
||||||
role_user_unallocated_query_result = RoleService.get_role_user_unallocated_list_services(query_db, role_user_query)
|
|
||||||
# 分页操作
|
|
||||||
role_user_unallocated_page_query_result = get_page_obj(role_user_unallocated_query_result, user_role.page_num, user_role.page_size)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=role_user_unallocated_page_query_result)
|
return ResponseUtil.success(model_content=role_user_unallocated_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@@ -5,7 +5,7 @@ from config.env import UploadConfig
|
|||||||
from module_admin.service.login_service import LoginService
|
from module_admin.service.login_service import LoginService
|
||||||
from module_admin.service.user_service import *
|
from module_admin.service.user_service import *
|
||||||
from module_admin.service.dept_service import DeptService
|
from module_admin.service.dept_service import DeptService
|
||||||
from utils.page_util import *
|
from utils.page_util import PageResponseModel
|
||||||
from utils.response_util import *
|
from utils.response_util import *
|
||||||
from utils.log_util import *
|
from utils.log_util import *
|
||||||
from utils.common_util import bytes2file_response
|
from utils.common_util import bytes2file_response
|
||||||
@@ -32,11 +32,8 @@ async def get_system_dept_tree(request: Request, query_db: Session = Depends(get
|
|||||||
@userController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))])
|
@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'))):
|
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:
|
try:
|
||||||
user_query = UserQueryModel(**user_page_query.model_dump(by_alias=True))
|
# 获取分页数据
|
||||||
# 获取全量数据
|
user_page_query_result = UserService.get_user_list_services(query_db, user_page_query, data_scope_sql, is_page=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)
|
|
||||||
logger.info('获取成功')
|
logger.info('获取成功')
|
||||||
return ResponseUtil.success(model_content=user_page_query_result)
|
return ResponseUtil.success(model_content=user_page_query_result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -272,9 +269,8 @@ async def export_system_user_template(request: Request, query_db: Session = Depe
|
|||||||
@log_decorator(title='用户管理', business_type=5)
|
@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'))):
|
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:
|
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)
|
user_export_result = UserService.export_user_list_services(user_query_result)
|
||||||
logger.info('导出成功')
|
logger.info('导出成功')
|
||||||
return ResponseUtil.streaming(data=bytes2file_response(user_export_result))
|
return ResponseUtil.streaming(data=bytes2file_response(user_export_result))
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from module_admin.entity.do.config_do import SysConfig
|
from module_admin.entity.do.config_do import SysConfig
|
||||||
from module_admin.entity.vo.config_vo import *
|
from module_admin.entity.vo.config_vo import *
|
||||||
|
from utils.page_util import PageUtil
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
||||||
@@ -39,14 +40,15 @@ class ConfigDao:
|
|||||||
return config_info
|
return config_info
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 参数配置列表信息对象
|
: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,
|
.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_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.config_type == query_object.config_type if query_object.config_type else True,
|
||||||
@@ -55,7 +57,8 @@ class ConfigDao:
|
|||||||
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
|
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
|
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 config_list
|
return config_list
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@ from sqlalchemy.orm import Session
|
|||||||
from module_admin.entity.do.dict_do import SysDictType, SysDictData
|
from module_admin.entity.do.dict_do import SysDictType, SysDictData
|
||||||
from module_admin.entity.vo.dict_vo import *
|
from module_admin.entity.vo.dict_vo import *
|
||||||
from utils.time_format_util import list_format_datetime
|
from utils.time_format_util import list_format_datetime
|
||||||
|
from utils.page_util import PageUtil
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
||||||
@@ -52,14 +53,15 @@ class DictTypeDao:
|
|||||||
return list_format_datetime(dict_type_info)
|
return list_format_datetime(dict_type_info)
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 字典类型列表信息对象
|
: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,
|
.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.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.status == query_object.status if query_object.status else True,
|
||||||
@@ -68,7 +70,8 @@ class DictTypeDao:
|
|||||||
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
|
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
|
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 dict_type_list
|
return dict_type_list
|
||||||
|
|
||||||
@@ -147,20 +150,22 @@ class DictDataDao:
|
|||||||
return dict_data_info
|
return dict_data_info
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 字典数据列表信息对象
|
: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,
|
.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.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
|
SysDictData.status == query_object.status if query_object.status else True
|
||||||
) \
|
) \
|
||||||
.order_by(SysDictData.dict_sort) \
|
.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 dict_data_list
|
return dict_data_list
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from module_admin.entity.do.job_do import SysJob
|
from module_admin.entity.do.job_do import SysJob
|
||||||
from module_admin.entity.vo.job_vo import *
|
from module_admin.entity.vo.job_vo import *
|
||||||
|
from utils.page_util import PageUtil
|
||||||
|
|
||||||
|
|
||||||
class JobDao:
|
class JobDao:
|
||||||
@@ -40,19 +41,21 @@ class JobDao:
|
|||||||
return job_info
|
return job_info
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 定时任务列表信息对象
|
: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,
|
.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.job_group == query_object.job_group if query_object.job_group else True,
|
||||||
SysJob.status == query_object.status if query_object.status 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 job_list
|
return job_list
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from module_admin.entity.do.job_do import SysJobLog
|
from module_admin.entity.do.job_do import SysJobLog
|
||||||
from module_admin.entity.vo.job_vo import *
|
from module_admin.entity.vo.job_vo import *
|
||||||
|
from utils.page_util import PageUtil
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
||||||
@@ -10,14 +11,15 @@ class JobLogDao:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 定时任务日志列表信息对象
|
: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,
|
.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.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.status == query_object.status if query_object.status else True,
|
||||||
@@ -26,7 +28,8 @@ class JobLogDao:
|
|||||||
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
|
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
|
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 job_log_list
|
return job_log_list
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from module_admin.entity.do.log_do import SysOperLog, SysLogininfor
|
from module_admin.entity.do.log_do import SysOperLog, SysLogininfor
|
||||||
from module_admin.entity.vo.log_vo import *
|
from module_admin.entity.vo.log_vo import *
|
||||||
from utils.time_format_util import object_format_datetime, list_format_datetime
|
from utils.page_util import PageUtil
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
||||||
@@ -10,14 +10,15 @@ class OperationLogDao:
|
|||||||
操作日志管理模块数据库操作层
|
操作日志管理模块数据库操作层
|
||||||
"""
|
"""
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 操作日志列表信息对象
|
: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,
|
.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.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.business_type == query_object.business_type if query_object.business_type else True,
|
||||||
@@ -27,7 +28,8 @@ class OperationLogDao:
|
|||||||
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
|
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
|
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 operation_log_list
|
return operation_log_list
|
||||||
|
|
||||||
@@ -74,14 +76,15 @@ class LoginLogDao:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 登录日志列表信息对象
|
: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,
|
.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.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.status == query_object.status if query_object.status else True,
|
||||||
@@ -90,7 +93,8 @@ class LoginLogDao:
|
|||||||
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
|
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
|
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 login_log_list
|
return login_log_list
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from module_admin.entity.do.notice_do import SysNotice
|
from module_admin.entity.do.notice_do import SysNotice
|
||||||
from module_admin.entity.vo.notice_vo import *
|
from module_admin.entity.vo.notice_vo import *
|
||||||
|
from utils.page_util import PageUtil
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
||||||
@@ -40,14 +41,15 @@ class NoticeDao:
|
|||||||
return notice_info
|
return notice_info
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 通知公告列表信息对象
|
: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,
|
.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.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.notice_type == query_object.notice_type if query_object.notice_type else True,
|
||||||
@@ -56,7 +58,8 @@ class NoticeDao:
|
|||||||
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
|
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
|
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 notice_list
|
return notice_list
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from module_admin.entity.do.post_do import SysPost
|
from module_admin.entity.do.post_do import SysPost
|
||||||
from module_admin.entity.vo.post_vo import *
|
from module_admin.entity.vo.post_vo import *
|
||||||
|
from utils.page_util import PageUtil
|
||||||
|
|
||||||
|
|
||||||
class PostDao:
|
class PostDao:
|
||||||
@@ -54,20 +55,22 @@ class PostDao:
|
|||||||
return post_info
|
return post_info
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 岗位列表信息对象
|
: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,
|
.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.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
|
SysPost.status == query_object.status if query_object.status else True
|
||||||
) \
|
) \
|
||||||
.order_by(SysPost.post_sort) \
|
.order_by(SysPost.post_sort) \
|
||||||
.distinct().all()
|
.distinct()
|
||||||
|
post_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
|
||||||
|
|
||||||
return post_list
|
return post_list
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@ from sqlalchemy.orm import Session
|
|||||||
from module_admin.entity.do.role_do import SysRole, SysRoleMenu, SysRoleDept
|
from module_admin.entity.do.role_do import SysRole, SysRoleMenu, SysRoleDept
|
||||||
from module_admin.entity.do.dept_do import SysDept
|
from module_admin.entity.do.dept_do import SysDept
|
||||||
from module_admin.entity.vo.role_vo import *
|
from module_admin.entity.vo.role_vo import *
|
||||||
|
from utils.page_util import PageUtil
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
||||||
@@ -85,14 +86,15 @@ class RoleDao:
|
|||||||
return role_info
|
return role_info
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 角色列表信息对象
|
:return: 角色列表信息对象
|
||||||
"""
|
"""
|
||||||
role_list = db.query(SysRole) \
|
query = db.query(SysRole) \
|
||||||
.filter(SysRole.del_flag == 0,
|
.filter(SysRole.del_flag == 0,
|
||||||
SysRole.role_name.like(f'%{query_object.role_name}%') if query_object.role_name else True,
|
SysRole.role_name.like(f'%{query_object.role_name}%') if query_object.role_name else True,
|
||||||
SysRole.role_key.like(f'%{query_object.role_key}%') if query_object.role_key else True,
|
SysRole.role_key.like(f'%{query_object.role_key}%') if query_object.role_key else True,
|
||||||
@@ -103,7 +105,8 @@ class RoleDao:
|
|||||||
if query_object.begin_time and query_object.end_time else True
|
if query_object.begin_time and query_object.end_time else True
|
||||||
) \
|
) \
|
||||||
.order_by(SysRole.role_sort) \
|
.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
|
return role_list
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@ from module_admin.entity.do.dept_do import SysDept
|
|||||||
from module_admin.entity.do.post_do import SysPost
|
from module_admin.entity.do.post_do import SysPost
|
||||||
from module_admin.entity.do.menu_do import SysMenu
|
from module_admin.entity.do.menu_do import SysMenu
|
||||||
from module_admin.entity.vo.user_vo import *
|
from module_admin.entity.vo.user_vo import *
|
||||||
from utils.time_format_util import list_format_datetime
|
from utils.page_util import PageUtil
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
||||||
@@ -137,15 +137,16 @@ class UserDao:
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
@classmethod
|
@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 db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
:param data_scope_sql: 数据权限对应的查询sql语句
|
:param data_scope_sql: 数据权限对应的查询sql语句
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 用户列表信息对象
|
:return: 用户列表信息对象
|
||||||
"""
|
"""
|
||||||
user_list = db.query(SysUser, SysDept) \
|
query = db.query(SysUser, SysDept) \
|
||||||
.filter(SysUser.del_flag == 0,
|
.filter(SysUser.del_flag == 0,
|
||||||
or_(SysUser.dept_id == query_object.dept_id, SysUser.dept_id.in_(
|
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))
|
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)
|
eval(data_scope_sql)
|
||||||
) \
|
) \
|
||||||
.outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \
|
.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
|
return user_list
|
||||||
|
|
||||||
@@ -227,35 +229,15 @@ class UserDao:
|
|||||||
return allocated_role_list
|
return allocated_role_list
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_user_role_unallocated_list_by_user_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: 用户角色查询对象
|
|
||||||
: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):
|
|
||||||
"""
|
"""
|
||||||
根据角色id获取已分配的用户列表信息
|
根据角色id获取已分配的用户列表信息
|
||||||
:param db: orm对象
|
:param db: orm对象
|
||||||
:param query_object: 用户角色查询对象
|
:param query_object: 用户角色查询对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 角色已分配的用户列表信息
|
:return: 角色已分配的用户列表信息
|
||||||
"""
|
"""
|
||||||
allocated_user_list = db.query(SysUser) \
|
query = db.query(SysUser) \
|
||||||
.filter(
|
.filter(
|
||||||
SysUser.del_flag == 0,
|
SysUser.del_flag == 0,
|
||||||
SysUser.user_id != 1,
|
SysUser.user_id != 1,
|
||||||
@@ -264,19 +246,21 @@ class UserDao:
|
|||||||
SysUser.user_id.in_(
|
SysUser.user_id.in_(
|
||||||
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
|
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
|
||||||
)
|
)
|
||||||
).distinct().all()
|
).distinct()
|
||||||
|
allocated_user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
|
||||||
|
|
||||||
return allocated_user_list
|
return allocated_user_list
|
||||||
|
|
||||||
@classmethod
|
@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获取未分配的用户列表信息
|
根据角色id获取未分配的用户列表信息
|
||||||
:param db: orm对象
|
:param db: orm对象
|
||||||
:param query_object: 用户角色查询对象
|
:param query_object: 用户角色查询对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 角色未分配的用户列表信息
|
:return: 角色未分配的用户列表信息
|
||||||
"""
|
"""
|
||||||
unallocated_user_list = db.query(SysUser) \
|
query = db.query(SysUser) \
|
||||||
.filter(
|
.filter(
|
||||||
SysUser.del_flag == 0,
|
SysUser.del_flag == 0,
|
||||||
SysUser.user_id != 1,
|
SysUser.user_id != 1,
|
||||||
@@ -285,7 +269,8 @@ class UserDao:
|
|||||||
~SysUser.user_id.in_(
|
~SysUser.user_id.in_(
|
||||||
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
|
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
|
||||||
)
|
)
|
||||||
).distinct().all()
|
).distinct()
|
||||||
|
unallocated_user_list = PageUtil.paginate(query, query_object.page_num, query_object.page_size, is_page)
|
||||||
|
|
||||||
return unallocated_user_list
|
return unallocated_user_list
|
||||||
|
|
||||||
|
@@ -37,8 +37,8 @@ class ConfigPageQueryModel(ConfigQueryModel):
|
|||||||
"""
|
"""
|
||||||
参数配置管理分页查询模型
|
参数配置管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeleteConfigModel(BaseModel):
|
class DeleteConfigModel(BaseModel):
|
||||||
|
@@ -58,8 +58,8 @@ class DictTypePageQueryModel(DictTypeQueryModel):
|
|||||||
"""
|
"""
|
||||||
字典类型管理分页查询模型
|
字典类型管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeleteDictTypeModel(BaseModel):
|
class DeleteDictTypeModel(BaseModel):
|
||||||
@@ -71,7 +71,7 @@ class DeleteDictTypeModel(BaseModel):
|
|||||||
dict_ids: str
|
dict_ids: str
|
||||||
|
|
||||||
|
|
||||||
class DictDataQueryModel(DictTypeModel):
|
class DictDataQueryModel(DictDataModel):
|
||||||
"""
|
"""
|
||||||
字典数据管理不分页查询模型
|
字典数据管理不分页查询模型
|
||||||
"""
|
"""
|
||||||
@@ -85,8 +85,8 @@ class DictDataPageQueryModel(DictDataQueryModel):
|
|||||||
"""
|
"""
|
||||||
字典数据管理分页查询模型
|
字典数据管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeleteDictDataModel(BaseModel):
|
class DeleteDictDataModel(BaseModel):
|
||||||
|
@@ -63,8 +63,8 @@ class JobPageQueryModel(JobQueryModel):
|
|||||||
"""
|
"""
|
||||||
定时任务管理分页查询模型
|
定时任务管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class EditJobModel(JobModel):
|
class EditJobModel(JobModel):
|
||||||
@@ -97,8 +97,8 @@ class JobLogPageQueryModel(JobLogQueryModel):
|
|||||||
"""
|
"""
|
||||||
定时任务日志管理分页查询模型
|
定时任务日志管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeleteJobLogModel(BaseModel):
|
class DeleteJobLogModel(BaseModel):
|
||||||
|
@@ -61,8 +61,8 @@ class OperLogPageQueryModel(OperLogQueryModel):
|
|||||||
"""
|
"""
|
||||||
操作日志管理分页查询模型
|
操作日志管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeleteOperLogModel(BaseModel):
|
class DeleteOperLogModel(BaseModel):
|
||||||
@@ -89,8 +89,8 @@ class LoginLogPageQueryModel(LoginLogQueryModel):
|
|||||||
"""
|
"""
|
||||||
登录日志管理分页查询模型
|
登录日志管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeleteLoginLogModel(BaseModel):
|
class DeleteLoginLogModel(BaseModel):
|
||||||
|
@@ -14,6 +14,16 @@ class UserLogin(BaseModel):
|
|||||||
captcha_enabled: Optional[bool] = None
|
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):
|
class Token(BaseModel):
|
||||||
access_token: str
|
access_token: str
|
||||||
token_type: str
|
token_type: str
|
||||||
@@ -23,6 +33,7 @@ class CaptchaCode(BaseModel):
|
|||||||
model_config = ConfigDict(alias_generator=to_camel)
|
model_config = ConfigDict(alias_generator=to_camel)
|
||||||
|
|
||||||
captcha_enabled: bool
|
captcha_enabled: bool
|
||||||
|
register_enabled: bool
|
||||||
img: str
|
img: str
|
||||||
uuid: str
|
uuid: str
|
||||||
|
|
||||||
|
@@ -37,8 +37,8 @@ class NoticePageQueryModel(NoticeQueryModel):
|
|||||||
"""
|
"""
|
||||||
通知公告管理分页查询模型
|
通知公告管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeleteNoticeModel(BaseModel):
|
class DeleteNoticeModel(BaseModel):
|
||||||
|
@@ -37,8 +37,8 @@ class PostPageQueryModel(PostQueryModel):
|
|||||||
"""
|
"""
|
||||||
岗位管理分页查询模型
|
岗位管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class DeletePostModel(BaseModel):
|
class DeletePostModel(BaseModel):
|
||||||
|
@@ -83,8 +83,8 @@ class RolePageQueryModel(RoleQueryModel):
|
|||||||
"""
|
"""
|
||||||
角色管理分页查询模型
|
角色管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class RoleMenuQueryModel(BaseModel):
|
class RoleMenuQueryModel(BaseModel):
|
||||||
|
@@ -124,8 +124,8 @@ class UserPageQueryModel(UserQueryModel):
|
|||||||
"""
|
"""
|
||||||
用户管理分页查询模型
|
用户管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class AddUserModel(UserModel):
|
class AddUserModel(UserModel):
|
||||||
@@ -176,8 +176,8 @@ class UserRolePageQueryModel(UserRoleQueryModel):
|
|||||||
"""
|
"""
|
||||||
用户角色关联管理分页查询模型
|
用户角色关联管理分页查询模型
|
||||||
"""
|
"""
|
||||||
page_num: int
|
page_num: int = 1
|
||||||
page_size: int
|
page_size: int = 10
|
||||||
|
|
||||||
|
|
||||||
class SelectedRoleModel(RoleModel):
|
class SelectedRoleModel(RoleModel):
|
||||||
|
@@ -11,16 +11,17 @@ class ConfigService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取参数配置列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 参数配置列表信息对象
|
: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 CamelCaseUtil.transform_result(config_list_result)
|
return config_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def init_cache_sys_config_services(cls, query_db: Session, redis):
|
async def init_cache_sys_config_services(cls, query_db: Session, redis):
|
||||||
@@ -35,10 +36,10 @@ class ConfigService:
|
|||||||
# 删除匹配的键
|
# 删除匹配的键
|
||||||
if keys:
|
if keys:
|
||||||
await redis.delete(*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:
|
for config_obj in config_all:
|
||||||
if config_obj.config_type == 'Y':
|
if config_obj.get('configType') == 'Y':
|
||||||
await redis.set(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_obj.config_key}", config_obj.config_value)
|
await redis.set(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_obj.get('configKey')}", config_obj.get('configValue'))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def query_config_list_from_cache_services(cls, redis, config_key: str):
|
async def query_config_list_from_cache_services(cls, redis, config_key: str):
|
||||||
|
@@ -12,16 +12,17 @@ class DictTypeService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取字典类型列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 字典类型列表信息对象
|
:return: 字典类型列表信息对象
|
||||||
"""
|
"""
|
||||||
dict_type_list_result = DictTypeDao.get_dict_type_list(query_db, query_object)
|
dict_type_list_result = DictTypeDao.get_dict_type_list(query_db, query_object, is_page)
|
||||||
|
|
||||||
return CamelCaseUtil.transform_result(dict_type_list_result)
|
return dict_type_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def add_dict_type_services(cls, request: Request, query_db: Session, page_object: DictTypeModel):
|
async def add_dict_type_services(cls, request: Request, query_db: Session, page_object: DictTypeModel):
|
||||||
@@ -172,16 +173,17 @@ class DictDataService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取字典数据列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 字典数据列表信息对象
|
: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 CamelCaseUtil.transform_result(dict_data_list_result)
|
return dict_data_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def query_dict_data_list_services(cls, query_db: Session, dict_type: str):
|
def query_dict_data_list_services(cls, query_db: Session, dict_type: str):
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
from module_admin.dao.job_log_dao 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 module_admin.entity.vo.common_vo import CrudResponseModel
|
||||||
from utils.common_util import export_list2excel, CamelCaseUtil
|
from utils.common_util import export_list2excel
|
||||||
|
|
||||||
|
|
||||||
class JobLogService:
|
class JobLogService:
|
||||||
@@ -10,16 +10,17 @@ class JobLogService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取定时任务日志列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 定时任务日志列表信息对象
|
: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 CamelCaseUtil.transform_result(job_log_list_result)
|
return job_log_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_job_log_services(cls, query_db: Session, page_object: JobLogModel):
|
def add_job_log_services(cls, query_db: Session, page_object: JobLogModel):
|
||||||
@@ -79,10 +80,10 @@ class JobLogService:
|
|||||||
return CrudResponseModel(**result)
|
return CrudResponseModel(**result)
|
||||||
|
|
||||||
@staticmethod
|
@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
|
导出定时任务日志信息service
|
||||||
:param query_db: orm对象
|
:param request: Request对象
|
||||||
:param job_log_list: 定时任务日志信息列表
|
:param job_log_list: 定时任务日志信息列表
|
||||||
:return: 定时任务日志信息对应excel的二进制数据
|
:return: 定时任务日志信息对应excel的二进制数据
|
||||||
"""
|
"""
|
||||||
@@ -103,17 +104,22 @@ class JobLogService:
|
|||||||
}
|
}
|
||||||
|
|
||||||
data = job_log_list
|
data = job_log_list
|
||||||
job_group_list = DictDataDao.query_dict_data_list(query_db, dict_type='sys_job_group')
|
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group')
|
||||||
job_group_option = [dict(label=item.dict_label, value=item.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_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:
|
for item in data:
|
||||||
if item.get('status') == '0':
|
if item.get('status') == '0':
|
||||||
item['status'] = '正常'
|
item['status'] = '正常'
|
||||||
else:
|
else:
|
||||||
item['status'] = '暂停'
|
item['status'] = '暂停'
|
||||||
if str(item.get('job_group')) in job_group_option_dict.keys():
|
if str(item.get('jobGroup')) in job_group_option_dict.keys():
|
||||||
item['job_group'] = job_group_option_dict.get(str(item.get('job_group'))).get('label')
|
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
|
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in
|
||||||
data]
|
data]
|
||||||
binary_data = export_list2excel(new_data)
|
binary_data = export_list2excel(new_data)
|
||||||
|
@@ -11,16 +11,17 @@ class JobService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取定时任务列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 定时任务列表信息对象
|
: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 CamelCaseUtil.transform_result(job_list_result)
|
return job_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_job_services(cls, query_db: Session, page_object: JobModel):
|
def add_job_services(cls, query_db: Session, page_object: JobModel):
|
||||||
|
@@ -10,16 +10,17 @@ class OperationLogService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取操作日志列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 操作日志列表信息对象
|
: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 CamelCaseUtil.transform_result(operation_log_list_result)
|
return operation_log_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_operation_log_services(cls, query_db: Session, page_object: OperLogModel):
|
def add_operation_log_services(cls, query_db: Session, page_object: OperLogModel):
|
||||||
@@ -131,16 +132,17 @@ class LoginLogService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取登录日志列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 登录日志列表信息对象
|
: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 CamelCaseUtil.transform_result(operation_log_list_result)
|
return operation_log_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_login_log_services(cls, query_db: Session, page_object: LogininforModel):
|
def add_login_log_services(cls, query_db: Session, page_object: LogininforModel):
|
||||||
|
@@ -9,12 +9,13 @@ from module_admin.service.user_service import *
|
|||||||
from module_admin.entity.vo.login_vo import *
|
from module_admin.entity.vo.login_vo import *
|
||||||
from module_admin.entity.vo.common_vo import CrudResponseModel
|
from module_admin.entity.vo.common_vo import CrudResponseModel
|
||||||
from module_admin.dao.login_dao import *
|
from module_admin.dao.login_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.common_util import CamelCaseUtil
|
||||||
from utils.pwd_util import *
|
from utils.pwd_util import *
|
||||||
from utils.response_util import *
|
from utils.response_util import *
|
||||||
from utils.message_util import *
|
from utils.message_util import *
|
||||||
from config.get_db import get_db
|
|
||||||
|
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")
|
||||||
|
|
||||||
@@ -60,8 +61,13 @@ class LoginService:
|
|||||||
if login_user.user_name == account_lock:
|
if login_user.user_name == account_lock:
|
||||||
logger.warning("账号已锁定,请稍后再试")
|
logger.warning("账号已锁定,请稍后再试")
|
||||||
raise LoginException(data="", message="账号已锁定,请稍后再试")
|
raise LoginException(data="", message="账号已锁定,请稍后再试")
|
||||||
# 判断是否开启验证码,开启则验证,否则不验证
|
# 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug
|
||||||
if login_user.captcha_enabled:
|
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)
|
await cls.__check_login_captcha(request, login_user)
|
||||||
user = login_by_account(query_db, login_user.user_name)
|
user = login_by_account(query_db, login_user.user_name)
|
||||||
if not user:
|
if not user:
|
||||||
@@ -124,9 +130,9 @@ class LoginService:
|
|||||||
if expires_delta:
|
if expires_delta:
|
||||||
expire = datetime.utcnow() + expires_delta
|
expire = datetime.utcnow() + expires_delta
|
||||||
else:
|
else:
|
||||||
expire = datetime.utcnow() + timedelta(minutes=15)
|
expire = datetime.utcnow() + timedelta(minutes=30)
|
||||||
to_encode.update({"exp": expire})
|
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
|
return encoded_jwt
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -146,7 +152,7 @@ class LoginService:
|
|||||||
try:
|
try:
|
||||||
if token.startswith('Bearer'):
|
if token.startswith('Bearer'):
|
||||||
token = token.split(' ')[1]
|
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")
|
user_id: str = payload.get("user_id")
|
||||||
session_id: str = payload.get("session_id")
|
session_id: str = payload.get("session_id")
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
@@ -165,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}")
|
# redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info.user_id}")
|
||||||
if token == redis_token:
|
if token == redis_token:
|
||||||
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", 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,
|
# 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')]
|
role_id_list = [item.role_id for item in query_user.get('user_role_info')]
|
||||||
if 1 in role_id_list:
|
if 1 in role_id_list:
|
||||||
@@ -255,63 +261,104 @@ class LoginService:
|
|||||||
|
|
||||||
return router_list
|
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_sms_code_services(request: Request, query_db: Session, user: ResetUserModel):
|
return CrudResponseModel(**result)
|
||||||
"""
|
|
||||||
获取短信验证码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='获取成功'))
|
@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=False, sms_code='', session_id='', message='用户不存在'))
|
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):
|
@classmethod
|
||||||
"""
|
async def forget_user_services(cls, request: Request, query_db: Session, forget_user: ResetUserModel):
|
||||||
用户忘记密码services
|
"""
|
||||||
:param request: Request对象
|
用户忘记密码services
|
||||||
:param query_db: orm对象
|
:param request: Request对象
|
||||||
:param forget_user: 重置用户对象
|
:param query_db: orm对象
|
||||||
:return: 重置结果
|
: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:
|
redis_sms_result = await request.app.state.redis.get(
|
||||||
forget_user.password = PwdUtil.get_password_hash(forget_user.password)
|
f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}")
|
||||||
forget_user.user_id = UserDao.get_user_by_name(query_db, forget_user.user_name).user_id
|
if forget_user.sms_code == redis_sms_result:
|
||||||
edit_result = UserService.reset_user_services(query_db, forget_user)
|
forget_user.password = PwdUtil.get_password_hash(forget_user.password)
|
||||||
result = edit_result.dict()
|
forget_user.user_id = UserDao.get_user_by_name(query_db, forget_user.user_name).user_id
|
||||||
elif not redis_sms_result:
|
edit_result = UserService.reset_user_services(query_db, forget_user)
|
||||||
result = dict(is_success=False, message='短信验证码已过期')
|
result = edit_result.dict()
|
||||||
else:
|
elif not redis_sms_result:
|
||||||
await request.app.state.redis.delete(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}")
|
result = dict(is_success=False, message='短信验证码已过期')
|
||||||
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)
|
return CrudResponseModel(**result)
|
||||||
|
|
||||||
|
@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')
|
||||||
|
|
||||||
async def logout_services(request: Request, session_id: str):
|
return True
|
||||||
"""
|
|
||||||
退出登录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
|
|
||||||
|
@@ -9,16 +9,17 @@ class NoticeService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取通知公告列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 通知公告列表信息对象
|
: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 CamelCaseUtil.transform_result(notice_list_result)
|
return notice_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_notice_services(cls, query_db: Session, page_object: NoticeModel):
|
def add_notice_services(cls, query_db: Session, page_object: NoticeModel):
|
||||||
|
@@ -25,7 +25,7 @@ class OnlineService:
|
|||||||
access_token_values_list = [await request.app.state.redis.get(key) for key in access_token_keys]
|
access_token_values_list = [await request.app.state.redis.get(key) for key in access_token_keys]
|
||||||
online_info_list = []
|
online_info_list = []
|
||||||
for item in access_token_values_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(
|
online_dict = dict(
|
||||||
token_id=payload.get('session_id'),
|
token_id=payload.get('session_id'),
|
||||||
user_name=payload.get('user_name'),
|
user_name=payload.get('user_name'),
|
||||||
|
@@ -8,16 +8,17 @@ class PostService:
|
|||||||
岗位管理模块服务层
|
岗位管理模块服务层
|
||||||
"""
|
"""
|
||||||
@classmethod
|
@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
|
获取岗位列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 岗位列表信息对象
|
: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 CamelCaseUtil.transform_result(post_list_result)
|
return post_list_result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_post_services(cls, query_db: Session, page_object: PostModel):
|
def add_post_services(cls, query_db: Session, page_object: PostModel):
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
from module_admin.entity.vo.user_vo import UserInfoModel, UserRoleQueryModel
|
from module_admin.entity.vo.user_vo import UserInfoModel, UserRolePageQueryModel
|
||||||
from module_admin.entity.vo.common_vo import CrudResponseModel
|
from module_admin.entity.vo.common_vo import CrudResponseModel
|
||||||
from module_admin.dao.user_dao import UserDao
|
from module_admin.dao.user_dao import UserDao
|
||||||
from module_admin.dao.role_dao import *
|
from module_admin.dao.role_dao import *
|
||||||
|
from utils.page_util import PageResponseModel
|
||||||
from utils.common_util import export_list2excel, CamelCaseUtil
|
from utils.common_util import export_list2excel, CamelCaseUtil
|
||||||
|
|
||||||
|
|
||||||
@@ -38,16 +39,17 @@ class RoleService:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_role_list_services(cls, query_db: Session, query_object: RoleQueryModel):
|
def get_role_list_services(cls, query_db: Session, query_object: RolePageQueryModel, is_page: bool = False):
|
||||||
"""
|
"""
|
||||||
获取角色列表信息service
|
获取角色列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 角色列表信息对象
|
: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
|
@classmethod
|
||||||
def add_role_services(cls, query_db: Session, page_object: AddRoleModel):
|
def add_role_services(cls, query_db: Session, page_object: AddRoleModel):
|
||||||
@@ -230,27 +232,39 @@ class RoleService:
|
|||||||
return binary_data
|
return binary_data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_role_user_allocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel):
|
def get_role_user_allocated_list_services(cls, query_db: Session, page_object: UserRolePageQueryModel, is_page: bool = False):
|
||||||
"""
|
"""
|
||||||
根据角色id获取已分配用户列表
|
根据角色id获取已分配用户列表
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param page_object: 用户关联角色对象
|
:param page_object: 用户关联角色对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 已分配用户列表
|
:return: 已分配用户列表
|
||||||
"""
|
"""
|
||||||
query_user_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object)
|
query_user_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object, is_page)
|
||||||
allocated_list = [UserInfoModel(**CamelCaseUtil.transform_result(row)) for row in query_user_list]
|
allocated_list = PageResponseModel(
|
||||||
|
**{
|
||||||
|
**query_user_list.model_dump(by_alias=True),
|
||||||
|
'rows': [UserInfoModel(**row) for row in query_user_list.rows]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return allocated_list
|
return allocated_list
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_role_user_unallocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel):
|
def get_role_user_unallocated_list_services(cls, query_db: Session, page_object: UserRolePageQueryModel, is_page: bool = False):
|
||||||
"""
|
"""
|
||||||
根据角色id获取未分配用户列表
|
根据角色id获取未分配用户列表
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param page_object: 用户关联角色对象
|
:param page_object: 用户关联角色对象
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 未分配用户列表
|
:return: 未分配用户列表
|
||||||
"""
|
"""
|
||||||
query_user_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object)
|
query_user_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object, is_page)
|
||||||
unallocated_list = [UserInfoModel(**CamelCaseUtil.transform_result(row)) for row in query_user_list]
|
unallocated_list = PageResponseModel(
|
||||||
|
**{
|
||||||
|
**query_user_list.model_dump(by_alias=True),
|
||||||
|
'rows': [UserInfoModel(**row) for row in query_user_list.rows]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return unallocated_list
|
return unallocated_list
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
from fastapi import UploadFile
|
from fastapi import UploadFile
|
||||||
from module_admin.service.role_service import RoleService
|
from module_admin.service.role_service import RoleService
|
||||||
from module_admin.service.post_service import PostService
|
from module_admin.service.post_service import PostService, PostPageQueryModel
|
||||||
from module_admin.entity.vo.common_vo import CrudResponseModel
|
from module_admin.entity.vo.common_vo import CrudResponseModel
|
||||||
from module_admin.dao.user_dao import *
|
from module_admin.dao.user_dao import *
|
||||||
|
from utils.page_util import PageResponseModel
|
||||||
from utils.pwd_util import *
|
from utils.pwd_util import *
|
||||||
from utils.common_util import *
|
from utils.common_util import *
|
||||||
|
|
||||||
@@ -13,18 +14,27 @@ class UserService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@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
|
获取用户列表信息service
|
||||||
:param query_db: orm对象
|
:param query_db: orm对象
|
||||||
:param query_object: 查询参数对象
|
:param query_object: 查询参数对象
|
||||||
:param data_scope_sql: 数据权限对应的查询sql语句
|
:param data_scope_sql: 数据权限对应的查询sql语句
|
||||||
|
:param is_page: 是否开启分页
|
||||||
:return: 用户列表信息对象
|
:return: 用户列表信息对象
|
||||||
"""
|
"""
|
||||||
query_result = UserDao.get_user_list(query_db, query_object, data_scope_sql)
|
query_result = UserDao.get_user_list(query_db, query_object, data_scope_sql, is_page)
|
||||||
user_list_result = []
|
if is_page:
|
||||||
if query_result:
|
user_list_result = PageResponseModel(
|
||||||
user_list_result = [{**CamelCaseUtil.transform_result(row[0]), 'dept': CamelCaseUtil.transform_result(row[1])} for row in query_result]
|
**{
|
||||||
|
**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
|
return user_list_result
|
||||||
|
|
||||||
@@ -134,7 +144,7 @@ class UserService:
|
|||||||
:param user_id: 用户id
|
:param user_id: 用户id
|
||||||
:return: 用户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)
|
roles = RoleService.get_role_select_option_services(query_db)
|
||||||
if user_id != '':
|
if user_id != '':
|
||||||
query_user = UserDao.get_user_detail_by_id(query_db, user_id=user_id)
|
query_user = UserDao.get_user_detail_by_id(query_db, user_id=user_id)
|
||||||
|
15
ruoyi-fastapi-backend/requirements.txt
Normal file
15
ruoyi-fastapi-backend/requirements.txt
Normal file
@@ -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
|
83
ruoyi-fastapi-backend/server.py
Normal file
83
ruoyi-fastapi-backend/server.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
from fastapi import FastAPI
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
from sub_applications.handle import handle_sub_applications
|
||||||
|
from middlewares.handle import handle_middleware
|
||||||
|
from exceptions.handle import handle_exception
|
||||||
|
from module_admin.controller.login_controller import loginController
|
||||||
|
from module_admin.controller.captcha_controller import captchaController
|
||||||
|
from module_admin.controller.user_controller import userController
|
||||||
|
from module_admin.controller.menu_controller import menuController
|
||||||
|
from module_admin.controller.dept_controller import deptController
|
||||||
|
from module_admin.controller.role_controller import roleController
|
||||||
|
from module_admin.controller.post_controler import postController
|
||||||
|
from module_admin.controller.dict_controller import dictController
|
||||||
|
from module_admin.controller.config_controller import configController
|
||||||
|
from module_admin.controller.notice_controller import noticeController
|
||||||
|
from module_admin.controller.log_controller import logController
|
||||||
|
from module_admin.controller.online_controller import onlineController
|
||||||
|
from module_admin.controller.job_controller import jobController
|
||||||
|
from module_admin.controller.server_controller import serverController
|
||||||
|
from module_admin.controller.cache_controller import cacheController
|
||||||
|
from module_admin.controller.common_controller import commonController
|
||||||
|
from 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.log_util import logger
|
||||||
|
from utils.common_util import worship
|
||||||
|
|
||||||
|
|
||||||
|
# 生命周期事件
|
||||||
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: 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(f"{AppConfig.app_name}启动成功")
|
||||||
|
yield
|
||||||
|
await RedisUtil.close_redis_pool(app)
|
||||||
|
await SchedulerUtil.close_system_scheduler()
|
||||||
|
|
||||||
|
|
||||||
|
# 初始化FastAPI对象
|
||||||
|
app = FastAPI(
|
||||||
|
title=AppConfig.app_name,
|
||||||
|
description=f'{AppConfig.app_name}接口文档',
|
||||||
|
version=AppConfig.app_version,
|
||||||
|
lifespan=lifespan
|
||||||
|
)
|
||||||
|
|
||||||
|
# 挂载子应用
|
||||||
|
handle_sub_applications(app)
|
||||||
|
# 加载中间件处理方法
|
||||||
|
handle_middleware(app)
|
||||||
|
# 加载全局异常处理方法
|
||||||
|
handle_exception(app)
|
||||||
|
|
||||||
|
|
||||||
|
# 加载路由列表
|
||||||
|
controller_list = [
|
||||||
|
{'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'), tags=controller.get('tags'))
|
10
ruoyi-fastapi-backend/sub_applications/handle.py
Normal file
10
ruoyi-fastapi-backend/sub_applications/handle.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from fastapi import FastAPI
|
||||||
|
from sub_applications.staticfiles import mount_staticfiles
|
||||||
|
|
||||||
|
|
||||||
|
def handle_sub_applications(app: FastAPI):
|
||||||
|
"""
|
||||||
|
全局处理子应用挂载
|
||||||
|
"""
|
||||||
|
# 挂载静态文件
|
||||||
|
mount_staticfiles(app)
|
10
ruoyi-fastapi-backend/sub_applications/staticfiles.py
Normal file
10
ruoyi-fastapi-backend/sub_applications/staticfiles.py
Normal file
@@ -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")
|
@@ -5,6 +5,7 @@ from openpyxl import Workbook
|
|||||||
from openpyxl.styles import Alignment, PatternFill
|
from openpyxl.styles import Alignment, PatternFill
|
||||||
from openpyxl.utils import get_column_letter
|
from openpyxl.utils import get_column_letter
|
||||||
from openpyxl.worksheet.datavalidation import DataValidation
|
from openpyxl.worksheet.datavalidation import DataValidation
|
||||||
|
from sqlalchemy.engine.row import Row
|
||||||
from typing import List
|
from typing import List
|
||||||
from config.env import CachePathConfig
|
from config.env import CachePathConfig
|
||||||
|
|
||||||
@@ -66,7 +67,10 @@ class CamelCaseUtil:
|
|||||||
return {cls.__to_camel_case(k): v for k, v in result.items()}
|
return {cls.__to_camel_case(k): v for k, v in result.items()}
|
||||||
# 如果是一组字典或其他类型的列表,遍历列表进行转换
|
# 如果是一组字典或其他类型的列表,遍历列表进行转换
|
||||||
elif isinstance(result, list):
|
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:
|
else:
|
||||||
return cls.transform_result({c.name: getattr(result, c.name) for c in result.__table__.columns})
|
return cls.transform_result({c.name: getattr(result, c.name) for c in result.__table__.columns})
|
||||||
|
@@ -1,30 +1,9 @@
|
|||||||
import math
|
import math
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
|
from sqlalchemy.orm.query import Query
|
||||||
from pydantic import BaseModel, ConfigDict
|
from pydantic import BaseModel, ConfigDict
|
||||||
from pydantic.alias_generators import to_camel
|
from pydantic.alias_generators import to_camel
|
||||||
|
from utils.common_util import CamelCaseUtil
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
class PageResponseModel(BaseModel):
|
class PageResponseModel(BaseModel):
|
||||||
@@ -40,33 +19,64 @@ class PageResponseModel(BaseModel):
|
|||||||
has_next: Optional[bool] = None
|
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:
|
@classmethod
|
||||||
res_offset_1 = (page_num - 2) * page_size
|
def get_page_obj(cls, data_list: List, page_num: int, page_size: int):
|
||||||
if res_offset_1 < 0:
|
"""
|
||||||
res_offset = 0
|
输入数据列表data_list和分页信息,返回分页数据列表结果
|
||||||
res_page_num = 1
|
: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:
|
else:
|
||||||
res_offset = res_offset_1
|
no_paginated_data = query.all()
|
||||||
res_page_num = page_num - 1
|
result = CamelCaseUtil.transform_result(no_paginated_data)
|
||||||
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)
|
return result
|
||||||
|
|
||||||
return PageModel(**result)
|
|
||||||
|
|
||||||
|
|
||||||
def get_page_obj(data_list: List, page_num: int, page_size: int):
|
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
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@@ -187,115 +187,3 @@ class ResponseUtil:
|
|||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
content=data
|
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
|
|
||||||
|
@@ -16,9 +16,12 @@
|
|||||||
"url": "https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI.git"
|
"url": "https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ant-design/icons-vue": "^7.0.1",
|
||||||
|
"@antv/g2plot": "^2.4.31",
|
||||||
"@element-plus/icons-vue": "2.3.1",
|
"@element-plus/icons-vue": "2.3.1",
|
||||||
"@vueup/vue-quill": "1.2.0",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "10.6.1",
|
"@vueuse/core": "10.6.1",
|
||||||
|
"ant-design-vue": "^4.1.1",
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
"echarts": "5.4.3",
|
"echarts": "5.4.3",
|
||||||
"element-plus": "2.4.3",
|
"element-plus": "2.4.3",
|
||||||
@@ -35,11 +38,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "4.5.0",
|
"@vitejs/plugin-vue": "4.5.0",
|
||||||
"@vue/compiler-sfc": "3.3.9",
|
"@vue/compiler-sfc": "3.3.9",
|
||||||
|
"less": "^4.2.0",
|
||||||
"sass": "1.69.5",
|
"sass": "1.69.5",
|
||||||
"unplugin-auto-import": "0.17.1",
|
"unplugin-auto-import": "0.17.1",
|
||||||
|
"unplugin-vue-setup-extend-plus": "1.0.0",
|
||||||
"vite": "5.0.4",
|
"vite": "5.0.4",
|
||||||
"vite-plugin-compression": "0.5.1",
|
"vite-plugin-compression": "0.5.1",
|
||||||
"vite-plugin-svg-icons": "2.0.1",
|
"vite-plugin-svg-icons": "2.0.1"
|
||||||
"unplugin-vue-setup-extend-plus": "1.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const url = ref('https://gitee.com/y_project/RuoYi-Vue');
|
const url = ref('https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI');
|
||||||
|
|
||||||
function goto() {
|
function goto() {
|
||||||
window.open(url.value)
|
window.open(url.value)
|
||||||
|
@@ -64,7 +64,7 @@ export const constantRoutes = [
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/index',
|
path: '/index',
|
||||||
component: () => import('@/views/index'),
|
component: () => import('@/views/dashboard/index'),
|
||||||
name: 'Index',
|
name: 'Index',
|
||||||
meta: { title: '首页', icon: 'dashboard', affix: true }
|
meta: { title: '首页', icon: 'dashboard', affix: true }
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<div class="linkGroup">
|
||||||
|
<a v-for="(item, index) in links" :key="index" :href="item.href">
|
||||||
|
{{ item.title }}
|
||||||
|
</a>
|
||||||
|
<a-button size="small" type="primary" ghost>
|
||||||
|
<PlusOutlined /> 添加
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Button } from "ant-design-vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
AButton: Button,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { PlusOutlined } from "@ant-design/icons-vue";
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{
|
||||||
|
title: "操作一",
|
||||||
|
href: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作二",
|
||||||
|
href: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作三",
|
||||||
|
href: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作四",
|
||||||
|
href: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作五",
|
||||||
|
href: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作六",
|
||||||
|
href: "",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.linkGroup {
|
||||||
|
padding: 20px 0 8px 24px;
|
||||||
|
font-size: 0;
|
||||||
|
& > a {
|
||||||
|
display: inline-block;
|
||||||
|
width: 25%;
|
||||||
|
margin-bottom: 13px;
|
||||||
|
color: rgba(0, 0, 0, 0.65);
|
||||||
|
font-size: 14px;
|
||||||
|
&:hover {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
738
ruoyi-fastapi-frontend/src/views/dashboard/index.vue
Normal file
738
ruoyi-fastapi-frontend/src/views/dashboard/index.vue
Normal file
@@ -0,0 +1,738 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="pageHeaderContent">
|
||||||
|
<div class="avatar">
|
||||||
|
<a-avatar size="large" :src="currentUser.avatar" />
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="contentTitle">
|
||||||
|
早安,
|
||||||
|
{{ currentUser.name }}
|
||||||
|
,祝你开心每一天!
|
||||||
|
</div>
|
||||||
|
<div>{{ currentUser.title }} |{{ currentUser.group }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="extraContent">
|
||||||
|
<div class="statItem">
|
||||||
|
<a-statistic title="项目数" :value="56" />
|
||||||
|
</div>
|
||||||
|
<div class="statItem">
|
||||||
|
<a-statistic title="团队内排名" :value="8" suffix="/ 24" />
|
||||||
|
</div>
|
||||||
|
<div class="statItem">
|
||||||
|
<a-statistic title="项目访问" :value="2223" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding: 10px">
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :xl="16" :lg="24" :md="24" :sm="24" :xs="24">
|
||||||
|
<a-card
|
||||||
|
class="projectList"
|
||||||
|
:style="{ marginBottom: '24px' }"
|
||||||
|
title="进行中的项目"
|
||||||
|
:bordered="false"
|
||||||
|
:loading="false"
|
||||||
|
:body-style="{ padding: 0 }"
|
||||||
|
>
|
||||||
|
<template #extra>
|
||||||
|
<a href=""> <span style="color: #1890ff">全部项目</span> </a>
|
||||||
|
</template>
|
||||||
|
<a-card-grid
|
||||||
|
v-for="item in projectNotice"
|
||||||
|
:key="item.id"
|
||||||
|
class="projectGrid"
|
||||||
|
>
|
||||||
|
<a-card
|
||||||
|
:body-style="{ padding: 0 }"
|
||||||
|
style="box-shadow: none"
|
||||||
|
:bordered="false"
|
||||||
|
>
|
||||||
|
<a-card-meta :description="item.description" class="w-full">
|
||||||
|
<template #title>
|
||||||
|
<div class="cardTitle">
|
||||||
|
<a-avatar size="small" :src="item.logo" />
|
||||||
|
<a :href="item.href">
|
||||||
|
{{ item.title }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-card-meta>
|
||||||
|
<div class="projectItemContent">
|
||||||
|
<a :href="item.memberLink">
|
||||||
|
{{ item.member || "" }}
|
||||||
|
</a>
|
||||||
|
<span class="datetime" ml-2 :title="item.updatedAt">
|
||||||
|
{{ item.updatedAt }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
</a-card-grid>
|
||||||
|
</a-card>
|
||||||
|
<a-card
|
||||||
|
:body-style="{ padding: 0 }"
|
||||||
|
:bordered="false"
|
||||||
|
class="activeCard"
|
||||||
|
title="动态"
|
||||||
|
:loading="false"
|
||||||
|
>
|
||||||
|
<a-list :data-source="activities" class="activitiesList">
|
||||||
|
<template #renderItem="{ item }">
|
||||||
|
<a-list-item :key="item.id">
|
||||||
|
<a-list-item-meta>
|
||||||
|
<template #title>
|
||||||
|
<span>
|
||||||
|
<a class="username">{{ item.user.name }}</a
|
||||||
|
>
|
||||||
|
<span class="event">
|
||||||
|
<span>{{ item.template1 }}</span
|
||||||
|
>
|
||||||
|
<a href="" style="color: #1890ff">
|
||||||
|
{{ item?.group?.name }} </a
|
||||||
|
> <span>{{ item.template2 }}</span
|
||||||
|
>
|
||||||
|
<a href="" style="color: #1890ff">
|
||||||
|
{{ item?.project?.name }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #avatar>
|
||||||
|
<a-avatar :src="item.user.avatar" />
|
||||||
|
</template>
|
||||||
|
<template #description>
|
||||||
|
<span class="datetime" :title="item.updatedAt">
|
||||||
|
{{ item.updatedAt }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
</template>
|
||||||
|
</a-list>
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
<a-col :xl="8" :lg="24" :md="24" :sm="24" :xs="24">
|
||||||
|
<a-card
|
||||||
|
:style="{ marginBottom: '24px' }"
|
||||||
|
title="快速开始 / 便捷导航"
|
||||||
|
:bordered="false"
|
||||||
|
:body-style="{ padding: 0 }"
|
||||||
|
>
|
||||||
|
<EditableLinkGroup />
|
||||||
|
</a-card>
|
||||||
|
<a-card
|
||||||
|
:style="{ marginBottom: '24px' }"
|
||||||
|
:bordered="false"
|
||||||
|
title="XX 指数"
|
||||||
|
>
|
||||||
|
<div class="chart">
|
||||||
|
<div ref="radarContainer" />
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
<a-card
|
||||||
|
:body-style="{ paddingTop: '12px', paddingBottom: '12px' }"
|
||||||
|
:bordered="false"
|
||||||
|
title="团队"
|
||||||
|
>
|
||||||
|
<div class="members">
|
||||||
|
<a-row :gutter="48">
|
||||||
|
<a-col
|
||||||
|
v-for="item in projectNotice"
|
||||||
|
:key="`members-item-${item.id}`"
|
||||||
|
:span="12"
|
||||||
|
>
|
||||||
|
<a :href="item.href">
|
||||||
|
<a-avatar :src="item.logo" size="small" />
|
||||||
|
<span class="member">{{ item.member }}</span>
|
||||||
|
</a>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
Statistic,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
Card,
|
||||||
|
CardGrid,
|
||||||
|
CardMeta,
|
||||||
|
List,
|
||||||
|
ListItem,
|
||||||
|
ListItemMeta,
|
||||||
|
Avatar,
|
||||||
|
} from "ant-design-vue";
|
||||||
|
import 'ant-design-vue/dist/reset.css';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
AStatistic: Statistic,
|
||||||
|
ARow: Row,
|
||||||
|
ACol: Col,
|
||||||
|
ACard: Card,
|
||||||
|
ACardGrid: CardGrid,
|
||||||
|
ACardMeta: CardMeta,
|
||||||
|
AList: List,
|
||||||
|
AListItem: ListItem,
|
||||||
|
AListItemMeta: ListItemMeta,
|
||||||
|
AAvatar: Avatar,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Radar } from "@antv/g2plot";
|
||||||
|
import EditableLinkGroup from "./editable-link-group.vue";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "DashBoard",
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentUser = {
|
||||||
|
avatar: "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
|
||||||
|
name: "吴彦祖",
|
||||||
|
userid: "00000001",
|
||||||
|
email: "antdesign@alipay.com",
|
||||||
|
signature: "海纳百川,有容乃大",
|
||||||
|
title: "交互专家",
|
||||||
|
group: "蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED",
|
||||||
|
};
|
||||||
|
|
||||||
|
const projectNotice = [
|
||||||
|
{
|
||||||
|
id: "xxx1",
|
||||||
|
title: "Alipay",
|
||||||
|
logo: "https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png",
|
||||||
|
description: "那是一种内在的东西,他们到达不了,也无法触及的",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
member: "科学搬砖组",
|
||||||
|
href: "",
|
||||||
|
memberLink: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "xxx2",
|
||||||
|
title: "Angular",
|
||||||
|
logo: "https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png",
|
||||||
|
description: "希望是一个好东西,也许是最好的,好东西是不会消亡的",
|
||||||
|
updatedAt: "6 年前",
|
||||||
|
member: "全组都是吴彦祖",
|
||||||
|
href: "",
|
||||||
|
memberLink: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "xxx3",
|
||||||
|
title: "Ant Design",
|
||||||
|
logo: "https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png",
|
||||||
|
description: "城镇中有那么多的酒馆,她却偏偏走进了我的酒馆",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
member: "中二少女团",
|
||||||
|
href: "",
|
||||||
|
memberLink: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "xxx4",
|
||||||
|
title: "Ant Design Pro",
|
||||||
|
logo: "https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png",
|
||||||
|
description: "那时候我只会想自己想要什么,从不想自己拥有什么",
|
||||||
|
updatedAt: "6 年前",
|
||||||
|
member: "程序员日常",
|
||||||
|
href: "",
|
||||||
|
memberLink: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "xxx5",
|
||||||
|
title: "Bootstrap",
|
||||||
|
logo: "https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png",
|
||||||
|
description:
|
||||||
|
"凛冬将至",
|
||||||
|
updatedAt: "6 年前",
|
||||||
|
member: "高逼格设计天团",
|
||||||
|
href: "",
|
||||||
|
memberLink: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "xxx6",
|
||||||
|
title: "React",
|
||||||
|
logo: "https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png",
|
||||||
|
description: "生命就像一盒巧克力,结果往往出人意料",
|
||||||
|
updatedAt: "6 年前",
|
||||||
|
member: "骗你来学计算机",
|
||||||
|
href: "",
|
||||||
|
memberLink: "",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const activities = [
|
||||||
|
{
|
||||||
|
id: "trend-1",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
user: {
|
||||||
|
name: "曲丽丽",
|
||||||
|
avatar:
|
||||||
|
"https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
name: "高逼格设计天团",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
name: "六月迭代",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
template1: "在",
|
||||||
|
template2: "新建项目",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "trend-2",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
user: {
|
||||||
|
name: "付小小",
|
||||||
|
avatar:
|
||||||
|
"https://gw.alipayobjects.com/zos/rmsportal/cnrhVkzwxjPwAaCfPbdc.png",
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
name: "高逼格设计天团",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
name: "六月迭代",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
template1: "在",
|
||||||
|
template2: "新建项目",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "trend-3",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
user: {
|
||||||
|
name: "林东东",
|
||||||
|
avatar:
|
||||||
|
"https://gw.alipayobjects.com/zos/rmsportal/gaOngJwsRYRaVAuXXcmB.png",
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
name: "中二少女团",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
name: "六月迭代",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
template1: "在",
|
||||||
|
template2: "新建项目",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "trend-4",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
user: {
|
||||||
|
name: "周星星",
|
||||||
|
avatar:
|
||||||
|
"https://gw.alipayobjects.com/zos/rmsportal/WhxKECPNujWoWEFNdnJE.png",
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
name: "5 月日常迭代",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
template1: "将",
|
||||||
|
template2: "更新至已发布状态",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "trend-5",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
user: {
|
||||||
|
name: "朱偏右",
|
||||||
|
avatar:
|
||||||
|
"https://gw.alipayobjects.com/zos/rmsportal/ubnKSIfAJTxIgXOKlciN.png",
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
name: "工程效能",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
name: "留言",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
template1: "在",
|
||||||
|
template2: "发布了",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "trend-6",
|
||||||
|
updatedAt: "几秒前",
|
||||||
|
user: {
|
||||||
|
name: "乐哥",
|
||||||
|
avatar:
|
||||||
|
"https://gw.alipayobjects.com/zos/rmsportal/jZUIxmJycoymBprLOUbT.png",
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
name: "程序员日常",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
name: "品牌迭代",
|
||||||
|
link: "http://github.com/",
|
||||||
|
},
|
||||||
|
template1: "在",
|
||||||
|
template2: "新建项目",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const radarContainer = ref();
|
||||||
|
const radarData = [
|
||||||
|
{
|
||||||
|
name: "个人",
|
||||||
|
label: "引用",
|
||||||
|
value: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "个人",
|
||||||
|
label: "口碑",
|
||||||
|
value: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "个人",
|
||||||
|
label: "产量",
|
||||||
|
value: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "个人",
|
||||||
|
label: "贡献",
|
||||||
|
value: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "个人",
|
||||||
|
label: "热度",
|
||||||
|
value: 7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "团队",
|
||||||
|
label: "引用",
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "团队",
|
||||||
|
label: "口碑",
|
||||||
|
value: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "团队",
|
||||||
|
label: "产量",
|
||||||
|
value: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "团队",
|
||||||
|
label: "贡献",
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "团队",
|
||||||
|
label: "热度",
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "部门",
|
||||||
|
label: "引用",
|
||||||
|
value: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "部门",
|
||||||
|
label: "口碑",
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "部门",
|
||||||
|
label: "产量",
|
||||||
|
value: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "部门",
|
||||||
|
label: "贡献",
|
||||||
|
value: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "部门",
|
||||||
|
label: "热度",
|
||||||
|
value: 7,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
let radar;
|
||||||
|
onMounted(() => {
|
||||||
|
radar = new Radar(radarContainer.value, {
|
||||||
|
data: radarData,
|
||||||
|
xField: "label",
|
||||||
|
yField: "value",
|
||||||
|
seriesField: "name",
|
||||||
|
point: {
|
||||||
|
size: 4,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
layout: "horizontal",
|
||||||
|
position: "bottom",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
radar.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
radar?.destroy?.();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.textOverflow() {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mixins for clearfix
|
||||||
|
// ------------------------
|
||||||
|
.clearfix() {
|
||||||
|
zoom: 1;
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
display: table;
|
||||||
|
content: " ";
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
clear: both;
|
||||||
|
height: 0;
|
||||||
|
font-size: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.activitiesList {
|
||||||
|
padding: 0 24px 8px 24px;
|
||||||
|
.username {
|
||||||
|
color: rgba(0, 0, 0, 0.65);
|
||||||
|
}
|
||||||
|
.event {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pageHeaderContent {
|
||||||
|
display: flex;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
||||||
|
.avatar {
|
||||||
|
flex: 0 1 72px;
|
||||||
|
& > span {
|
||||||
|
display: block;
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
border-radius: 72px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
margin-left: 24px;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
line-height: 22px;
|
||||||
|
.contentTitle {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.extraContent {
|
||||||
|
.clearfix();
|
||||||
|
|
||||||
|
float: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
.statItem {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 32px;
|
||||||
|
> p:first-child {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
> p {
|
||||||
|
margin: 0;
|
||||||
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
font-size: 30px;
|
||||||
|
line-height: 38px;
|
||||||
|
> span {
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.members {
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
height: 24px;
|
||||||
|
margin: 12px 0;
|
||||||
|
color: rgba(0, 0, 0, 0.65);
|
||||||
|
transition: all 0.3s;
|
||||||
|
.textOverflow();
|
||||||
|
.member {
|
||||||
|
margin-left: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.projectList {
|
||||||
|
:deep(.ant-card-meta-description) {
|
||||||
|
height: 44px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
.cardTitle {
|
||||||
|
font-size: 0;
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
height: 24px;
|
||||||
|
margin-left: 12px;
|
||||||
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
vertical-align: top;
|
||||||
|
&:hover {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.projectGrid {
|
||||||
|
width: 33.33%;
|
||||||
|
}
|
||||||
|
.projectItemContent {
|
||||||
|
display: flex;
|
||||||
|
flex-basis: 100%;
|
||||||
|
height: 20px;
|
||||||
|
margin-top: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
.textOverflow();
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
flex: 1 1 0;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
.textOverflow();
|
||||||
|
&:hover {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.datetime {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
float: right;
|
||||||
|
color: rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetime {
|
||||||
|
color: rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1200px) and (min-width: 992px) {
|
||||||
|
.activeCard {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
.members {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.extraContent {
|
||||||
|
margin-left: -44px;
|
||||||
|
.statItem {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 992px) {
|
||||||
|
.activeCard {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
.members {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.extraContent {
|
||||||
|
float: none;
|
||||||
|
margin-right: 0;
|
||||||
|
.statItem {
|
||||||
|
padding: 0 16px;
|
||||||
|
text-align: left;
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
.extraContent {
|
||||||
|
margin-left: -16px;
|
||||||
|
}
|
||||||
|
.projectList {
|
||||||
|
.projectGrid {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 576px) {
|
||||||
|
.pageHeaderContent {
|
||||||
|
display: block;
|
||||||
|
.content {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.extraContent {
|
||||||
|
.statItem {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 480px) {
|
||||||
|
.projectList {
|
||||||
|
.projectGrid {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
File diff suppressed because it is too large
Load Diff
@@ -76,8 +76,8 @@ const router = useRouter();
|
|||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
const loginForm = ref({
|
const loginForm = ref({
|
||||||
username: "admin",
|
username: "",
|
||||||
password: "admin123",
|
password: "",
|
||||||
rememberMe: false,
|
rememberMe: false,
|
||||||
code: "",
|
code: "",
|
||||||
uuid: ""
|
uuid: ""
|
||||||
@@ -140,6 +140,7 @@ function handleLogin() {
|
|||||||
function getCode() {
|
function getCode() {
|
||||||
getCodeImg().then(res => {
|
getCodeImg().then(res => {
|
||||||
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
|
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
|
||||||
|
register.value = res.registerEnabled === undefined ? false : res.registerEnabled;
|
||||||
if (captchaEnabled.value) {
|
if (captchaEnabled.value) {
|
||||||
codeUrl.value = "data:image/gif;base64," + res.img;
|
codeUrl.value = "data:image/gif;base64," + res.img;
|
||||||
loginForm.value.uuid = res.uuid;
|
loginForm.value.uuid = res.uuid;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="register">
|
<div class="register">
|
||||||
<el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
|
<el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
|
||||||
<h3 class="title">若依后台管理系统</h3>
|
<h3 class="title">vfadmin后台管理系统</h3>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="registerForm.username"
|
v-model="registerForm.username"
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div class="el-register-footer">
|
<div class="el-register-footer">
|
||||||
<span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>
|
<span>Copyright © 2024 insistence.tech All Rights Reserved.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
Reference in New Issue
Block a user