feat: 初始化项目架构

This commit is contained in:
insistence
2024-01-22 23:46:27 +08:00
parent 10b686ff0f
commit f0c38a87dc
347 changed files with 30398 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
from fastapi import FastAPI, Request
import uvicorn
from fastapi.exceptions import HTTPException
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager
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.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,
root_path='/dev-api'
)
# 前端页面url
origins = [
"http://localhost:81",
"http://127.0.0.1:81",
]
# 后台api允许跨域
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 自定义token检验异常
@app.exception_handler(AuthException)
async def auth_exception_handler(request: Request, exc: AuthException):
return ResponseUtil.unauthorized(data=exc.data, msg=exc.message)
# 自定义权限检验异常
@app.exception_handler(PermissionException)
async def permission_exception_handler(request: Request, exc: PermissionException):
return ResponseUtil.forbidden(data=exc.data, msg=exc.message)
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
return JSONResponse(
content=jsonable_encoder({"message": exc.detail, "code": exc.status_code}),
status_code=exc.status_code
)
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__':
uvicorn.run(app='app:app', host="0.0.0.0", port=9099, reload=True)

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -0,0 +1,14 @@
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from urllib.parse import quote_plus
from config.env import DataBaseConfig
SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.USERNAME}:{quote_plus(DataBaseConfig.PASSWORD)}@" \
f"{DataBaseConfig.HOST}:{DataBaseConfig.PORT}/{DataBaseConfig.DB}"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, echo=True
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

View File

@@ -0,0 +1,54 @@
import os
class JwtConfig:
"""
Jwt配置
"""
SECRET_KEY = "b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 1440
REDIS_TOKEN_EXPIRE_MINUTES = 30
class DataBaseConfig:
"""
数据库配置
"""
HOST = "127.0.0.1"
PORT = 3306
USERNAME = 'root'
PASSWORD = 'mysqlroot'
DB = 'ruoyi-fastapi'
class RedisConfig:
"""
Redis配置
"""
HOST = "127.0.0.1"
PORT = 6379
USERNAME = ''
PASSWORD = ''
DB = 2
class CachePathConfig:
"""
缓存目录配置
"""
PATH = os.path.join(os.path.abspath(os.getcwd()), 'caches')
PATHSTR = 'caches'
class RedisInitKeyConfig:
"""
系统内置Redis键名
"""
ACCESS_TOKEN = {'key': 'access_token', 'remark': '登录令牌信息'}
SYS_DICT = {'key': 'sys_dict', 'remark': '数据字典'}
SYS_CONFIG = {'key': 'sys_config', 'remark': '配置信息'}
CAPTCHA_CODES = {'key': 'captcha_codes', 'remark': '图片验证码'}
ACCOUNT_LOCK = {'key': 'account_lock', 'remark': '用户锁定'}
PASSWORD_ERROR_COUNT = {'key': 'password_error_count', 'remark': '密码错误次数'}
SMS_CODE = {'key': 'sms_code', 'remark': '短信验证码'}

View File

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

View File

@@ -0,0 +1,65 @@
import aioredis
from module_admin.service.dict_service import DictDataService
from module_admin.service.config_service import ConfigService
from config.env import RedisConfig
from config.database import SessionLocal
from utils.log_util import logger
class RedisUtil:
"""
Redis相关方法
"""
@classmethod
async def create_redis_pool(cls) -> aioredis.Redis:
"""
应用启动时初始化redis连接
:return: Redis连接对象
"""
logger.info("开始连接redis...")
redis = await aioredis.from_url(
url=f"redis://{RedisConfig.HOST}",
port=RedisConfig.PORT,
username=RedisConfig.USERNAME,
password=RedisConfig.PASSWORD,
db=RedisConfig.DB,
encoding="utf-8",
decode_responses=True
)
logger.info("redis连接成功")
return redis
@classmethod
async def close_redis_pool(cls, app):
"""
应用关闭时关闭redis连接
:param app: fastapi对象
:return:
"""
await app.state.redis.close()
logger.info("关闭redis连接成功")
@classmethod
async def init_sys_dict(cls, redis):
"""
应用启动时缓存字典表
:param redis: redis对象
:return:
"""
session = SessionLocal()
await DictDataService.init_cache_sys_dict_services(session, redis)
session.close()
@classmethod
async def init_sys_config(cls, redis):
"""
应用启动时缓存参数配置表
:param redis: redis对象
:return:
"""
session = SessionLocal()
await ConfigService.init_cache_sys_config_services(session, redis)
session.close()

View File

@@ -0,0 +1,232 @@
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.jobstores.redis import RedisJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.triggers.cron import CronTrigger
from apscheduler.events import EVENT_ALL
import json
from datetime import datetime, timedelta
from config.database import engine, SQLALCHEMY_DATABASE_URL, SessionLocal
from config.env import RedisConfig
from module_admin.service.job_log_service import JobLogService, JobLogModel
from module_admin.dao.job_dao import Session, JobDao
from utils.log_util import logger
import module_task
# 重写Cron定时
class MyCronTrigger(CronTrigger):
@classmethod
def from_crontab(cls, expr, timezone=None):
values = expr.split()
if len(values) != 6 and len(values) != 7:
raise ValueError('Wrong number of fields; got {}, expected 6 or 7'.format(len(values)))
second = values[0]
minute = values[1]
hour = values[2]
if '?' in values[3]:
day = None
elif 'L' in values[5]:
day = f"last {values[5].replace('L', '')}"
elif 'W' in values[3]:
day = cls.__find_recent_workday(int(values[3].split('W')[0]))
else:
day = values[3].replace('L', 'last')
month = values[4]
if '?' in values[5] or 'L' in values[5]:
week = None
elif '#' in values[5]:
week = int(values[5].split('#')[1])
else:
week = values[5]
if '#' in values[5]:
day_of_week = int(values[5].split('#')[0]) - 1
else:
day_of_week = None
year = values[6] if len(values) == 7 else None
return cls(second=second, minute=minute, hour=hour, day=day, month=month, week=week,
day_of_week=day_of_week, year=year, timezone=timezone)
@classmethod
def __find_recent_workday(cls, day):
now = datetime.now()
date = datetime(now.year, now.month, day)
if date.weekday() < 5:
return date.day
else:
diff = 1
while True:
previous_day = date - timedelta(days=diff)
if previous_day.weekday() < 5:
return previous_day.day
else:
diff += 1
job_stores = {
'default': MemoryJobStore(),
'sqlalchemy': SQLAlchemyJobStore(url=SQLALCHEMY_DATABASE_URL, engine=engine),
'redis': RedisJobStore(
**dict(
host=RedisConfig.HOST,
port=RedisConfig.PORT,
username=RedisConfig.USERNAME,
password=RedisConfig.PASSWORD,
db=RedisConfig.DB
)
)
}
executors = {
'default': ThreadPoolExecutor(20),
'processpool': ProcessPoolExecutor(5)
}
job_defaults = {
'coalesce': False,
'max_instance': 1
}
scheduler = BackgroundScheduler()
scheduler.configure(jobstores=job_stores, executors=executors, job_defaults=job_defaults)
class SchedulerUtil:
"""
定时任务相关方法
"""
@classmethod
async def init_system_scheduler(cls, query_db: Session = SessionLocal()):
"""
应用启动时初始化定时任务
:return:
"""
logger.info("开始启动定时任务...")
scheduler.start()
job_list = JobDao.get_job_list_for_scheduler(query_db)
for item in job_list:
query_job = cls.get_scheduler_job(job_id=str(item.job_id))
if query_job:
cls.remove_scheduler_job(job_id=str(item.job_id))
cls.add_scheduler_job(item)
query_db.close()
scheduler.add_listener(cls.scheduler_event_listener, EVENT_ALL)
logger.info("系统初始定时任务加载成功")
@classmethod
async def close_system_scheduler(cls):
"""
应用关闭时关闭定时任务
:return:
"""
scheduler.shutdown()
logger.info("关闭定时任务成功")
@classmethod
def get_scheduler_job(cls, job_id):
"""
根据任务id获取任务对象
:param job_id: 任务id
:return: 任务对象
"""
query_job = scheduler.get_job(job_id=str(job_id))
return query_job
@classmethod
def add_scheduler_job(cls, job_info):
"""
根据输入的任务对象信息添加任务
:param job_info: 任务对象信息
:return:
"""
scheduler.add_job(
func=eval(job_info.invoke_target),
trigger=MyCronTrigger.from_crontab(job_info.cron_expression),
args=job_info.job_args.split(',') if job_info.job_args else None,
kwargs=json.loads(job_info.job_kwargs) if job_info.job_kwargs else None,
id=str(job_info.job_id),
name=job_info.job_name,
misfire_grace_time=1000000000000 if job_info.misfire_policy == '3' else None,
coalesce=True if job_info.misfire_policy == '2' else False,
max_instances=3 if job_info.concurrent == '0' else 1,
jobstore=job_info.job_group,
executor=job_info.job_executor
)
@classmethod
def execute_scheduler_job_once(cls, job_info):
"""
根据输入的任务对象执行一次任务
:param job_info: 任务对象信息
:return:
"""
scheduler.add_job(
func=eval(job_info.invoke_target),
trigger='date',
run_date=datetime.now() + timedelta(seconds=1),
args=job_info.job_args.split(',') if job_info.job_args else None,
kwargs=json.loads(job_info.job_kwargs) if job_info.job_kwargs else None,
id=str(job_info.job_id),
name=job_info.job_name,
misfire_grace_time=1000000000000 if job_info.misfire_policy == '3' else None,
coalesce=True if job_info.misfire_policy == '2' else False,
max_instances=3 if job_info.concurrent == '0' else 1,
jobstore=job_info.job_group,
executor=job_info.job_executor
)
@classmethod
def remove_scheduler_job(cls, job_id):
"""
根据任务id移除任务
:param job_id: 任务id
:return:
"""
scheduler.remove_job(job_id=str(job_id))
@classmethod
def scheduler_event_listener(cls, event):
# 获取事件类型和任务ID
event_type = event.__class__.__name__
# 获取任务执行异常信息
status = '0'
exception_info = ''
if event_type == 'JobExecutionEvent' and event.exception:
exception_info = str(event.exception)
status = '1'
job_id = event.job_id
query_job = cls.get_scheduler_job(job_id=job_id)
if query_job:
query_job_info = query_job.__getstate__()
# 获取任务名称
job_name = query_job_info.get('name')
# 获取任务组名
job_group = query_job._jobstore_alias
# 获取任务执行器
job_executor = query_job_info.get('executor')
# 获取调用目标字符串
invoke_target = query_job_info.get('func')
# 获取调用函数位置参数
job_args = ','.join(query_job_info.get('args'))
# 获取调用函数关键字参数
job_kwargs = json.dumps(query_job_info.get('kwargs'))
# 获取任务触发器
job_trigger = str(query_job_info.get('trigger'))
# 构造日志消息
job_message = f"事件类型: {event_type}, 任务ID: {job_id}, 任务名称: {job_name}, 执行于{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
job_log = JobLogModel(
jobName=job_name,
jobGroup=job_group,
jobExecutor=job_executor,
invokeTarget=invoke_target,
jobArgs=job_args,
jobKwargs=job_kwargs,
jobTrigger=job_trigger,
jobMessage=job_message,
status=status,
exceptionInfo=exception_info
)
session = SessionLocal()
JobLogService.add_job_log_services(session, job_log)
session.close()

View File

@@ -0,0 +1,172 @@
from functools import wraps
from fastapi import Request
from fastapi.responses import JSONResponse, ORJSONResponse, UJSONResponse
import inspect
import os
import json
import time
from datetime import datetime
import requests
from user_agents import parse
from typing import Optional
from module_admin.service.login_service import LoginService
from module_admin.service.log_service import OperationLogService, LoginLogService
from module_admin.entity.vo.log_vo import OperLogModel, LogininforModel
def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'operation'):
"""
日志装饰器
:param log_type: 日志类型login表示登录日志为空表示为操作日志
:param title: 当前日志装饰器装饰的模块标题
:param business_type: 业务类型0其它 1新增 2修改 3删除 4授权 5导出 6导入 7强退 8生成代码 9清空数据
:return:
"""
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
start_time = time.time()
# 获取被装饰函数的文件路径
file_path = inspect.getfile(func)
# 获取项目根路径
project_root = os.getcwd()
# 处理文件路径,去除项目根路径部分
relative_path = os.path.relpath(file_path, start=project_root)[0:-2].replace('\\', '.')
# 获取当前被装饰函数所在路径
func_path = f'{relative_path}{func.__name__}()'
# 获取上下文信息
request: Request = kwargs.get('request')
token = request.headers.get('Authorization')
query_db = kwargs.get('query_db')
request_method = request.method
operator_type = 0
user_agent = request.headers.get('User-Agent')
if "Windows" in user_agent or "Macintosh" in user_agent or "Linux" in user_agent:
operator_type = 1
if "Mobile" in user_agent or "Android" in user_agent or "iPhone" in user_agent:
operator_type = 2
# 获取请求的url
oper_url = request.url.path
# 获取请求的ip及ip归属区域
oper_ip = request.headers.get("X-Forwarded-For")
oper_location = '内网IP'
try:
if oper_ip != '127.0.0.1' and oper_ip != 'localhost':
ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}')
if ip_result.status_code == 200:
prov = ip_result.json().get('data').get('prov')
city = ip_result.json().get('data').get('city')
if prov or city:
oper_location = f'{prov}-{city}'
else:
oper_location = '未知'
else:
oper_location = '未知'
except Exception as e:
oper_location = '未知'
print(e)
finally:
# 根据不同的请求类型使用不同的方法获取请求参数
content_type = request.headers.get("Content-Type")
if content_type and ("multipart/form-data" in content_type or 'application/x-www-form-urlencoded' in content_type):
payload = await request.form()
oper_param = "\n".join([f"{key}: {value}" for key, value in payload.items()])
else:
payload = await request.body()
# 通过 request.path_params 直接访问路径参数
path_params = request.path_params
oper_param = {}
if payload:
oper_param.update(json.loads(str(payload, 'utf-8')))
if path_params:
oper_param.update(path_params)
oper_param = json.dumps(oper_param, ensure_ascii=False)
# 日志表请求参数字段长度最大为2000因此在此处判断长度
if len(oper_param) > 2000:
oper_param = '请求参数过长'
# 获取操作时间
oper_time = datetime.now()
# 此处在登录之前向原始函数传递一些登录信息,用于监测在线用户的相关信息
login_log = {}
if log_type == 'login':
user_agent_info = parse(user_agent)
browser = f'{user_agent_info.browser.family} {user_agent_info.browser.version[0]}'
system_os = f'{user_agent_info.os.family} {user_agent_info.os.version[0]}'
login_log = dict(
ipaddr=oper_ip,
loginLocation=oper_location,
browser=browser,
os=system_os,
loginTime=oper_time.strftime('%Y-%m-%d %H:%M:%S')
)
kwargs['form_data'].login_info = login_log
# 调用原始函数
result = await func(*args, **kwargs)
# 获取请求耗时
cost_time = float(time.time() - start_time) * 100
# 判断请求是否来自api文档
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
# 根据响应结果的类型使用不同的方法获取响应结果参数
if isinstance(result, JSONResponse) or isinstance(result, ORJSONResponse) or isinstance(result, UJSONResponse):
result_dict = json.loads(str(result.body, 'utf-8'))
else:
if request_from_swagger or request_from_redoc:
result_dict = {}
else:
if result.status_code == 200:
result_dict = {'code': result.status_code, 'message': '获取成功'}
else:
result_dict = {'code': result.status_code, 'message': '获取失败'}
json_result = json.dumps(result_dict, ensure_ascii=False)
# 根据响应结果获取响应状态及异常信息
status = 1
error_msg = ''
if result_dict.get('code') == 200:
status = 0
else:
error_msg = result_dict.get('msg')
# 根据日志类型向对应的日志表插入数据
if log_type == 'login':
# 登录请求来自于api文档时不记录登录日志其余情况则记录
if request_from_swagger or request_from_redoc:
pass
else:
user = kwargs.get('form_data')
user_name = user.username
login_log['loginTime'] = oper_time
login_log['userName'] = user_name
login_log['status'] = str(status)
login_log['msg'] = result_dict.get('msg')
LoginLogService.add_login_log_services(query_db, LogininforModel(**login_log))
else:
current_user = await LoginService.get_current_user(request, token, query_db)
oper_name = current_user.user.user_name
dept_name = current_user.user.dept.dept_name if current_user.user.dept else None
operation_log = OperLogModel(
title=title,
businessType=business_type,
method=func_path,
requestMethod=request_method,
operatorType=operator_type,
operName=oper_name,
deptName=dept_name,
operUrl=oper_url,
operIp=oper_ip,
operLocation=oper_location,
operParam=oper_param,
jsonResult=json_result,
status=status,
errorMsg=error_msg,
operTime=oper_time,
costTime=int(cost_time)
)
OperationLogService.add_operation_log_services(query_db, operation_log)
return result
return wrapper
return decorator

View File

@@ -0,0 +1,82 @@
import inspect
from typing import Type
from fastapi import Query, Form
from pydantic import BaseModel
from pydantic.fields import FieldInfo
def as_query(cls: Type[BaseModel]):
"""
pydantic模型查询参数装饰器将pydantic模型用于接收查询参数
"""
new_parameters = []
for field_name, model_field in cls.model_fields.items():
model_field: FieldInfo # type: ignore
if not model_field.is_required():
new_parameters.append(
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Query(model_field.default),
annotation=model_field.annotation
)
)
else:
new_parameters.append(
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Query(...),
annotation=model_field.annotation
)
)
async def as_query_func(**data):
return cls(**data)
sig = inspect.signature(as_query_func)
sig = sig.replace(parameters=new_parameters)
as_query_func.__signature__ = sig # type: ignore
setattr(cls, 'as_query', as_query_func)
return cls
def as_form(cls: Type[BaseModel]):
"""
pydantic模型表单参数装饰器将pydantic模型用于接收表单参数
"""
new_parameters = []
for field_name, model_field in cls.model_fields.items():
model_field: FieldInfo # type: ignore
if not model_field.is_required():
new_parameters.append(
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Form(model_field.default),
annotation=model_field.annotation
)
)
else:
new_parameters.append(
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Form(...),
annotation=model_field.annotation
)
)
async def as_form_func(**data):
return cls(**data)
sig = inspect.signature(as_form_func)
sig = sig.replace(parameters=new_parameters)
as_form_func.__signature__ = sig # type: ignore
setattr(cls, 'as_form', as_form_func)
return cls

View File

@@ -0,0 +1,37 @@
from fastapi import Depends
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from typing import Optional
class GetDataScope:
"""
获取当前用户数据权限对应的查询sql语句
"""
def __init__(self, query_alias: Optional[str] = '', db_alias: Optional[str] = 'db', user_alias: Optional[str] = 'user_id', dept_alias: Optional[str] = 'dept_id'):
self.query_alias = query_alias
self.db_alias = db_alias
self.user_alias = user_alias
self.dept_alias = dept_alias
def __call__(self, current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
user_id = current_user.user.user_id
dept_id = current_user.user.dept_id
role_datascope_list = [dict(role_id=item.role_id, data_scope=int(item.data_scope)) for item in current_user.user.role]
max_data_scope_dict = min(role_datascope_list, key=lambda x: x['data_scope'])
max_role_id = max_data_scope_dict['role_id']
max_data_scope = max_data_scope_dict['data_scope']
if self.query_alias == '' or max_data_scope == 1 or user_id == 1:
param_sql = '1 == 1'
elif max_data_scope == 2:
param_sql = f"{self.query_alias}.{self.dept_alias}.in_({self.db_alias}.query(SysRoleDept.dept_id).filter(SysRoleDept.role_id == {max_role_id})) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1"
elif max_data_scope == 3:
param_sql = f"{self.query_alias}.{self.dept_alias} == {dept_id} if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1"
elif max_data_scope == 4:
param_sql = f"{self.query_alias}.{self.dept_alias}.in_({self.db_alias}.query(SysDept.dept_id).filter(or_(SysDept.dept_id == {dept_id}, func.find_in_set({dept_id}, SysDept.ancestors)))) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1"
elif max_data_scope == 5:
param_sql = f"{self.query_alias}.{self.user_alias} == {user_id} if hasattr({self.query_alias}, '{self.user_alias}') else 1 == 1"
else:
param_sql = '1 == 0'
return param_sql

View File

@@ -0,0 +1,19 @@
from fastapi import Depends
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from utils.response_util import PermissionException
class CheckUserInterfaceAuth:
"""
校验当前用户是否具有相应的接口权限
"""
def __init__(self, perm_str: str = 'common'):
self.perm_str = perm_str
def __call__(self, current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
user_auth_list = current_user.permissions
user_auth_list.append('common')
if '*:*:*' in user_auth_list or self.perm_str in user_auth_list:
return True
raise PermissionException(data="", message="该用户无此接口权限")

View File

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

View File

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

View File

@@ -0,0 +1,87 @@
from fastapi import APIRouter, Request
from fastapi import Depends, File, Form, Query
from sqlalchemy.orm import Session
from config.env import CachePathConfig
from config.get_db import get_db
from module_admin.service.login_service import LoginService
from module_admin.service.common_service import *
from module_admin.service.config_service import ConfigService
from utils.response_util import *
from utils.log_util import *
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from typing import Optional
commonController = APIRouter(prefix='/common')
@commonController.post("/upload", dependencies=[Depends(LoginService.get_current_user), Depends(CheckUserInterfaceAuth('common'))])
async def common_upload(request: Request, taskPath: str = Form(), uploadId: str = Form(), file: UploadFile = File(...)):
try:
try:
os.makedirs(os.path.join(CachePathConfig.PATH, taskPath, uploadId))
except FileExistsError:
pass
CommonService.upload_service(CachePathConfig.PATH, taskPath, uploadId, file)
logger.info('上传成功')
return response_200(data={'filename': file.filename, 'path': f'/common/{CachePathConfig.PATHSTR}?taskPath={taskPath}&taskId={uploadId}&filename={file.filename}'}, message="上传成功")
except Exception as e:
logger.exception(e)
return response_500(data="", message=str(e))
@commonController.post("/uploadForEditor", dependencies=[Depends(LoginService.get_current_user), Depends(CheckUserInterfaceAuth('common'))])
async def editor_upload(request: Request, baseUrl: str = Form(), uploadId: str = Form(), taskPath: str = Form(), file: UploadFile = File(...)):
try:
try:
os.makedirs(os.path.join(CachePathConfig.PATH, taskPath, uploadId))
except FileExistsError:
pass
CommonService.upload_service(CachePathConfig.PATH, taskPath, uploadId, file)
logger.info('上传成功')
return JSONResponse(
status_code=status.HTTP_200_OK,
content=jsonable_encoder(
{
'errno': 0,
'data': {
'url': f'{baseUrl}/common/{CachePathConfig.PATHSTR}?taskPath={taskPath}&taskId={uploadId}&filename={file.filename}'
},
}
)
)
except Exception as e:
logger.exception(e)
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=jsonable_encoder(
{
'errno': 1,
'message': str(e),
}
)
)
@commonController.get(f"/{CachePathConfig.PATHSTR}")
async def common_download(request: Request, task_path: str = Query(alias='taskPath'), task_id: str = Query(alias='taskId'), filename: str = Query()):
try:
def generate_file():
with open(os.path.join(CachePathConfig.PATH, task_path, task_id, filename), 'rb') as response_file:
yield from response_file
return streaming_response_200(data=generate_file())
except Exception as e:
logger.exception(e)
return response_500(data="", message=str(e))
@commonController.get("/config/query/{config_key}")
async def query_system_config(request: Request, config_key: str):
try:
# 获取全量数据
config_query_result = await ConfigService.query_config_list_from_cache_services(request.app.state.redis, config_key)
logger.info('获取成功')
return response_200(data=config_query_result, message="获取成功")
except Exception as e:
logger.exception(e)
return response_500(data="", message=str(e))

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,207 @@
from fastapi import APIRouter
from fastapi import Depends
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.job_service import *
from module_admin.service.job_log_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from utils.common_util import bytes2file_response
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
jobController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)])
@jobController.get("/job/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))])
async def get_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
job_query = JobModel(**job_page_query.model_dump(by_alias=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('获取成功')
return ResponseUtil.success(model_content=notice_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.post("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))])
@log_decorator(title='定时任务管理', business_type=1)
async def add_system_job(request: Request, add_job: JobModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_job.create_by = current_user.user.user_name
add_job.update_by = current_user.user.user_name
add_job_result = JobService.add_job_services(query_db, add_job)
if add_job_result.is_success:
logger.info(add_job_result.message)
return ResponseUtil.success(msg=add_job_result.message)
else:
logger.warning(add_job_result.message)
return ResponseUtil.failure(msg=add_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.put("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))])
@log_decorator(title='定时任务管理', business_type=2)
async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_job.update_by = current_user.user.user_name
edit_job.update_time = datetime.now()
edit_job_result = JobService.edit_job_services(query_db, edit_job)
if edit_job_result.is_success:
logger.info(edit_job_result.message)
return ResponseUtil.success(msg=edit_job_result.message)
else:
logger.warning(edit_job_result.message)
return ResponseUtil.failure(msg=edit_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.put("/job/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))])
@log_decorator(title='定时任务管理', business_type=2)
async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_job.update_by = current_user.user.user_name
edit_job.update_time = datetime.now()
edit_job.type = 'status'
edit_job_result = JobService.edit_job_services(query_db, edit_job)
if edit_job_result.is_success:
logger.info(edit_job_result.message)
return ResponseUtil.success(msg=edit_job_result.message)
else:
logger.warning(edit_job_result.message)
return ResponseUtil.failure(msg=edit_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.put("/job/run", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))])
@log_decorator(title='定时任务管理', business_type=2)
async def execute_system_job(request: Request, execute_job: JobModel, query_db: Session = Depends(get_db)):
try:
execute_job_result = JobService.execute_job_once_services(query_db, execute_job)
if execute_job_result.is_success:
logger.info(execute_job_result.message)
return ResponseUtil.success(msg=execute_job_result.message)
else:
logger.warning(execute_job_result.message)
return ResponseUtil.failure(msg=execute_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.delete("/job/{job_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务管理', business_type=3)
async def delete_system_job(request: Request, job_ids: str, query_db: Session = Depends(get_db)):
try:
delete_job = DeleteJobModel(jobIds=job_ids)
delete_job_result = JobService.delete_job_services(query_db, delete_job)
if delete_job_result.is_success:
logger.info(delete_job_result.message)
return ResponseUtil.success(msg=delete_job_result.message)
else:
logger.warning(delete_job_result.message)
return ResponseUtil.failure(msg=delete_job_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.get("/job/{job_id}", response_model=JobModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))])
async def query_detail_system_job(request: Request, job_id: int, query_db: Session = Depends(get_db)):
try:
job_detail_result = JobService.job_detail_services(query_db, job_id)
logger.info(f'获取job_id为{job_id}的信息成功')
return ResponseUtil.success(data=job_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.post("/job/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@log_decorator(title='定时任务管理', business_type=5)
async def export_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
job_query = JobModel(**job_page_query.model_dump(by_alias=True))
# 获取全量数据
job_query_result = JobService.get_job_list_services(query_db, job_query)
job_export_result = await JobService.export_job_list_services(request, job_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(job_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.get("/jobLog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))])
async def get_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
job_log_query = JobLogQueryModel(**job_log_page_query.model_dump(by_alias=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('获取成功')
return ResponseUtil.success(model_content=notice_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.delete("/jobLog/{job_log_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务日志管理', business_type=3)
async def delete_system_job_log(request: Request, job_log_ids: str, query_db: Session = Depends(get_db)):
try:
delete_job_log = DeleteJobLogModel(jobLogIds=job_log_ids)
delete_job_log_result = JobLogService.delete_job_log_services(query_db, delete_job_log)
if delete_job_log_result.is_success:
logger.info(delete_job_log_result.message)
return ResponseUtil.success(msg=delete_job_log_result.message)
else:
logger.warning(delete_job_log_result.message)
return ResponseUtil.failure(msg=delete_job_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.post("/jobLog/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务日志管理', business_type=9)
async def clear_system_job_log(request: Request, query_db: Session = Depends(get_db)):
try:
clear_job_log_result = JobLogService.clear_job_log_services(query_db)
if clear_job_log_result.is_success:
logger.info(clear_job_log_result.message)
return ResponseUtil.success(msg=clear_job_log_result.message)
else:
logger.warning(clear_job_log_result.message)
return ResponseUtil.failure(msg=clear_job_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@jobController.post("/jobLog/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@log_decorator(title='定时任务日志管理', business_type=5)
async def export_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
job_log_query = 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_export_result = JobLogService.export_job_log_list_services(query_db, job_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))

View File

@@ -0,0 +1,157 @@
from fastapi import APIRouter
from fastapi import Depends
from config.get_db import get_db
from module_admin.service.login_service import LoginService
from module_admin.service.log_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from utils.common_util import bytes2file_response
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
logController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)])
@logController.get("/operlog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:list'))])
async def get_system_operation_log_list(request: Request, operation_log_page_query: OperLogPageQueryModel = Depends(OperLogPageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
operation_log_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_page_query_result = get_page_obj(operation_log_query_result, operation_log_page_query.page_num, operation_log_page_query.page_size)
logger.info('获取成功')
return ResponseUtil.success(model_content=operation_log_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete("/operlog/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))])
@log_decorator(title='操作日志管理', business_type=9)
async def clear_system_operation_log(request: Request, query_db: Session = Depends(get_db)):
try:
clear_operation_log_result = OperationLogService.clear_operation_log_services(query_db)
if clear_operation_log_result.is_success:
logger.info(clear_operation_log_result.message)
return ResponseUtil.success(msg=clear_operation_log_result.message)
else:
logger.warning(clear_operation_log_result.message)
return ResponseUtil.failure(msg=clear_operation_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete("/operlog/{oper_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))])
@log_decorator(title='操作日志管理', business_type=3)
async def delete_system_operation_log(request: Request, oper_ids: str, query_db: Session = Depends(get_db)):
try:
delete_operation_log = DeleteOperLogModel(operIds=oper_ids)
delete_operation_log_result = OperationLogService.delete_operation_log_services(query_db, delete_operation_log)
if delete_operation_log_result.is_success:
logger.info(delete_operation_log_result.message)
return ResponseUtil.success(msg=delete_operation_log_result.message)
else:
logger.warning(delete_operation_log_result.message)
return ResponseUtil.failure(msg=delete_operation_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.post("/operlog/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:export'))])
@log_decorator(title='操作日志管理', business_type=5)
async def export_system_operation_log_list(request: Request, operation_log_page_query: OperLogPageQueryModel = Depends(OperLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
operation_log_query = 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_export_result = await OperationLogService.export_operation_log_list_services(request, operation_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(operation_log_export_result))
except Exception as e:
logger.exception(e)
return response_500(data="", message=str(e))
@logController.get("/logininfor/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:list'))])
async def get_system_login_log_list(request: Request, login_log_page_query: LoginLogPageQueryModel = Depends(LoginLogPageQueryModel.as_query), query_db: Session = Depends(get_db)):
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_page_query_result = get_page_obj(login_log_query_result, login_log_page_query.page_num, login_log_page_query.page_size)
logger.info('获取成功')
return ResponseUtil.success(model_content=login_log_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete("/logininfor/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))])
@log_decorator(title='登录日志管理', business_type=9)
async def clear_system_login_log(request: Request, query_db: Session = Depends(get_db)):
try:
clear_login_log_result = LoginLogService.clear_login_log_services(query_db)
if clear_login_log_result.is_success:
logger.info(clear_login_log_result.message)
return ResponseUtil.success(msg=clear_login_log_result.message)
else:
logger.warning(clear_login_log_result.message)
return ResponseUtil.failure(msg=clear_login_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.delete("/logininfor/{info_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))])
@log_decorator(title='登录日志管理', business_type=3)
async def delete_system_login_log(request: Request, info_ids: str, query_db: Session = Depends(get_db)):
try:
delete_login_log = DeleteLoginLogModel(infoIds=info_ids)
delete_login_log_result = LoginLogService.delete_login_log_services(query_db, delete_login_log)
if delete_login_log_result.is_success:
logger.info(delete_login_log_result.message)
return ResponseUtil.success(msg=delete_login_log_result.message)
else:
logger.warning(delete_login_log_result.message)
return ResponseUtil.failure(msg=delete_login_log_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.get("/logininfor/unlock/{user_name}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:unlock'))])
@log_decorator(title='登录日志管理', business_type=0)
async def clear_system_login_log(request: Request, user_name: str, query_db: Session = Depends(get_db)):
try:
unlock_user = UnlockUser(userName=user_name)
unlock_user_result = await LoginLogService.unlock_user_services(request, unlock_user)
if unlock_user_result.is_success:
logger.info(unlock_user_result.message)
return ResponseUtil.success(msg=unlock_user_result.message)
else:
logger.warning(unlock_user_result.message)
return ResponseUtil.failure(msg=unlock_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@logController.post("/logininfor/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:export'))])
@log_decorator(title='登录日志管理', business_type=5)
async def export_system_login_log_list(request: Request, login_log_page_query: LoginLogPageQueryModel = Depends(LoginLogPageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
login_log_query = 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_export_result = LoginLogService.export_login_log_list_services(login_log_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(login_log_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))

View File

@@ -0,0 +1,125 @@
from fastapi import APIRouter
from module_admin.service.login_service import *
from module_admin.entity.vo.login_vo import *
from module_admin.dao.login_dao import *
from 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 datetime import timedelta
loginController = APIRouter()
@loginController.post("/login", response_model=Token)
@log_decorator(title='用户登录', business_type=0, log_type='login')
async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = Depends(), query_db: Session = Depends(get_db)):
captcha_enabled = True if await request.app.state.redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.captchaEnabled") == 'true' else False
user = UserLogin(
userName=form_data.username,
password=form_data.password,
code=form_data.code,
uuid=form_data.uuid,
loginInfo=form_data.login_info,
captchaEnabled=captcha_enabled
)
try:
result = await LoginService.authenticate_user(request, query_db, user)
except LoginException as e:
return ResponseUtil.failure(msg=e.message)
try:
access_token_expires = timedelta(minutes=JwtConfig.ACCESS_TOKEN_EXPIRE_MINUTES)
session_id = str(uuid.uuid4())
access_token = LoginService.create_access_token(
data={
"user_id": str(result[0].user_id),
"user_name": result[0].user_name,
"dept_name": result[1].dept_name if result[1] else None,
"session_id": session_id,
"login_info": user.login_info
},
expires_delta=access_token_expires
)
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", access_token,
ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES))
# 此方法可实现同一账号同一时间只能登录一次
# await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{result[0].user_id}", access_token,
# ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES))
logger.info('登录成功')
# 判断请求是否来自于api文档如果是返回指定格式的结果用于修复api文档认证成功后token显示undefined的bug
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False
if request_from_swagger or request_from_redoc:
return {'access_token': access_token, 'token_type': 'Bearer'}
return ResponseUtil.success(
msg='登录成功',
dict_content={'token': access_token}
)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@loginController.get("/getInfo", response_model=CurrentUserModel)
async def get_login_user_info(request: Request, current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
logger.info('获取成功')
return ResponseUtil.success(model_content=current_user)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@loginController.get("/getRouters")
async def get_login_user_routers(request: Request, current_user: CurrentUserModel = Depends(LoginService.get_current_user), query_db: Session = Depends(get_db)):
try:
logger.info('获取成功')
user_routers = await LoginService.get_current_user_routers(current_user.user.user_id, query_db)
return ResponseUtil.success(data=user_routers)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@loginController.post("/getSmsCode", response_model=SmsCode)
async def get_sms_code(request: Request, user: ResetUserModel, query_db: Session = Depends(get_db)):
try:
sms_result = await get_sms_code_services(request, query_db, user)
if sms_result.is_success:
logger.info('获取成功')
return response_200(data=sms_result, message='获取成功')
else:
logger.warning(sms_result.message)
return response_400(data='', message=sms_result.message)
except Exception as e:
logger.exception(e)
return response_500(data="", message=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 forget_user_services(request, query_db, forget_user)
if forget_user_result.is_success:
logger.info(forget_user_result.message)
return response_200(data=forget_user_result, message=forget_user_result.message)
else:
logger.warning(forget_user_result.message)
return response_400(data="", message=forget_user_result.message)
except Exception as e:
logger.exception(e)
return response_500(data="", message=str(e))
@loginController.post("/logout")
async def logout(request: Request, token: Optional[str] = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM])
session_id: str = payload.get("session_id")
await logout_services(request, session_id)
logger.info('退出成功')
return ResponseUtil.success(msg="退出成功")
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))

View File

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

View File

@@ -0,0 +1,92 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.notice_service import *
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator
noticeController = APIRouter(prefix='/system/notice', dependencies=[Depends(LoginService.get_current_user)])
@noticeController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:list'))])
async def get_system_notice_list(request: Request, notice_page_query: NoticePageQueryModel = Depends(NoticePageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
notice_query = NoticeQueryModel(**notice_page_query.model_dump(by_alias=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('获取成功')
return ResponseUtil.success(model_content=notice_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:notice:add'))])
@log_decorator(title='通知公告管理', business_type=1)
async def add_system_notice(request: Request, add_notice: NoticeModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_notice.create_by = current_user.user.user_name
add_notice.update_by = current_user.user.user_name
add_notice_result = NoticeService.add_notice_services(query_db, add_notice)
if add_notice_result.is_success:
logger.info(add_notice_result.message)
return ResponseUtil.success(msg=add_notice_result.message)
else:
logger.warning(add_notice_result.message)
return ResponseUtil.failure(msg=add_notice_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:notice:edit'))])
@log_decorator(title='通知公告管理', business_type=2)
async def edit_system_notice(request: Request, edit_notice: NoticeModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_notice.update_by = current_user.user.user_name
edit_notice.update_time = datetime.now()
edit_notice_result = NoticeService.edit_notice_services(query_db, edit_notice)
if edit_notice_result.is_success:
logger.info(edit_notice_result.message)
return ResponseUtil.success(msg=edit_notice_result.message)
else:
logger.warning(edit_notice_result.message)
return ResponseUtil.failure(msg=edit_notice_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.delete("/{notice_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:notice:remove'))])
@log_decorator(title='通知公告管理', business_type=3)
async def delete_system_notice(request: Request, notice_ids: str, query_db: Session = Depends(get_db)):
try:
delete_notice = DeleteNoticeModel(noticeIds=notice_ids)
delete_notice_result = NoticeService.delete_notice_services(query_db, delete_notice)
if delete_notice_result.is_success:
logger.info(delete_notice_result.message)
return ResponseUtil.success(msg=delete_notice_result.message)
else:
logger.warning(delete_notice_result.message)
return ResponseUtil.failure(msg=delete_notice_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@noticeController.get("/{notice_id}", response_model=NoticeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:query'))])
async def query_detail_system_post(request: Request, notice_id: int, query_db: Session = Depends(get_db)):
try:
notice_detail_result = NoticeService.notice_detail_services(query_db, notice_id)
logger.info(f'获取notice_id为{notice_id}的信息成功')
return ResponseUtil.success(data=notice_detail_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))

View File

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

View File

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

View File

@@ -0,0 +1,240 @@
from fastapi import APIRouter, Request
from fastapi import Depends
from config.get_db import get_db
from module_admin.service.login_service import LoginService, CurrentUserModel
from module_admin.service.role_service import *
from module_admin.service.dept_service import DeptService, DeptModel
from module_admin.service.user_service import UserService, UserRoleQueryModel, UserRolePageQueryModel, CrudUserRoleModel
from utils.response_util import *
from utils.log_util import *
from utils.page_util import *
from utils.common_util import bytes2file_response
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.aspect.data_scope import GetDataScope
from module_admin.annotation.log_annotation import log_decorator
roleController = APIRouter(prefix='/system/role', dependencies=[Depends(LoginService.get_current_user)])
@roleController.get("/deptTree/{role_id}", dependencies=[Depends(CheckUserInterfaceAuth('common'))])
async def get_system_role_dept_tree(request: Request, role_id: int, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))):
try:
dept_query_result = DeptService.get_dept_tree_services(query_db, DeptModel(**{}), data_scope_sql)
role_dept_query_result = RoleService.get_role_dept_tree_services(query_db, role_id)
role_dept_query_result.depts = dept_query_result
logger.info('获取成功')
return ResponseUtil.success(model_content=role_dept_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))])
async def get_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
role_query = RoleQueryModel(**role_page_query.model_dump(by_alias=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('获取成功')
return ResponseUtil.success(model_content=role_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:role:add'))])
@log_decorator(title='角色管理', business_type=1)
async def add_system_role(request: Request, add_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_role.create_by = current_user.user.user_name
add_role.update_by = current_user.user.user_name
add_role_result = RoleService.add_role_services(query_db, add_role)
if add_role_result.is_success:
logger.info(add_role_result.message)
return ResponseUtil.success(msg=add_role_result.message)
else:
logger.warning(add_role_result.message)
return ResponseUtil.failure(msg=add_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=2)
async def edit_system_role(request: Request, edit_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_role.update_by = current_user.user.user_name
edit_role.update_time = datetime.now()
edit_role_result = RoleService.edit_role_services(query_db, edit_role)
if edit_role_result.is_success:
logger.info(edit_role_result.message)
return ResponseUtil.success(msg=edit_role_result.message)
else:
logger.warning(edit_role_result.message)
return ResponseUtil.failure(msg=edit_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put("/dataScope", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def edit_system_role_datascope(request: Request, role_data_scope: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
role_data_scope.update_by = current_user.user.user_name
role_data_scope.update_time = datetime.now()
role_data_scope_result = RoleService.role_datascope_services(query_db, role_data_scope)
if role_data_scope_result.is_success:
logger.info(role_data_scope_result.message)
return ResponseUtil.success(msg=role_data_scope_result.message)
else:
logger.warning(role_data_scope_result.message)
return ResponseUtil.failure(msg=role_data_scope_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.delete("/{role_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:role:remove'))])
@log_decorator(title='角色管理', business_type=3)
async def delete_system_role(request: Request, role_ids: str, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
delete_role = DeleteRoleModel(
roleIds=role_ids,
updateBy=current_user.user.user_name,
updateTime=datetime.now()
)
delete_role_result = RoleService.delete_role_services(query_db, delete_role)
if delete_role_result.is_success:
logger.info(delete_role_result.message)
return ResponseUtil.success(msg=delete_role_result.message)
else:
logger.warning(delete_role_result.message)
return ResponseUtil.failure(msg=delete_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.get("/{role_id}", response_model=RoleModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:query'))])
async def query_detail_system_role(request: Request, role_id: int, query_db: Session = Depends(get_db)):
try:
role_detail_result = RoleService.role_detail_services(query_db, role_id)
logger.info(f'获取role_id为{role_id}的信息成功')
return ResponseUtil.success(data=role_detail_result.model_dump(by_alias=True))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:role:export'))])
@log_decorator(title='角色管理', business_type=5)
async def export_system_role_list(request: Request, role_page_query: RolePageQueryModel = Depends(RolePageQueryModel.as_form), query_db: Session = Depends(get_db)):
try:
role_query = RoleQueryModel(**role_page_query.model_dump(by_alias=True))
# 获取全量数据
role_query_result = RoleService.get_role_list_services(query_db, role_query)
role_export_result = RoleService.export_role_list_services(role_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(role_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put("/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=2)
async def reset_system_role_status(request: Request, edit_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_role.update_by = current_user.user.user_name
edit_role.update_time = datetime.now()
edit_role.type = 'status'
edit_role_result = RoleService.edit_role_services(query_db, edit_role)
if edit_role_result.is_success:
logger.info(edit_role_result.message)
return ResponseUtil.success(msg=edit_role_result.message)
else:
logger.warning(edit_role_result.message)
return ResponseUtil.failure(msg=edit_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.get("/authUser/allocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))])
async def get_system_allocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
role_user_query = UserRoleQueryModel(**user_role.model_dump(by_alias=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('获取成功')
return ResponseUtil.success(model_content=role_user_allocated_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.get("/authUser/unallocatedList", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))])
async def get_system_unallocated_user_list(request: Request, user_role: UserRolePageQueryModel = Depends(UserRolePageQueryModel.as_query), query_db: Session = Depends(get_db)):
try:
role_user_query = UserRoleQueryModel(**user_role.model_dump(by_alias=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('获取成功')
return ResponseUtil.success(model_content=role_user_unallocated_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put("/authUser/selectAll", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def add_system_role_user(request: Request, add_role_user: CrudUserRoleModel = Depends(CrudUserRoleModel.as_query), query_db: Session = Depends(get_db)):
try:
add_role_user_result = UserService.add_user_role_services(query_db, add_role_user)
if add_role_user_result.is_success:
logger.info(add_role_user_result.message)
return ResponseUtil.success(msg=add_role_user_result.message)
else:
logger.warning(add_role_user_result.message)
return ResponseUtil.failure(msg=add_role_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put("/authUser/cancel", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def cancel_system_role_user(request: Request, cancel_user_role: CrudUserRoleModel, query_db: Session = Depends(get_db)):
try:
cancel_user_role_result = UserService.delete_user_role_services(query_db, cancel_user_role)
if cancel_user_role_result.is_success:
logger.info(cancel_user_role_result.message)
return ResponseUtil.success(msg=cancel_user_role_result.message)
else:
logger.warning(cancel_user_role_result.message)
return ResponseUtil.failure(msg=cancel_user_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@roleController.put("/authUser/cancelAll", dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))])
@log_decorator(title='角色管理', business_type=4)
async def batch_cancel_system_role_user(request: Request, batch_cancel_user_role: CrudUserRoleModel = Depends(CrudUserRoleModel.as_query), query_db: Session = Depends(get_db)):
try:
batch_cancel_user_role_result = UserService.delete_user_role_services(query_db, batch_cancel_user_role)
if batch_cancel_user_role_result.is_success:
logger.info(batch_cancel_user_role_result.message)
return ResponseUtil.success(msg=batch_cancel_user_role_result.message)
else:
logger.warning(batch_cancel_user_role_result.message)
return ResponseUtil.failure(msg=batch_cancel_user_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))

View File

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

View File

@@ -0,0 +1,307 @@
from fastapi import APIRouter, Request
from fastapi import Depends, File, Query
from config.get_db import get_db
from module_admin.service.login_service import LoginService
from module_admin.service.user_service import *
from module_admin.service.dept_service import DeptService
from utils.page_util import *
from utils.response_util import *
from utils.log_util import *
from utils.common_util import bytes2file_response
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.aspect.data_scope import GetDataScope
from module_admin.annotation.log_annotation import log_decorator
userController = APIRouter(prefix='/system/user', dependencies=[Depends(LoginService.get_current_user)])
@userController.get("/deptTree", dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))])
async def get_system_dept_tree(request: Request, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))):
try:
dept_query_result = DeptService.get_dept_tree_services(query_db, DeptModel(**{}), data_scope_sql)
logger.info('获取成功')
return ResponseUtil.success(data=dept_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.get("/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))])
async def get_system_user_list(request: Request, user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_query), query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))):
try:
user_query = UserQueryModel(**user_page_query.model_dump(by_alias=True))
# 获取全量数据
user_query_result = UserService.get_user_list_services(query_db, user_query, data_scope_sql)
# 分页操作
user_page_query_result = get_page_obj(user_query_result, user_page_query.page_num, user_page_query.page_size)
logger.info('获取成功')
return ResponseUtil.success(model_content=user_page_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.post("", dependencies=[Depends(CheckUserInterfaceAuth('system:user:add'))])
@log_decorator(title='用户管理', business_type=1)
async def add_system_user(request: Request, add_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
add_user.password = PwdUtil.get_password_hash(add_user.password)
add_user.create_by = current_user.user.user_name
add_user.update_by = current_user.user.user_name
add_user_result = UserService.add_user_services(query_db, add_user)
if add_user_result.is_success:
logger.info(add_user_result.message)
return ResponseUtil.success(msg=add_user_result.message)
else:
logger.warning(add_user_result.message)
return ResponseUtil.failure(msg=add_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put("", dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
@log_decorator(title='用户管理', business_type=2)
async def edit_system_user(request: Request, edit_user: EditUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.delete("/{user_ids}", dependencies=[Depends(CheckUserInterfaceAuth('system:user:remove'))])
@log_decorator(title='用户管理', business_type=3)
async def delete_system_user(request: Request, user_ids: str, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
delete_user = DeleteUserModel(
userIds=user_ids,
updateBy=current_user.user.user_name,
updateTime=datetime.now()
)
delete_user_result = UserService.delete_user_services(query_db, delete_user)
if delete_user_result.is_success:
logger.info(delete_user_result.message)
return ResponseUtil.success(msg=delete_user_result.message)
else:
logger.warning(delete_user_result.message)
return ResponseUtil.failure(msg=delete_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put("/resetPwd", dependencies=[Depends(CheckUserInterfaceAuth('system:user:resetPwd'))])
@log_decorator(title='用户管理', business_type=2)
async def reset_system_user_pwd(request: Request, edit_user: EditUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user.password = PwdUtil.get_password_hash(edit_user.password)
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
edit_user.type = 'pwd'
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put("/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
@log_decorator(title='用户管理', business_type=2)
async def change_system_user_status(request: Request, edit_user: EditUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
edit_user.type = 'status'
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.get("/profile", response_model=UserProfileModel)
async def query_detail_system_user(request: Request, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
profile_user_result = UserService.user_profile_services(query_db, current_user.user.user_id)
logger.info(f'获取user_id为{current_user.user.user_id}的信息成功')
return ResponseUtil.success(model_content=profile_user_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.get("/{user_id}", response_model=UserDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))])
@userController.get("/", response_model=UserDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))])
async def query_detail_system_user(request: Request, user_id: Optional[Union[int, str]] = '', query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
detail_user_result = UserService.user_detail_services(query_db, user_id)
logger.info(f'获取user_id为{user_id}的信息成功')
return ResponseUtil.success(model_content=detail_user_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.post("/profile/avatar")
@log_decorator(title='个人信息', business_type=2)
async def change_system_user_profile_avatar(request: Request, avatarfile: bytes = File(), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
dir_path = os.path.join(CachePathConfig.PATH, 'profile', 'avatar')
try:
os.makedirs(dir_path)
except FileExistsError:
pass
avatar_name = f'blob_{datetime.now().strftime("%Y%m%d%H%M%S")}.jpeg'
avatar_path = os.path.join(dir_path, avatar_name)
with open(avatar_path, 'wb') as f:
f.write(avatarfile)
edit_user = EditUserModel(
userId=current_user.user.user_id,
avatar=f'/common/{CachePathConfig.PATHSTR}?taskPath=profile&taskId=avatar&filename={avatar_name}',
updateBy=current_user.user.user_name,
updateTime=datetime.now(),
type='avatar'
)
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(dict_content={'imgUrl': edit_user.avatar}, msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put("/profile")
@log_decorator(title='个人信息', business_type=2)
async def change_system_user_profile_info(request: Request, user_info: UserInfoModel, query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
edit_user = EditUserModel(**user_info.model_dump(by_alias=True, exclude={'role_ids', 'post_ids'}), roleIds=user_info.role_ids.split(','), postIds=user_info.post_ids.split(','))
edit_user.user_id = current_user.user.user_id
edit_user.update_by = current_user.user.user_name
edit_user.update_time = datetime.now()
print(edit_user.model_dump())
edit_user_result = UserService.edit_user_services(query_db, edit_user)
if edit_user_result.is_success:
logger.info(edit_user_result.message)
return ResponseUtil.success(msg=edit_user_result.message)
else:
logger.warning(edit_user_result.message)
return ResponseUtil.failure(msg=edit_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put("/profile/updatePwd")
@log_decorator(title='个人信息', business_type=2)
async def reset_system_user_password(request: Request, old_password: str = Query(alias='oldPassword'), new_password: str = Query(alias='newPassword'), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
reset_user = ResetUserModel(
userId=current_user.user.user_id,
oldPassword=old_password,
password=PwdUtil.get_password_hash(new_password),
updateBy=current_user.user.user_name,
updateTime=datetime.now()
)
reset_user_result = UserService.reset_user_services(query_db, reset_user)
if reset_user_result.is_success:
logger.info(reset_user_result.message)
return ResponseUtil.success(msg=reset_user_result.message)
else:
logger.warning(reset_user_result.message)
return ResponseUtil.failure(msg=reset_user_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.post("/importData", dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))])
@log_decorator(title='用户管理', business_type=6)
async def batch_import_system_user(request: Request, file: UploadFile = File(...), update_support: bool = Query(alias='updateSupport'), query_db: Session = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
try:
batch_import_result = await UserService.batch_import_user_services(query_db, file, update_support, current_user)
if batch_import_result.is_success:
logger.info(batch_import_result.message)
return ResponseUtil.success(msg=batch_import_result.message)
else:
logger.warning(batch_import_result.message)
return ResponseUtil.failure(msg=batch_import_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.post("/importTemplate", dependencies=[Depends(CheckUserInterfaceAuth('system:user:import'))])
async def export_system_user_template(request: Request, query_db: Session = Depends(get_db)):
try:
user_import_template_result = UserService.get_user_import_template_services()
logger.info('获取成功')
return ResponseUtil.streaming(data=bytes2file_response(user_import_template_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.post("/export", dependencies=[Depends(CheckUserInterfaceAuth('system:user:export'))])
@log_decorator(title='用户管理', business_type=5)
async def export_system_user_list(request: Request, user_page_query: UserPageQueryModel = Depends(UserPageQueryModel.as_form), query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysUser'))):
try:
user_query = 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_export_result = UserService.export_user_list_services(user_query_result)
logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(user_export_result))
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.get("/authRole/{user_id}", response_model=UserRoleResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))])
async def get_system_allocated_role_list(request: Request, user_id: int, query_db: Session = Depends(get_db)):
try:
user_role_query = UserRoleQueryModel(userId=user_id)
user_role_allocated_query_result = UserService.get_user_role_allocated_list_services(query_db, user_role_query)
logger.info('获取成功')
return ResponseUtil.success(model_content=user_role_allocated_query_result)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))
@userController.put("/authRole", response_model=UserRoleResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))])
async def update_system_role_user(request: Request, user_id: int = Query(alias='userId'), role_ids: str = Query(alias='roleIds'), query_db: Session = Depends(get_db)):
try:
add_user_role_result = UserService.add_user_role_services(query_db, CrudUserRoleModel(userId=user_id, roleIds=role_ids))
if add_user_role_result.is_success:
logger.info(add_user_role_result.message)
return ResponseUtil.success(msg=add_user_role_result.message)
else:
logger.warning(add_user_role_result.message)
return ResponseUtil.failure(msg=add_user_role_result.message)
except Exception as e:
logger.exception(e)
return ResponseUtil.error(msg=str(e))

View File

@@ -0,0 +1,98 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.config_do import SysConfig
from module_admin.entity.vo.config_vo import *
from datetime import datetime, time
class ConfigDao:
"""
参数配置管理模块数据库操作层
"""
@classmethod
def get_config_detail_by_id(cls, db: Session, config_id: int):
"""
根据参数配置id获取参数配置详细信息
:param db: orm对象
:param config_id: 参数配置id
:return: 参数配置信息对象
"""
config_info = db.query(SysConfig) \
.filter(SysConfig.config_id == config_id) \
.first()
return config_info
@classmethod
def get_config_detail_by_info(cls, db: Session, config: ConfigModel):
"""
根据参数配置参数获取参数配置信息
:param db: orm对象
:param config: 参数配置参数对象
:return: 参数配置信息对象
"""
config_info = db.query(SysConfig) \
.filter(SysConfig.config_key == config.config_key if config.config_key else True,
SysConfig.config_value == config.config_value if config.config_value else True) \
.first()
return config_info
@classmethod
def get_config_list(cls, db: Session, query_object: ConfigQueryModel):
"""
根据查询参数获取参数配置列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 参数配置列表信息对象
"""
config_list = db.query(SysConfig) \
.filter(SysConfig.config_name.like(f'%{query_object.config_name}%') if query_object.config_name else True,
SysConfig.config_key.like(f'%{query_object.config_key}%') if query_object.config_key else True,
SysConfig.config_type == query_object.config_type if query_object.config_type else True,
SysConfig.create_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True
) \
.distinct().all()
return config_list
@classmethod
def add_config_dao(cls, db: Session, config: ConfigModel):
"""
新增参数配置数据库操作
:param db: orm对象
:param config: 参数配置对象
:return:
"""
db_config = SysConfig(**config.model_dump())
db.add(db_config)
db.flush()
return db_config
@classmethod
def edit_config_dao(cls, db: Session, config: dict):
"""
编辑参数配置数据库操作
:param db: orm对象
:param config: 需要更新的参数配置字典
:return:
"""
db.query(SysConfig) \
.filter(SysConfig.config_id == config.get('config_id')) \
.update(config)
@classmethod
def delete_config_dao(cls, db: Session, config: ConfigModel):
"""
删除参数配置数据库操作
:param db: orm对象
:param config: 参数配置对象
:return:
"""
db.query(SysConfig) \
.filter(SysConfig.config_id == config.config_id) \
.delete()

View File

@@ -0,0 +1,194 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.vo.dept_vo import *
from utils.time_format_util import list_format_datetime
class DeptDao:
"""
部门管理模块数据库操作层
"""
@classmethod
def get_dept_by_id(cls, db: Session, dept_id: int):
"""
根据部门id获取在用部门信息
:param db: orm对象
:param dept_id: 部门id
:return: 在用部门信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.status == 0,
SysDept.del_flag == 0) \
.first()
return dept_info
@classmethod
def get_dept_by_id_for_list(cls, db: Session, dept_id: int):
"""
用于获取部门列表的工具方法
:param db: orm对象
:param dept_id: 部门id
:return: 部门id对应的信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.del_flag == 0) \
.first()
return dept_info
@classmethod
def get_dept_detail_by_id(cls, db: Session, dept_id: int):
"""
根据部门id获取部门详细信息
:param db: orm对象
:param dept_id: 部门id
:return: 部门信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.del_flag == 0) \
.first()
return dept_info
@classmethod
def get_dept_detail_by_info(cls, db: Session, dept: DeptModel):
"""
根据部门参数获取部门信息
:param db: orm对象
:param dept: 部门参数对象
:return: 部门信息对象
"""
dept_info = db.query(SysDept) \
.filter(SysDept.parent_id == dept.parent_id if dept.parent_id else True,
SysDept.dept_name == dept.dept_name if dept.dept_name else True) \
.first()
return dept_info
@classmethod
def get_dept_info_for_edit_option(cls, db: Session, dept_info: DeptModel, data_scope_sql: str):
"""
获取部门编辑对应的在用部门列表信息
:param db: orm对象
:param dept_info: 部门对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门列表信息
"""
dept_result = db.query(SysDept) \
.filter(SysDept.dept_id != dept_info.dept_id,
SysDept.parent_id != dept_info.dept_id,
SysDept.del_flag == 0, SysDept.status == 0,
eval(data_scope_sql)) \
.order_by(SysDept.order_num) \
.distinct().all()
return list_format_datetime(dept_result)
@classmethod
def get_children_dept(cls, db: Session, dept_id: int):
"""
根据部门id查询当前部门的子部门列表信息
:param db: orm对象
:param dept_id: 部门id
:return: 子部门信息列表
"""
dept_result = db.query(SysDept) \
.filter(SysDept.parent_id == dept_id,
SysDept.del_flag == 0) \
.all()
return list_format_datetime(dept_result)
@classmethod
def get_dept_all_ancestors(cls, db: Session):
"""
获取所有部门的ancestors信息
:param db: orm对象
:return: ancestors信息列表
"""
ancestors = db.query(SysDept.ancestors)\
.filter(SysDept.del_flag == 0)\
.all()
return ancestors
@classmethod
def get_dept_list_for_tree(cls, db: Session, dept_info: DeptModel, data_scope_sql: str):
"""
获取所有在用部门列表信息
:param db: orm对象
:param dept_info: 部门对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 在用部门列表信息
"""
dept_result = db.query(SysDept) \
.filter(SysDept.status == 0,
SysDept.del_flag == 0,
SysDept.dept_name.like(f'%{dept_info.dept_name}%') if dept_info.dept_name else True,
eval(data_scope_sql)) \
.order_by(SysDept.order_num) \
.distinct().all()
return dept_result
@classmethod
def get_dept_list(cls, db: Session, page_object: DeptModel, data_scope_sql: str):
"""
根据查询参数获取部门列表信息
:param db: orm对象
:param page_object: 不分页查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门列表信息对象
"""
dept_result = db.query(SysDept) \
.filter(SysDept.del_flag == 0,
SysDept.status == page_object.status if page_object.status else True,
SysDept.dept_name.like(f'%{page_object.dept_name}%') if page_object.dept_name else True,
eval(data_scope_sql)) \
.order_by(SysDept.order_num) \
.distinct().all()
return dept_result
@classmethod
def add_dept_dao(cls, db: Session, dept: DeptModel):
"""
新增部门数据库操作
:param db: orm对象
:param dept: 部门对象
:return: 新增校验结果
"""
db_dept = SysDept(**dept.model_dump())
db.add(db_dept)
db.flush()
return db_dept
@classmethod
def edit_dept_dao(cls, db: Session, dept: dict):
"""
编辑部门数据库操作
:param db: orm对象
:param dept: 需要更新的部门字典
:return: 编辑校验结果
"""
db.query(SysDept) \
.filter(SysDept.dept_id == dept.get('dept_id')) \
.update(dept)
@classmethod
def delete_dept_dao(cls, db: Session, dept: DeptModel):
"""
删除部门数据库操作
:param db: orm对象
:param dept: 部门对象
:return:
"""
db.query(SysDept) \
.filter(SysDept.dept_id == dept.dept_id) \
.update({SysDept.del_flag: '2', SysDept.update_by: dept.update_by, SysDept.update_time: dept.update_time})

View File

@@ -0,0 +1,219 @@
from sqlalchemy import and_
from sqlalchemy.orm import Session
from module_admin.entity.do.dict_do import SysDictType, SysDictData
from module_admin.entity.vo.dict_vo import *
from utils.time_format_util import list_format_datetime
from datetime import datetime, time
class DictTypeDao:
"""
字典类型管理模块数据库操作层
"""
@classmethod
def get_dict_type_detail_by_id(cls, db: Session, dict_id: int):
"""
根据字典类型id获取字典类型详细信息
:param db: orm对象
:param dict_id: 字典类型id
:return: 字典类型信息对象
"""
dict_type_info = db.query(SysDictType) \
.filter(SysDictType.dict_id == dict_id) \
.first()
return dict_type_info
@classmethod
def get_dict_type_detail_by_info(cls, db: Session, dict_type: DictTypeModel):
"""
根据字典类型参数获取字典类型信息
:param db: orm对象
:param dict_type: 字典类型参数对象
:return: 字典类型信息对象
"""
dict_type_info = db.query(SysDictType) \
.filter(SysDictType.dict_type == dict_type.dict_type if dict_type.dict_type else True,
SysDictType.dict_name == dict_type.dict_name if dict_type.dict_name else True) \
.first()
return dict_type_info
@classmethod
def get_all_dict_type(cls, db: Session):
"""
获取所有的字典类型信息
:param db: orm对象
:return: 字典类型信息列表对象
"""
dict_type_info = db.query(SysDictType).all()
return list_format_datetime(dict_type_info)
@classmethod
def get_dict_type_list(cls, db: Session, query_object: DictTypeQueryModel):
"""
根据查询参数获取字典类型列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 字典类型列表信息对象
"""
dict_type_list = db.query(SysDictType) \
.filter(SysDictType.dict_name.like(f'%{query_object.dict_name}%') if query_object.dict_name else True,
SysDictType.dict_type.like(f'%{query_object.dict_type}%') if query_object.dict_type else True,
SysDictType.status == query_object.status if query_object.status else True,
SysDictType.create_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True
) \
.distinct().all()
return dict_type_list
@classmethod
def add_dict_type_dao(cls, db: Session, dict_type: DictTypeModel):
"""
新增字典类型数据库操作
:param db: orm对象
:param dict_type: 字典类型对象
:return:
"""
db_dict_type = SysDictType(**dict_type.dict())
db.add(db_dict_type)
db.flush()
return db_dict_type
@classmethod
def edit_dict_type_dao(cls, db: Session, dict_type: dict):
"""
编辑字典类型数据库操作
:param db: orm对象
:param dict_type: 需要更新的字典类型字典
:return:
"""
db.query(SysDictType) \
.filter(SysDictType.dict_id == dict_type.get('dict_id')) \
.update(dict_type)
@classmethod
def delete_dict_type_dao(cls, db: Session, dict_type: DictTypeModel):
"""
删除字典类型数据库操作
:param db: orm对象
:param dict_type: 字典类型对象
:return:
"""
db.query(SysDictType) \
.filter(SysDictType.dict_id == dict_type.dict_id) \
.delete()
class DictDataDao:
"""
字典数据管理模块数据库操作层
"""
@classmethod
def get_dict_data_detail_by_id(cls, db: Session, dict_code: int):
"""
根据字典数据id获取字典数据详细信息
:param db: orm对象
:param dict_code: 字典数据id
:return: 字典数据信息对象
"""
dict_data_info = db.query(SysDictData) \
.filter(SysDictData.dict_code == dict_code) \
.first()
return dict_data_info
@classmethod
def get_dict_data_detail_by_info(cls, db: Session, dict_data: DictDataModel):
"""
根据字典数据参数获取字典数据信息
:param db: orm对象
:param dict_data: 字典数据参数对象
:return: 字典数据信息对象
"""
dict_data_info = db.query(SysDictData) \
.filter(SysDictData.dict_type == dict_data.dict_type if dict_data.dict_type else True,
SysDictData.dict_label == dict_data.dict_label if dict_data.dict_label else True,
SysDictData.dict_value == dict_data.dict_value if dict_data.dict_value else True) \
.first()
return dict_data_info
@classmethod
def get_dict_data_list(cls, db: Session, query_object: DictDataModel):
"""
根据查询参数获取字典数据列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 字典数据列表信息对象
"""
dict_data_list = db.query(SysDictData) \
.filter(SysDictData.dict_type == query_object.dict_type if query_object.dict_type else True,
SysDictData.dict_label.like(f'%{query_object.dict_label}%') if query_object.dict_label else True,
SysDictData.status == query_object.status if query_object.status else True
) \
.order_by(SysDictData.dict_sort) \
.distinct().all()
return dict_data_list
@classmethod
def query_dict_data_list(cls, db: Session, dict_type: str):
"""
根据查询参数获取字典数据列表信息
:param db: orm对象
:param dict_type: 字典类型
:return: 字典数据列表信息对象
"""
dict_data_list = db.query(SysDictData).select_from(SysDictType) \
.filter(SysDictType.dict_type == dict_type if dict_type else True, SysDictType.status == 0) \
.outerjoin(SysDictData, and_(SysDictType.dict_type == SysDictData.dict_type, SysDictData.status == 0)) \
.order_by(SysDictData.dict_sort) \
.distinct().all()
return dict_data_list
@classmethod
def add_dict_data_dao(cls, db: Session, dict_data: DictDataModel):
"""
新增字典数据数据库操作
:param db: orm对象
:param dict_data: 字典数据对象
:return:
"""
db_data_type = SysDictData(**dict_data.dict())
db.add(db_data_type)
db.flush()
return db_data_type
@classmethod
def edit_dict_data_dao(cls, db: Session, dict_data: dict):
"""
编辑字典数据数据库操作
:param db: orm对象
:param dict_data: 需要更新的字典数据字典
:return:
"""
db.query(SysDictData) \
.filter(SysDictData.dict_code == dict_data.get('dict_code')) \
.update(dict_data)
@classmethod
def delete_dict_data_dao(cls, db: Session, dict_data: DictDataModel):
"""
删除字典数据数据库操作
:param db: orm对象
:param dict_data: 字典数据对象
:return:
"""
db.query(SysDictData) \
.filter(SysDictData.dict_code == dict_data.dict_code) \
.delete()

View File

@@ -0,0 +1,108 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.job_do import SysJob
from module_admin.entity.vo.job_vo import *
class JobDao:
"""
定时任务管理模块数据库操作层
"""
@classmethod
def get_job_detail_by_id(cls, db: Session, job_id: int):
"""
根据定时任务id获取定时任务详细信息
:param db: orm对象
:param job_id: 定时任务id
:return: 定时任务信息对象
"""
job_info = db.query(SysJob) \
.filter(SysJob.job_id == job_id) \
.first()
return job_info
@classmethod
def get_job_detail_by_info(cls, db: Session, job: JobModel):
"""
根据定时任务参数获取定时任务信息
:param db: orm对象
:param job: 定时任务参数对象
:return: 定时任务信息对象
"""
job_info = db.query(SysJob) \
.filter(SysJob.job_name == job.job_name if job.job_name else True,
SysJob.job_group == job.job_group if job.job_group else True,
SysJob.invoke_target == job.invoke_target if job.invoke_target else True,
SysJob.cron_expression == job.cron_expression if job.cron_expression else True) \
.first()
return job_info
@classmethod
def get_job_list(cls, db: Session, query_object: JobModel):
"""
根据查询参数获取定时任务列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 定时任务列表信息对象
"""
job_list = db.query(SysJob) \
.filter(SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJob.job_group == query_object.job_group if query_object.job_group else True,
SysJob.status == query_object.status if query_object.status else True
) \
.distinct().all()
return job_list
@classmethod
def get_job_list_for_scheduler(cls, db: Session):
"""
获取定时任务列表信息
:param db: orm对象
:return: 定时任务列表信息对象
"""
job_list = db.query(SysJob) \
.filter(SysJob.status == 0) \
.distinct().all()
return job_list
@classmethod
def add_job_dao(cls, db: Session, job: JobModel):
"""
新增定时任务数据库操作
:param db: orm对象
:param job: 定时任务对象
:return:
"""
db_job = SysJob(**job.model_dump())
db.add(db_job)
db.flush()
return db_job
@classmethod
def edit_job_dao(cls, db: Session, job: dict):
"""
编辑定时任务数据库操作
:param db: orm对象
:param job: 需要更新的定时任务字典
:return:
"""
db.query(SysJob) \
.filter(SysJob.job_id == job.get('job_id')) \
.update(job)
@classmethod
def delete_job_dao(cls, db: Session, job: JobModel):
"""
删除定时任务数据库操作
:param db: orm对象
:param job: 定时任务对象
:return:
"""
db.query(SysJob) \
.filter(SysJob.job_id == job.job_id) \
.delete()

View File

@@ -0,0 +1,67 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.job_do import SysJobLog
from module_admin.entity.vo.job_vo import *
from datetime import datetime, time
class JobLogDao:
"""
定时任务日志管理模块数据库操作层
"""
@classmethod
def get_job_log_list(cls, db: Session, query_object: JobLogQueryModel):
"""
根据查询参数获取定时任务日志列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 定时任务日志列表信息对象
"""
job_log_list = db.query(SysJobLog) \
.filter(SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJobLog.job_group == query_object.job_group if query_object.job_group else True,
SysJobLog.status == query_object.status if query_object.status else True,
SysJobLog.create_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True
) \
.distinct().all()
return job_log_list
@classmethod
def add_job_log_dao(cls, db: Session, job_log: JobLogModel):
"""
新增定时任务日志数据库操作
:param db: orm对象
:param job_log: 定时任务日志对象
:return:
"""
db_job_log = SysJobLog(**job_log.model_dump())
db.add(db_job_log)
db.flush()
return db_job_log
@classmethod
def delete_job_log_dao(cls, db: Session, job_log: JobLogModel):
"""
删除定时任务日志数据库操作
:param db: orm对象
:param job_log: 定时任务日志对象
:return:
"""
db.query(SysJobLog) \
.filter(SysJobLog.job_log_id == job_log.job_log_id) \
.delete()
@classmethod
def clear_job_log_dao(cls, db: Session):
"""
清除定时任务日志数据库操作
:param db: orm对象
:return:
"""
db.query(SysJobLog) \
.delete()

View File

@@ -0,0 +1,131 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.log_do import SysOperLog, SysLogininfor
from module_admin.entity.vo.log_vo import *
from utils.time_format_util import object_format_datetime, list_format_datetime
from datetime import datetime, time
class OperationLogDao:
"""
操作日志管理模块数据库操作层
"""
@classmethod
def get_operation_log_list(cls, db: Session, query_object: OperLogQueryModel):
"""
根据查询参数获取操作日志列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 操作日志列表信息对象
"""
operation_log_list = db.query(SysOperLog) \
.filter(SysOperLog.title.like(f'%{query_object.title}%') if query_object.title else True,
SysOperLog.oper_name.like(f'%{query_object.oper_name}%') if query_object.oper_name else True,
SysOperLog.business_type == query_object.business_type if query_object.business_type else True,
SysOperLog.status == query_object.status if query_object.status else True,
SysOperLog.oper_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True
)\
.distinct().all()
return operation_log_list
@classmethod
def add_operation_log_dao(cls, db: Session, operation_log: OperLogModel):
"""
新增操作日志数据库操作
:param db: orm对象
:param operation_log: 操作日志对象
:return: 新增校验结果
"""
db_operation_log = SysOperLog(**operation_log.model_dump())
db.add(db_operation_log)
db.flush()
return db_operation_log
@classmethod
def delete_operation_log_dao(cls, db: Session, operation_log: OperLogModel):
"""
删除操作日志数据库操作
:param db: orm对象
:param operation_log: 操作日志对象
:return:
"""
db.query(SysOperLog) \
.filter(SysOperLog.oper_id == operation_log.oper_id) \
.delete()
@classmethod
def clear_operation_log_dao(cls, db: Session):
"""
清除操作日志数据库操作
:param db: orm对象
:return:
"""
db.query(SysOperLog) \
.delete()
class LoginLogDao:
"""
登录日志管理模块数据库操作层
"""
@classmethod
def get_login_log_list(cls, db: Session, query_object: LoginLogQueryModel):
"""
根据查询参数获取登录日志列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 登录日志列表信息对象
"""
login_log_list = db.query(SysLogininfor) \
.filter(SysLogininfor.ipaddr.like(f'%{query_object.ipaddr}%') if query_object.ipaddr else True,
SysLogininfor.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True,
SysLogininfor.status == query_object.status if query_object.status else True,
SysLogininfor.login_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True
)\
.distinct().all()
return login_log_list
@classmethod
def add_login_log_dao(cls, db: Session, login_log: LogininforModel):
"""
新增登录日志数据库操作
:param db: orm对象
:param login_log: 登录日志对象
:return: 新增校验结果
"""
db_login_log = SysLogininfor(**login_log.model_dump())
db.add(db_login_log)
db.flush()
return db_login_log
@classmethod
def delete_login_log_dao(cls, db: Session, login_log: LogininforModel):
"""
删除登录日志数据库操作
:param db: orm对象
:param login_log: 登录日志对象
:return:
"""
db.query(SysLogininfor) \
.filter(SysLogininfor.info_id == login_log.info_id) \
.delete()
@classmethod
def clear_login_log_dao(cls, db: Session):
"""
清除登录日志数据库操作
:param db: orm对象
:return:
"""
db.query(SysLogininfor) \
.delete()

View File

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

View File

@@ -0,0 +1,142 @@
from sqlalchemy import and_
from sqlalchemy.orm import Session
from module_admin.entity.do.menu_do import SysMenu
from module_admin.entity.do.user_do import SysUser, SysUserRole
from module_admin.entity.do.role_do import SysRole, SysRoleMenu
from module_admin.entity.vo.menu_vo import *
class MenuDao:
"""
菜单管理模块数据库操作层
"""
@classmethod
def get_menu_detail_by_id(cls, db: Session, menu_id: int):
"""
根据菜单id获取菜单详细信息
:param db: orm对象
:param menu_id: 菜单id
:return: 菜单信息对象
"""
menu_info = db.query(SysMenu) \
.filter(SysMenu.menu_id == menu_id) \
.first()
return menu_info
@classmethod
def get_menu_detail_by_info(cls, db: Session, menu: MenuModel):
"""
根据菜单参数获取菜单信息
:param db: orm对象
:param menu: 菜单参数对象
:return: 菜单信息对象
"""
menu_info = db.query(SysMenu) \
.filter(SysMenu.parent_id == menu.parent_id if menu.parent_id else True,
SysMenu.menu_name == menu.menu_name if menu.menu_name else True,
SysMenu.menu_type == menu.menu_type if menu.menu_type else True) \
.first()
return menu_info
@classmethod
def get_menu_list_for_tree(cls, db: Session, user_id: int, role: list):
"""
根据角色信息获取所有在用菜单列表信息
:param db: orm对象
:param user_id: 用户id
:param role: 用户角色列表信息
:return: 菜单列表信息
"""
role_id_list = [item.role_id for item in role]
if 1 in role_id_list:
menu_query_all = db.query(SysMenu) \
.filter(SysMenu.status == 0) \
.order_by(SysMenu.order_num) \
.distinct().all()
else:
menu_query_all = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole,
and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0,)) \
.order_by(SysMenu.order_num) \
.distinct().all()
return menu_query_all
@classmethod
def get_menu_list(cls, db: Session, page_object: MenuQueryModel, user_id: int, role: list):
"""
根据查询参数获取菜单列表信息
:param db: orm对象
:param page_object: 不分页查询参数对象
:param user_id: 用户id
:param role: 用户角色列表
:return: 菜单列表信息对象
"""
role_id_list = [item.role_id for item in role]
if 1 in role_id_list:
menu_query_all = db.query(SysMenu) \
.filter(SysMenu.status == page_object.status if page_object.status else True,
SysMenu.menu_name.like(
f'%{page_object.menu_name}%') if page_object.menu_name else True) \
.order_by(SysMenu.order_num) \
.distinct().all()
else:
menu_query_all = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole,
and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id,
SysMenu.status == page_object.status if page_object.status else True,
SysMenu.menu_name.like(
f'%{page_object.menu_name}%') if page_object.menu_name else True)) \
.order_by(SysMenu.order_num) \
.distinct().all()
return menu_query_all
@classmethod
def add_menu_dao(cls, db: Session, menu: MenuModel):
"""
新增菜单数据库操作
:param db: orm对象
:param menu: 菜单对象
:return:
"""
db_menu = SysMenu(**menu.model_dump())
db.add(db_menu)
db.flush()
return db_menu
@classmethod
def edit_menu_dao(cls, db: Session, menu: dict):
"""
编辑菜单数据库操作
:param db: orm对象
:param menu: 需要更新的菜单字典
:return:
"""
db.query(SysMenu) \
.filter(SysMenu.menu_id == menu.get('menu_id')) \
.update(menu)
@classmethod
def delete_menu_dao(cls, db: Session, menu: MenuModel):
"""
删除菜单数据库操作
:param db: orm对象
:param menu: 菜单对象
:return:
"""
db.query(SysMenu) \
.filter(SysMenu.menu_id == menu.menu_id) \
.delete()

View File

@@ -0,0 +1,99 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.notice_do import SysNotice
from module_admin.entity.vo.notice_vo import *
from datetime import datetime, time
class NoticeDao:
"""
通知公告管理模块数据库操作层
"""
@classmethod
def get_notice_detail_by_id(cls, db: Session, notice_id: int):
"""
根据通知公告id获取通知公告详细信息
:param db: orm对象
:param notice_id: 通知公告id
:return: 通知公告信息对象
"""
notice_info = db.query(SysNotice) \
.filter(SysNotice.notice_id == notice_id) \
.first()
return notice_info
@classmethod
def get_notice_detail_by_info(cls, db: Session, notice: NoticeModel):
"""
根据通知公告参数获取通知公告信息
:param db: orm对象
:param notice: 通知公告参数对象
:return: 通知公告信息对象
"""
notice_info = db.query(SysNotice) \
.filter(SysNotice.notice_title == notice.notice_title if notice.notice_title else True,
SysNotice.notice_type == notice.notice_type if notice.notice_type else True,
SysNotice.notice_content == notice.notice_content if notice.notice_content else True) \
.first()
return notice_info
@classmethod
def get_notice_list(cls, db: Session, query_object: NoticeQueryModel):
"""
根据查询参数获取通知公告列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 通知公告列表信息对象
"""
notice_list = db.query(SysNotice) \
.filter(SysNotice.notice_title.like(f'%{query_object.notice_title}%') if query_object.notice_title else True,
SysNotice.update_by.like(f'%{query_object.update_by}%') if query_object.update_by else True,
SysNotice.notice_type == query_object.notice_type if query_object.notice_type else True,
SysNotice.create_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True
) \
.distinct().all()
return notice_list
@classmethod
def add_notice_dao(cls, db: Session, notice: NoticeModel):
"""
新增通知公告数据库操作
:param db: orm对象
:param notice: 通知公告对象
:return:
"""
db_notice = SysNotice(**notice.model_dump())
db.add(db_notice)
db.flush()
return db_notice
@classmethod
def edit_notice_dao(cls, db: Session, notice: dict):
"""
编辑通知公告数据库操作
:param db: orm对象
:param notice: 需要更新的通知公告字典
:return:
"""
db.query(SysNotice) \
.filter(SysNotice.notice_id == notice.get('notice_id')) \
.update(notice)
@classmethod
def delete_notice_dao(cls, db: Session, notice: NoticeModel):
"""
删除通知公告数据库操作
:param db: orm对象
:param notice: 通知公告对象
:return:
"""
db.query(SysNotice) \
.filter(SysNotice.notice_id == notice.notice_id) \
.delete()

View File

@@ -0,0 +1,110 @@
from sqlalchemy.orm import Session
from module_admin.entity.do.post_do import SysPost
from module_admin.entity.vo.post_vo import *
class PostDao:
"""
岗位管理模块数据库操作层
"""
@classmethod
def get_post_by_id(cls, db: Session, post_id: int):
"""
根据岗位id获取在用岗位详细信息
:param db: orm对象
:param post_id: 岗位id
:return: 在用岗位信息对象
"""
post_info = db.query(SysPost) \
.filter(SysPost.post_id == post_id,
SysPost.status == 0) \
.first()
return post_info
@classmethod
def get_post_detail_by_id(cls, db: Session, post_id: int):
"""
根据岗位id获取岗位详细信息
:param db: orm对象
:param post_id: 岗位id
:return: 岗位信息对象
"""
post_info = db.query(SysPost) \
.filter(SysPost.post_id == post_id) \
.first()
return post_info
@classmethod
def get_post_detail_by_info(cls, db: Session, post: PostModel):
"""
根据岗位参数获取岗位信息
:param db: orm对象
:param post: 岗位参数对象
:return: 岗位信息对象
"""
post_info = db.query(SysPost) \
.filter(SysPost.post_name == post.post_name if post.post_name else True,
SysPost.post_code == post.post_code if post.post_code else True,
SysPost.post_sort == post.post_sort if post.post_sort else True) \
.first()
return post_info
@classmethod
def get_post_list(cls, db: Session, query_object: PostModel):
"""
根据查询参数获取岗位列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 岗位列表信息对象
"""
post_list = db.query(SysPost) \
.filter(SysPost.post_code.like(f'%{query_object.post_code}%') if query_object.post_code else True,
SysPost.post_name.like(f'%{query_object.post_name}%') if query_object.post_name else True,
SysPost.status == query_object.status if query_object.status else True
) \
.order_by(SysPost.post_sort) \
.distinct().all()
return post_list
@classmethod
def add_post_dao(cls, db: Session, post: PostModel):
"""
新增岗位数据库操作
:param db: orm对象
:param post: 岗位对象
:return:
"""
db_post = SysPost(**post.model_dump())
db.add(db_post)
db.flush()
return db_post
@classmethod
def edit_post_dao(cls, db: Session, post: dict):
"""
编辑岗位数据库操作
:param db: orm对象
:param post: 需要更新的岗位字典
:return:
"""
db.query(SysPost) \
.filter(SysPost.post_id == post.get('post_id')) \
.update(post)
@classmethod
def delete_post_dao(cls, db: Session, post: PostModel):
"""
删除岗位数据库操作
:param db: orm对象
:param post: 岗位对象
:return:
"""
db.query(SysPost) \
.filter(SysPost.post_id == post.post_id) \
.delete()

View File

@@ -0,0 +1,222 @@
from sqlalchemy import desc, func
from sqlalchemy.orm import Session
from module_admin.entity.do.role_do import SysRole, SysRoleMenu, SysRoleDept
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.vo.role_vo import *
from datetime import datetime, time
class RoleDao:
"""
角色管理模块数据库操作层
"""
@classmethod
def get_role_by_name(cls, db: Session, role_name: str):
"""
根据角色名获取在用角色信息
:param db: orm对象
:param role_name: 角色名
:return: 当前角色名的角色信息对象
"""
query_role_info = db.query(SysRole) \
.filter(SysRole.status == 0, SysRole.del_flag == 0, SysRole.role_name == role_name) \
.order_by(desc(SysRole.create_time)).distinct().first()
return query_role_info
@classmethod
def get_role_by_info(cls, db: Session, role: RoleModel):
"""
根据角色参数获取角色信息
:param db: orm对象
:param role: 角色参数
:return: 当前角色参数的角色信息对象
"""
query_role_info = db.query(SysRole) \
.filter(SysRole.del_flag == 0,
SysRole.role_name == role.role_name if role.role_name else True,
SysRole.role_key == role.role_key if role.role_key else True) \
.order_by(desc(SysRole.create_time)).distinct().first()
return query_role_info
@classmethod
def get_role_by_id(cls, db: Session, role_id: int):
"""
根据角色id获取在用角色信息
:param db: orm对象
:param role_id: 角色id
:return: 当前角色id的角色信息对象
"""
role_info = db.query(SysRole) \
.filter(SysRole.role_id == role_id,
SysRole.status == 0,
SysRole.del_flag == 0) \
.first()
return role_info
@classmethod
def get_role_detail_by_id(cls, db: Session, role_id: int):
"""
根据role_id获取角色详细信息
:param db: orm对象
:param role_id: 角色id
:return: 当前role_id的角色信息对象
"""
query_role_info = db.query(SysRole) \
.filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \
.distinct().first()
return query_role_info
@classmethod
def get_role_select_option_dao(cls, db: Session):
"""
获取编辑页面对应的在用角色列表信息
:param db: orm对象
:return: 角色列表信息
"""
role_info = db.query(SysRole) \
.filter(SysRole.role_id != 1, SysRole.status == 0, SysRole.del_flag == 0) \
.all()
return role_info
@classmethod
def get_role_list(cls, db: Session, query_object: RoleQueryModel):
"""
根据查询参数获取角色列表信息
:param db: orm对象
:param query_object: 查询参数对象
:return: 角色列表信息对象
"""
role_list = db.query(SysRole) \
.filter(SysRole.del_flag == 0,
SysRole.role_name.like(f'%{query_object.role_name}%') if query_object.role_name else True,
SysRole.role_key.like(f'%{query_object.role_key}%') if query_object.role_key else True,
SysRole.status == query_object.status if query_object.status else True,
SysRole.create_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True
) \
.order_by(SysRole.role_sort) \
.distinct().all()
return role_list
@classmethod
def add_role_dao(cls, db: Session, role: RoleModel):
"""
新增角色数据库操作
:param db: orm对象
:param role: 角色对象
:return:
"""
db_role = SysRole(**role.model_dump())
db.add(db_role)
db.flush()
return db_role
@classmethod
def edit_role_dao(cls, db: Session, role: dict):
"""
编辑角色数据库操作
:param db: orm对象
:param role: 需要更新的角色字典
:return:
"""
db.query(SysRole) \
.filter(SysRole.role_id == role.get('role_id')) \
.update(role)
@classmethod
def delete_role_dao(cls, db: Session, role: RoleModel):
"""
删除角色数据库操作
:param db: orm对象
:param role: 角色对象
:return:
"""
db.query(SysRole) \
.filter(SysRole.role_id == role.role_id) \
.update({SysRole.del_flag: '2', SysRole.update_by: role.update_by, SysRole.update_time: role.update_time})
@classmethod
def get_role_menu_dao(cls, db: Session, role_id: int):
"""
根据角色id获取角色菜单关联列表信息
:param db: orm对象
:param role_id: 角色id
:return: 角色菜单关联列表信息
"""
role_menu_query_all = db.query(SysRoleMenu) \
.filter(SysRoleMenu.role_id == role_id) \
.distinct().all()
return role_menu_query_all
@classmethod
def add_role_menu_dao(cls, db: Session, role_menu: RoleMenuModel):
"""
新增角色菜单关联信息数据库操作
:param db: orm对象
:param role_menu: 用户角色菜单关联对象
:return:
"""
db_role_menu = SysRoleMenu(**role_menu.model_dump())
db.add(db_role_menu)
@classmethod
def delete_role_menu_dao(cls, db: Session, role_menu: RoleMenuModel):
"""
删除角色菜单关联信息数据库操作
:param db: orm对象
:param role_menu: 角色菜单关联对象
:return:
"""
db.query(SysRoleMenu) \
.filter(SysRoleMenu.role_id == role_menu.role_id) \
.delete()
@classmethod
def get_role_dept_dao(cls, db: Session, role_id: int):
"""
根据角色id获取角色部门关联列表信息
:param db: orm对象
:param role_id: 角色id
:return: 角色部门关联列表信息
"""
role_dept_query_all = db.query(SysRoleDept) \
.filter(SysRoleDept.role_id == role_id,
~db.query(SysDept).filter(func.find_in_set(SysRoleDept.dept_id, SysDept.ancestors)).exists()
) \
.distinct().all()
return role_dept_query_all
@classmethod
def add_role_dept_dao(cls, db: Session, role_dept: RoleDeptModel):
"""
新增角色部门关联信息数据库操作
:param db: orm对象
:param role_dept: 用户角色部门关联对象
:return:
"""
db_role_dept = SysRoleDept(**role_dept.dict())
db.add(db_role_dept)
@classmethod
def delete_role_dept_dao(cls, db: Session, role_dept: RoleDeptModel):
"""
删除角色部门关联信息数据库操作
:param db: orm对象
:param role_dept: 角色部门关联对象
:return:
"""
db.query(SysRoleDept) \
.filter(SysRoleDept.role_id == role_dept.role_id) \
.delete()

View File

@@ -0,0 +1,372 @@
from sqlalchemy import and_, or_, desc, func
from sqlalchemy.orm import Session
from module_admin.entity.do.user_do import SysUser, SysUserRole, SysUserPost
from module_admin.entity.do.role_do import SysRole, SysRoleMenu
from module_admin.entity.do.dept_do import SysDept
from module_admin.entity.do.post_do import SysPost
from module_admin.entity.do.menu_do import SysMenu
from module_admin.entity.vo.user_vo import *
from utils.time_format_util import list_format_datetime
from datetime import datetime, time
class UserDao:
"""
用户管理模块数据库操作层
"""
@classmethod
def get_user_by_name(cls, db: Session, user_name: str):
"""
根据用户名获取用户信息
:param db: orm对象
:param user_name: 用户名
:return: 当前用户名的用户信息对象
"""
query_user_info = db.query(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_name == user_name) \
.order_by(desc(SysUser.create_time)).distinct().first()
return query_user_info
@classmethod
def get_user_by_info(cls, db: Session, user: UserModel):
"""
根据用户参数获取用户信息
:param db: orm对象
:param user: 用户参数
:return: 当前用户参数的用户信息对象
"""
query_user_info = db.query(SysUser) \
.filter(SysUser.del_flag == 0,
SysUser.user_name == user.user_name) \
.order_by(desc(SysUser.create_time)).distinct().first()
return query_user_info
@classmethod
def get_user_by_id(cls, db: Session, user_id: int):
"""
根据user_id获取用户信息
:param db: orm对象
:param user_id: 用户id
:return: 当前user_id的用户信息对象
"""
query_user_basic_info = db.query(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.distinct().first()
query_user_dept_info = db.query(SysDept).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.join(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \
.distinct().first()
query_user_role_info = db.query(SysRole).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.distinct().all()
query_user_post_info = db.query(SysPost).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \
.join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \
.distinct().all()
role_id_list = [item.role_id for item in query_user_role_info]
if 1 in role_id_list:
query_user_menu_info = db.query(SysMenu) \
.filter(SysMenu.status == 0) \
.distinct().all()
else:
query_user_menu_info = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \
.order_by(SysMenu.order_num) \
.distinct().all()
results = dict(
user_basic_info=query_user_basic_info,
user_dept_info=query_user_dept_info,
user_role_info=query_user_role_info,
user_post_info=query_user_post_info,
user_menu_info=query_user_menu_info
)
return results
@classmethod
def get_user_detail_by_id(cls, db: Session, user_id: int):
"""
根据user_id获取用户详细信息
:param db: orm对象
:param user_id: 用户id
:return: 当前user_id的用户信息对象
"""
query_user_basic_info = db.query(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.distinct().first()
query_user_dept_info = db.query(SysDept).select_from(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.join(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \
.distinct().first()
query_user_role_info = db.query(SysRole).select_from(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.distinct().all()
query_user_post_info = db.query(SysPost).select_from(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \
.join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \
.distinct().all()
query_user_menu_info = db.query(SysMenu).select_from(SysUser) \
.filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \
.outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \
.outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \
.outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \
.join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \
.distinct().all()
results = dict(
user_basic_info=query_user_basic_info,
user_dept_info=query_user_dept_info,
user_role_info=query_user_role_info,
user_post_info=query_user_post_info,
user_menu_info=query_user_menu_info
)
return results
@classmethod
def get_user_list(cls, db: Session, query_object: UserQueryModel, data_scope_sql: str):
"""
根据查询参数获取用户列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 用户列表信息对象
"""
user_list = db.query(SysUser, SysDept) \
.filter(SysUser.del_flag == 0,
or_(SysUser.dept_id == query_object.dept_id, SysUser.dept_id.in_(
db.query(SysDept.dept_id).filter(func.find_in_set(query_object.dept_id, SysDept.ancestors))
)) if query_object.dept_id else True,
SysUser.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True,
SysUser.nick_name.like(f'%{query_object.nick_name}%') if query_object.nick_name else True,
SysUser.email.like(f'%{query_object.email}%') if query_object.email else True,
SysUser.phonenumber.like(f'%{query_object.phonenumber}%') if query_object.phonenumber else True,
SysUser.status == query_object.status if query_object.status else True,
SysUser.sex == query_object.sex if query_object.sex else True,
SysUser.create_time.between(
datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)))
if query_object.begin_time and query_object.end_time else True,
eval(data_scope_sql)
) \
.outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \
.distinct().all()
return user_list
@classmethod
def add_user_dao(cls, db: Session, user: UserModel):
"""
新增用户数据库操作
:param db: orm对象
:param user: 用户对象
:return: 新增校验结果
"""
db_user = SysUser(**user.model_dump())
db.add(db_user)
db.flush()
return db_user
@classmethod
def edit_user_dao(cls, db: Session, user: dict):
"""
编辑用户数据库操作
:param db: orm对象
:param user: 需要更新的用户字典
:return: 编辑校验结果
"""
db.query(SysUser) \
.filter(SysUser.user_id == user.get('user_id')) \
.update(user)
@classmethod
def delete_user_dao(cls, db: Session, user: UserModel):
"""
删除用户数据库操作
:param db: orm对象
:param user: 用户对象
:return:
"""
db.query(SysUser) \
.filter(SysUser.user_id == user.user_id) \
.update({SysUser.del_flag: '2', SysUser.update_by: user.update_by, SysUser.update_time: user.update_time})
@classmethod
def get_user_role_allocated_list_by_user_id(cls, db: Session, query_object: UserRoleQueryModel):
"""
根据用户id获取用户已分配的角色列表信息数据库操作
:param db: orm对象
:param query_object: 用户角色查询对象
:return: 用户已分配的角色列表信息
"""
allocated_role_list = db.query(SysRole) \
.filter(
SysRole.del_flag == 0,
SysRole.role_id != 1,
SysRole.role_name == query_object.role_name if query_object.role_name else True,
SysRole.role_key == query_object.role_key if query_object.role_key else True,
SysRole.role_id.in_(
db.query(SysUserRole.role_id).filter(SysUserRole.user_id == query_object.user_id)
)
).distinct().all()
return allocated_role_list
@classmethod
def get_user_role_unallocated_list_by_user_id(cls, db: Session, query_object: UserRoleQueryModel):
"""
根据用户id获取用户未分配的角色列表信息数据库操作
:param db: orm对象
:param query_object: 用户角色查询对象
:return: 用户未分配的角色列表信息
"""
unallocated_role_list = db.query(SysRole) \
.filter(
SysRole.del_flag == 0,
SysRole.role_id != 1,
SysRole.role_name == query_object.role_name if query_object.role_name else True,
SysRole.role_key == query_object.role_key if query_object.role_key else True,
~SysRole.role_id.in_(
db.query(SysUserRole.role_id).filter(SysUserRole.user_id == query_object.user_id)
)
).distinct().all()
return list_format_datetime(unallocated_role_list)
@classmethod
def get_user_role_allocated_list_by_role_id(cls, db: Session, query_object: UserRoleQueryModel):
"""
根据角色id获取已分配的用户列表信息
:param db: orm对象
:param query_object: 用户角色查询对象
:return: 角色已分配的用户列表信息
"""
allocated_user_list = db.query(SysUser) \
.filter(
SysUser.del_flag == 0,
SysUser.user_id != 1,
SysUser.user_name == query_object.user_name if query_object.user_name else True,
SysUser.phonenumber == query_object.phonenumber if query_object.phonenumber else True,
SysUser.user_id.in_(
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
)
).distinct().all()
return allocated_user_list
@classmethod
def get_user_role_unallocated_list_by_role_id(cls, db: Session, query_object: UserRoleQueryModel):
"""
根据角色id获取未分配的用户列表信息
:param db: orm对象
:param query_object: 用户角色查询对象
:return: 角色未分配的用户列表信息
"""
unallocated_user_list = db.query(SysUser) \
.filter(
SysUser.del_flag == 0,
SysUser.user_id != 1,
SysUser.user_name == query_object.user_name if query_object.user_name else True,
SysUser.phonenumber == query_object.phonenumber if query_object.phonenumber else True,
~SysUser.user_id.in_(
db.query(SysUserRole.user_id).filter(SysUserRole.role_id == query_object.role_id)
)
).distinct().all()
return unallocated_user_list
@classmethod
def add_user_role_dao(cls, db: Session, user_role: UserRoleModel):
"""
新增用户角色关联信息数据库操作
:param db: orm对象
:param user_role: 用户角色关联对象
:return:
"""
db_user_role = SysUserRole(**user_role.model_dump())
db.add(db_user_role)
@classmethod
def delete_user_role_dao(cls, db: Session, user_role: UserRoleModel):
"""
删除用户角色关联信息数据库操作
:param db: orm对象
:param user_role: 用户角色关联对象
:return:
"""
db.query(SysUserRole) \
.filter(SysUserRole.user_id == user_role.user_id) \
.delete()
@classmethod
def delete_user_role_by_user_and_role_dao(cls, db: Session, user_role: UserRoleModel):
"""
根据用户id及角色id删除用户角色关联信息数据库操作
:param db: orm对象
:param user_role: 用户角色关联对象
:return:
"""
db.query(SysUserRole) \
.filter(SysUserRole.user_id == user_role.user_id,
SysUserRole.role_id == user_role.role_id if user_role.role_id else True) \
.delete()
@classmethod
def get_user_role_detail(cls, db: Session, user_role: UserRoleModel):
"""
根据用户角色关联获取用户角色关联详细信息
:param db: orm对象
:param user_role: 用户角色关联对象
:return: 用户角色关联信息
"""
user_role_info = db.query(SysUserRole) \
.filter(SysUserRole.user_id == user_role.user_id, SysUserRole.role_id == user_role.role_id) \
.distinct().first()
return user_role_info
@classmethod
def add_user_post_dao(cls, db: Session, user_post: UserPostModel):
"""
新增用户岗位关联信息数据库操作
:param db: orm对象
:param user_post: 用户岗位关联对象
:return:
"""
db_user_post = SysUserPost(**user_post.model_dump())
db.add(db_user_post)
@classmethod
def delete_user_post_dao(cls, db: Session, user_post: UserPostModel):
"""
删除用户岗位关联信息数据库操作
:param db: orm对象
:param user_post: 用户岗位关联对象
:return:
"""
db.query(SysUserPost) \
.filter(SysUserPost.user_id == user_post.user_id) \
.delete()
@classmethod
def get_user_dept_info(cls, db: Session, dept_id: int):
dept_basic_info = db.query(SysDept) \
.filter(SysDept.dept_id == dept_id,
SysDept.status == 0,
SysDept.del_flag == 0) \
.first()
return dept_basic_info

View File

@@ -0,0 +1,21 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
class SysConfig(Base):
"""
参数配置表
"""
__tablename__ = 'sys_config'
config_id = Column(Integer, primary_key=True, autoincrement=True, comment='参数主键')
config_name = Column(String(100), nullable=True, default='', comment='参数名称')
config_key = Column(String(100), nullable=True, default='', comment='参数键名')
config_value = Column(String(500), nullable=True, default='', comment='参数键值')
config_type = Column(String(1), nullable=True, default='N', comment='系统内置Y是 N否')
create_by = Column(String(64), nullable=True, default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), nullable=True, default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500), nullable=True, default='', comment='备注')

View File

@@ -0,0 +1,25 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
class SysDept(Base):
"""
部门表
"""
__tablename__ = 'sys_dept'
dept_id = Column(Integer, primary_key=True, autoincrement=True, comment='部门id')
parent_id = Column(Integer, default=0, comment='父部门id')
ancestors = Column(String(50), nullable=True, default='', comment='祖级列表')
dept_name = Column(String(30), nullable=True, default='', comment='部门名称')
order_num = Column(Integer, default=0, comment='显示顺序')
leader = Column(String(20), nullable=True, default=None, comment='负责人')
phone = Column(String(11), nullable=True, default=None, comment='联系电话')
email = Column(String(50), nullable=True, default=None, comment='邮箱')
status = Column(String(1), nullable=True, default=0, comment='部门状态0正常 1停用')
del_flag = Column(String(1), nullable=True, default=0, comment='删除标志0代表存在 2代表删除')
create_by = Column(String(64), nullable=True, default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), nullable=True, default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,30 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
class SysMenu(Base):
"""
菜单权限表
"""
__tablename__ = 'sys_menu'
menu_id = Column(Integer, primary_key=True, autoincrement=True, comment='菜单ID')
menu_name = Column(String(50), nullable=False, default='', comment='菜单名称')
parent_id = Column(Integer, default=0, comment='父菜单ID')
order_num = Column(Integer, default=0, comment='显示顺序')
path = Column(String(200), nullable=True, default='', comment='路由地址')
component = Column(String(255), nullable=True, default=None, comment='组件路径')
query = Column(String(255), nullable=True, default=None, comment='路由参数')
is_frame = Column(Integer, default=1, comment='是否为外链0是 1否')
is_cache = Column(Integer, default=0, comment='是否缓存0缓存 1不缓存')
menu_type = Column(String(1), nullable=True, default='', comment='菜单类型M目录 C菜单 F按钮')
visible = Column(String(1), nullable=True, default='0', comment='菜单状态0显示 1隐藏')
status = Column(String(1), nullable=True, default='0', comment='菜单状态0正常 1停用')
perms = Column(String(100), nullable=True, default=None, comment='权限标识')
icon = Column(String(100), nullable=True, default='#', comment='菜单图标')
create_by = Column(String(64), nullable=True, default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), nullable=True, default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500), nullable=True, default='', comment='备注')

View File

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

View File

@@ -0,0 +1,21 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime
class SysPost(Base):
"""
岗位信息表
"""
__tablename__ = 'sys_post'
post_id = Column(Integer, primary_key=True, autoincrement=True, comment='岗位ID')
post_code = Column(String(64), nullable=False, comment='岗位编码')
post_name = Column(String(50), nullable=False, comment='岗位名称')
post_sort = Column(Integer, nullable=False, comment='显示顺序')
status = Column(String(1), nullable=False, default='0', comment='状态0正常 1停用')
create_by = Column(String(64), default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
update_by = Column(String(64), default='', comment='更新者')
update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间')
remark = Column(String(500), nullable=True, default='', comment='备注')

View File

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

View File

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

View File

@@ -0,0 +1,26 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Optional, List, Any
class CacheMonitorModel(BaseModel):
"""
缓存监控信息对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
command_stats: Optional[List] = []
db_size: Optional[int] = None
info: Optional[dict] = {}
class CacheInfoModel(BaseModel):
"""
缓存监控对象对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
cache_key: Optional[str] = None
cache_name: Optional[str] = None
cache_value: Optional[Any] = None
remark: Optional[str] = None

View File

@@ -0,0 +1,9 @@
from pydantic import BaseModel
class CrudResponseModel(BaseModel):
"""
操作响应模型
"""
is_success: bool
message: str

View File

@@ -0,0 +1,50 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
class ConfigModel(BaseModel):
"""
参数配置表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
config_id: Optional[int] = None
config_name: Optional[str] = None
config_key: Optional[str] = None
config_value: Optional[str] = None
config_type: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
class ConfigQueryModel(ConfigModel):
"""
参数配置管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class ConfigPageQueryModel(ConfigQueryModel):
"""
参数配置管理分页查询模型
"""
page_num: int
page_size: int
class DeleteConfigModel(BaseModel):
"""
删除参数配置模型
"""
model_config = ConfigDict(alias_generator=to_camel)
config_ids: str

View File

@@ -0,0 +1,47 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query
class DeptModel(BaseModel):
"""
部门表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
dept_id: Optional[int] = None
parent_id: Optional[int] = None
ancestors: Optional[str] = None
dept_name: Optional[str] = None
order_num: Optional[int] = None
leader: Optional[str] = None
phone: Optional[str] = None
email: Optional[str] = None
status: Optional[str] = None
del_flag: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
@as_query
class DeptQueryModel(DeptModel):
"""
部门管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
class DeleteDeptModel(BaseModel):
"""
删除部门模型
"""
model_config = ConfigDict(alias_generator=to_camel)
dept_ids: str
update_by: Optional[str] = None
update_time: Optional[str] = None

View File

@@ -0,0 +1,98 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
class DictTypeModel(BaseModel):
"""
字典类型表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
dict_id: Optional[int] = None
dict_name: Optional[str] = None
dict_type: Optional[str] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
class DictDataModel(BaseModel):
"""
字典数据表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
dict_code: Optional[int] = None
dict_sort: Optional[int] = None
dict_label: Optional[str] = None
dict_value: Optional[str] = None
dict_type: Optional[str] = None
css_class: Optional[str] = None
list_class: Optional[str] = None
is_default: Optional[str] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
class DictTypeQueryModel(DictTypeModel):
"""
字典类型管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class DictTypePageQueryModel(DictTypeQueryModel):
"""
字典类型管理分页查询模型
"""
page_num: int
page_size: int
class DeleteDictTypeModel(BaseModel):
"""
删除字典类型模型
"""
model_config = ConfigDict(alias_generator=to_camel)
dict_ids: str
class DictDataQueryModel(DictTypeModel):
"""
字典数据管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class DictDataPageQueryModel(DictDataQueryModel):
"""
字典数据管理分页查询模型
"""
page_num: int
page_size: int
class DeleteDictDataModel(BaseModel):
"""
删除字典数据模型
"""
model_config = ConfigDict(alias_generator=to_camel)
dict_codes: str

View File

@@ -0,0 +1,110 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
class JobModel(BaseModel):
"""
定时任务调度表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
job_id: Optional[int] = None
job_name: Optional[str] = None
job_group: Optional[str] = None
job_executor: Optional[str] = None
invoke_target: Optional[str] = None
job_args: Optional[str] = None
job_kwargs: Optional[str] = None
cron_expression: Optional[str] = None
misfire_policy: Optional[str] = None
concurrent: Optional[str] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
class JobLogModel(BaseModel):
"""
定时任务调度日志表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
job_log_id: Optional[int] = None
job_name: Optional[str] = None
job_group: Optional[str] = None
job_executor: Optional[str] = None
invoke_target: Optional[str] = None
job_args: Optional[str] = None
job_kwargs: Optional[str] = None
job_trigger: Optional[str] = None
job_message: Optional[str] = None
status: Optional[str] = None
exception_info: Optional[str] = None
create_time: Optional[datetime] = None
class JobQueryModel(JobModel):
"""
定时任务管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class JobPageQueryModel(JobQueryModel):
"""
定时任务管理分页查询模型
"""
page_num: int
page_size: int
class EditJobModel(JobModel):
"""
编辑定时任务模型
"""
type: Optional[str] = None
class DeleteJobModel(BaseModel):
"""
删除定时任务模型
"""
model_config = ConfigDict(alias_generator=to_camel)
job_ids: str
class JobLogQueryModel(JobLogModel):
"""
定时任务日志不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class JobLogPageQueryModel(JobLogQueryModel):
"""
定时任务日志管理分页查询模型
"""
page_num: int
page_size: int
class DeleteJobLogModel(BaseModel):
"""
删除定时任务日志模型
"""
model_config = ConfigDict(alias_generator=to_camel)
job_log_ids: str

View File

@@ -0,0 +1,111 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
class OperLogModel(BaseModel):
"""
操作日志表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
oper_id: Optional[int] = None
title: Optional[str] = None
business_type: Optional[int] = None
method: Optional[str] = None
request_method: Optional[str] = None
operator_type: Optional[int] = None
oper_name: Optional[str] = None
dept_name: Optional[str] = None
oper_url: Optional[str] = None
oper_ip: Optional[str] = None
oper_location: Optional[str] = None
oper_param: Optional[str] = None
json_result: Optional[str] = None
status: Optional[int] = None
error_msg: Optional[str] = None
oper_time: Optional[datetime] = None
cost_time: Optional[int] = None
class LogininforModel(BaseModel):
"""
登录日志表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
info_id: Optional[int] = None
user_name: Optional[str] = None
ipaddr: Optional[str] = None
login_location: Optional[str] = None
browser: Optional[str] = None
os: Optional[str] = None
status: Optional[str] = None
msg: Optional[str] = None
login_time: Optional[datetime] = None
class OperLogQueryModel(OperLogModel):
"""
操作日志管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class OperLogPageQueryModel(OperLogQueryModel):
"""
操作日志管理分页查询模型
"""
page_num: int
page_size: int
class DeleteOperLogModel(BaseModel):
"""
删除操作日志模型
"""
model_config = ConfigDict(alias_generator=to_camel)
oper_ids: str
class LoginLogQueryModel(LogininforModel):
"""
登录日志管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class LoginLogPageQueryModel(LoginLogQueryModel):
"""
登录日志管理分页查询模型
"""
page_num: int
page_size: int
class DeleteLoginLogModel(BaseModel):
"""
删除登录日志模型
"""
model_config = ConfigDict(alias_generator=to_camel)
info_ids: str
class UnlockUser(BaseModel):
"""
解锁用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
user_name: str

View File

@@ -0,0 +1,34 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Optional
class UserLogin(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
user_name: str
password: str
code: Optional[str] = None
uuid: Optional[str] = None
login_info: Optional[dict] = None
captcha_enabled: Optional[bool] = None
class Token(BaseModel):
access_token: str
token_type: str
class CaptchaCode(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
captcha_enabled: bool
img: str
uuid: str
class SmsCode(BaseModel):
is_success: Optional[bool] = None
sms_code: str
session_id: str
message: Optional[str] = None

View File

@@ -0,0 +1,50 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from datetime import datetime
from typing import Union, Optional, List
from module_admin.annotation.pydantic_annotation import as_query
class MenuModel(BaseModel):
"""
菜单表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
menu_id: Optional[int] = None
menu_name: Optional[str] = None
parent_id: Optional[int] = None
order_num: Optional[int] = None
path: Optional[str] = None
component: Optional[str] = None
query: Optional[str] = None
is_frame: Optional[int] = None
is_cache: Optional[int] = None
menu_type: Optional[str] = None
visible: Optional[str] = None
status: Optional[str] = None
perms: Optional[str] = None
icon: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
@as_query
class MenuQueryModel(MenuModel):
"""
菜单管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
class DeleteMenuModel(BaseModel):
"""
删除菜单模型
"""
model_config = ConfigDict(alias_generator=to_camel)
menu_ids: str

View File

@@ -0,0 +1,50 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
class NoticeModel(BaseModel):
"""
通知公告表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
notice_id: Optional[int] = None
notice_title: Optional[str] = None
notice_type: Optional[str] = None
notice_content: Optional[bytes] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
class NoticeQueryModel(NoticeModel):
"""
通知公告管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class NoticePageQueryModel(NoticeQueryModel):
"""
通知公告管理分页查询模型
"""
page_num: int
page_size: int
class DeleteNoticeModel(BaseModel):
"""
删除通知公告模型
"""
model_config = ConfigDict(alias_generator=to_camel)
notice_ids: str

View File

@@ -0,0 +1,39 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query
class OnlineModel(BaseModel):
"""
在线用户对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
token_id: Optional[str] = None
user_name: Optional[str] = None
dept_name: Optional[str] = None
ipaddr: Optional[str] = None
login_location: Optional[str] = None
browser: Optional[str] = None
os: Optional[str] = None
login_time: Optional[datetime] = None
@as_query
class OnlineQueryModel(OnlineModel):
"""
岗位管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
class DeleteOnlineModel(BaseModel):
"""
强退在线用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
token_ids: str

View File

@@ -0,0 +1,50 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
class PostModel(BaseModel):
"""
岗位信息表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
post_id: Optional[int] = None
post_code: Optional[str] = None
post_name: Optional[str] = None
post_sort: Optional[int] = None
status: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
class PostQueryModel(PostModel):
"""
岗位管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class PostPageQueryModel(PostQueryModel):
"""
岗位管理分页查询模型
"""
page_num: int
page_size: int
class DeletePostModel(BaseModel):
"""
删除岗位模型
"""
model_config = ConfigDict(alias_generator=to_camel)
post_ids: str

View File

@@ -0,0 +1,127 @@
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.annotation.pydantic_annotation import as_query, as_form
class RoleModel(BaseModel):
"""
角色表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
role_id: Optional[int] = None
role_name: Optional[str] = None
role_key: Optional[str] = None
role_sort: Optional[int] = None
data_scope: Optional[str] = None
menu_check_strictly: Optional[Union[int, bool]] = None
dept_check_strictly: Optional[Union[int, bool]] = None
status: Optional[str] = None
del_flag: Optional[str] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
admin: Optional[bool] = False
@field_validator('menu_check_strictly', 'dept_check_strictly')
@classmethod
def check_filed_mapping(cls, v: Union[int, bool]) -> Union[int, bool]:
if v == 1:
v = True
elif v == 0:
v = False
elif v is True:
v = 1
elif v is False:
v = 0
return v
@model_validator(mode='after')
def check_admin(self) -> 'RoleModel':
if self.role_id == 1:
self.admin = True
else:
self.admin = False
return self
class RoleMenuModel(BaseModel):
"""
角色和菜单关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
role_id: Optional[int] = None
menu_id: Optional[int] = None
class RoleDeptModel(BaseModel):
"""
角色和部门关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
role_id: Optional[int] = None
dept_id: Optional[int] = None
class RoleQueryModel(RoleModel):
"""
角色管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class RolePageQueryModel(RoleQueryModel):
"""
角色管理分页查询模型
"""
page_num: int
page_size: int
class RoleMenuQueryModel(BaseModel):
"""
角色菜单查询模型
"""
model_config = ConfigDict(alias_generator=to_camel)
menus: List = []
checked_keys: List[int] = []
class RoleDeptQueryModel(BaseModel):
"""
角色部门查询模型
"""
model_config = ConfigDict(alias_generator=to_camel)
depts: List = []
checked_keys: List[int] = []
class AddRoleModel(RoleModel):
"""
新增角色模型
"""
dept_ids: List = []
menu_ids: List = []
type: Optional[str] = None
class DeleteRoleModel(BaseModel):
"""
删除角色模型
"""
model_config = ConfigDict(alias_generator=to_camel)
role_ids: str
update_by: Optional[str] = None
update_time: Optional[datetime] = None

View File

@@ -0,0 +1,66 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
from typing import Optional, List
class CpuInfo(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
cpu_num: Optional[int] = None
used: Optional[float] = None
sys: Optional[float] = None
free: Optional[float] = None
class MemoryInfo(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
total: Optional[str] = None
used: Optional[str] = None
free: Optional[str] = None
usage: Optional[float] = None
class SysInfo(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
computer_ip: Optional[str] = None
computer_name: Optional[str] = None
os_arch: Optional[str] = None
os_name: Optional[str] = None
user_dir: Optional[str] = None
class PyInfo(MemoryInfo):
model_config = ConfigDict(alias_generator=to_camel)
name: Optional[str] = None
version: Optional[str] = None
start_time: Optional[str] = None
run_time: Optional[str] = None
home: Optional[str] = None
class SysFiles(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
dir_name: Optional[str] = None
sys_type_name: Optional[str] = None
type_name: Optional[str] = None
total: Optional[str] = None
used: Optional[str] = None
free: Optional[str] = None
usage: Optional[str] = None
class ServerMonitorModel(BaseModel):
"""
服务监控对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel)
cpu: Optional[CpuInfo]
py: Optional[PyInfo]
mem: Optional[MemoryInfo]
sys: Optional[SysInfo]
sys_files: Optional[List[SysFiles]]

View File

@@ -0,0 +1,210 @@
from pydantic import BaseModel, ConfigDict, model_validator
from pydantic.alias_generators import to_camel
from typing import Union, Optional, List
from datetime import datetime
from module_admin.entity.vo.role_vo import RoleModel
from module_admin.entity.vo.dept_vo import DeptModel
from module_admin.entity.vo.post_vo import PostModel
from module_admin.annotation.pydantic_annotation import as_query, as_form
class TokenData(BaseModel):
"""
token解析结果
"""
user_id: Union[int, None] = None
class UserModel(BaseModel):
"""
用户表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
user_id: Optional[int] = None
dept_id: Optional[int] = None
user_name: Optional[str] = None
nick_name: Optional[str] = None
user_type: Optional[str] = None
email: Optional[str] = None
phonenumber: Optional[str] = None
sex: Optional[str] = None
avatar: Optional[str] = None
password: Optional[str] = None
status: Optional[str] = None
del_flag: Optional[str] = None
login_ip: Optional[str] = None
login_date: Optional[datetime] = None
create_by: Optional[str] = None
create_time: Optional[datetime] = None
update_by: Optional[str] = None
update_time: Optional[datetime] = None
remark: Optional[str] = None
admin: Optional[bool] = False
@model_validator(mode='after')
def check_admin(self) -> 'UserModel':
if self.user_id == 1:
self.admin = True
else:
self.admin = False
return self
class UserRoleModel(BaseModel):
"""
用户和角色关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
user_id: Optional[int] = None
role_id: Optional[int] = None
class UserPostModel(BaseModel):
"""
用户与岗位关联表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
user_id: Optional[int] = None
post_id: Optional[int] = None
class UserInfoModel(UserModel):
post_ids: Optional[Union[str, None]] = None
role_ids: Optional[Union[str, None]] = None
dept: Optional[Union[DeptModel, None]] = None
role: Optional[List[Union[RoleModel, None]]] = []
class CurrentUserModel(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
permissions: List
roles: List
user: Union[UserInfoModel, None]
class UserDetailModel(BaseModel):
"""
获取用户详情信息响应模型
"""
model_config = ConfigDict(alias_generator=to_camel)
data: Optional[Union[UserInfoModel, None]] = None
post_ids: Optional[List] = None
posts: List[Union[PostModel, None]]
role_ids: Optional[List] = None
roles: List[Union[RoleModel, None]]
class UserProfileModel(BaseModel):
"""
获取个人信息响应模型
"""
model_config = ConfigDict(alias_generator=to_camel)
data: Union[UserInfoModel, None]
post_group: Union[str, None]
role_group: Union[str, None]
class UserQueryModel(UserModel):
"""
用户管理不分页查询模型
"""
begin_time: Optional[str] = None
end_time: Optional[str] = None
@as_query
@as_form
class UserPageQueryModel(UserQueryModel):
"""
用户管理分页查询模型
"""
page_num: int
page_size: int
class AddUserModel(UserModel):
"""
新增用户模型
"""
role_ids: Optional[List] = []
post_ids: Optional[List] = []
type: Optional[str] = None
class EditUserModel(AddUserModel):
"""
编辑用户模型
"""
role: Optional[List] = []
class ResetUserModel(UserModel):
"""
重置用户密码模型
"""
old_password: Optional[str] = None
sms_code: Optional[str] = None
session_id: Optional[str] = None
class DeleteUserModel(BaseModel):
"""
删除用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
user_ids: str
update_by: Optional[str] = None
update_time: Optional[datetime] = None
class UserRoleQueryModel(UserModel):
"""
用户角色关联管理不分页查询模型
"""
role_id: Optional[int] = None
@as_query
class UserRolePageQueryModel(UserRoleQueryModel):
"""
用户角色关联管理分页查询模型
"""
page_num: int
page_size: int
class SelectedRoleModel(RoleModel):
"""
是否选择角色模型
"""
flag: Optional[bool] = False
class UserRoleResponseModel(BaseModel):
"""
用户角色关联管理列表返回模型
"""
model_config = ConfigDict(alias_generator=to_camel)
roles: List[Union[SelectedRoleModel, None]] = []
user: UserInfoModel
@as_query
class CrudUserRoleModel(BaseModel):
"""
新增、删除用户关联角色及角色关联用户模型
"""
model_config = ConfigDict(alias_generator=to_camel)
user_id: Optional[int] = None
user_ids: Optional[str] = None
role_id: Optional[int] = None
role_ids: Optional[str] = None

View File

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

View File

@@ -0,0 +1,48 @@
from PIL import Image, ImageDraw, ImageFont
import io
import os
import random
import base64
class CaptchaService:
"""
验证码模块服务层
"""
@classmethod
def create_captcha_image_service(cls):
# 创建空白图像
image = Image.new('RGB', (160, 60), color='#EAEAEA')
# 创建绘图对象
draw = ImageDraw.Draw(image)
# 设置字体
font = ImageFont.truetype(os.path.join(os.path.abspath(os.getcwd()), 'assets', 'font', 'Arial.ttf'), size=30)
# 生成两个0-9之间的随机整数
num1 = random.randint(0, 9)
num2 = random.randint(0, 9)
# 从运算符列表中随机选择一个
operational_character_list = ['+', '-', '*']
operational_character = random.choice(operational_character_list)
# 根据选择的运算符进行计算
if operational_character == '+':
result = num1 + num2
elif operational_character == '-':
result = num1 - num2
else:
result = num1 * num2
# 绘制文本
text = f"{num1} {operational_character} {num2} = ?"
draw.text((25, 15), text, fill='blue', font=font)
# 将图像数据保存到内存中
buffer = io.BytesIO()
image.save(buffer, format='PNG')
# 将图像数据转换为base64字符串
base64_string = base64.b64encode(buffer.getvalue()).decode()
return [base64_string, result]

View File

@@ -0,0 +1,18 @@
import os
from fastapi import UploadFile
class CommonService:
"""
通用模块服务层
"""
@classmethod
def upload_service(cls, path: str, task_path: str, upload_id: str, file: UploadFile):
filepath = os.path.join(path, task_path, upload_id, f'{file.filename}')
with open(filepath, 'wb') as f:
# 流式写出大型文件这里的10代表10MB
for chunk in iter(lambda: file.file.read(1024 * 1024 * 10), b''):
f.write(chunk)

View File

@@ -0,0 +1,190 @@
from fastapi import Request
from config.env import RedisInitKeyConfig
from module_admin.dao.config_dao import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
class ConfigService:
"""
参数配置管理模块服务层
"""
@classmethod
def get_config_list_services(cls, query_db: Session, query_object: ConfigQueryModel):
"""
获取参数配置列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 参数配置列表信息对象
"""
config_list_result = ConfigDao.get_config_list(query_db, query_object)
return CamelCaseUtil.transform_result(config_list_result)
@classmethod
async def init_cache_sys_config_services(cls, query_db: Session, redis):
"""
应用初始化获取所有参数配置对应的键值对信息并缓存service
:param query_db: orm对象
:param redis: redis对象
:return:
"""
# 获取以sys_config:开头的键列表
keys = await redis.keys(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:*")
# 删除匹配的键
if keys:
await redis.delete(*keys)
config_all = ConfigDao.get_config_list(query_db, ConfigQueryModel(**dict()))
for config_obj in config_all:
if config_obj.config_type == 'Y':
await redis.set(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_obj.config_key}", config_obj.config_value)
@classmethod
async def query_config_list_from_cache_services(cls, redis, config_key: str):
"""
从缓存获取参数键名对应值service
:param redis: redis对象
:param config_key: 参数键名
:return: 参数键名对应值
"""
result = await redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_key}")
return result
@classmethod
async def add_config_services(cls, request: Request, query_db: Session, page_object: ConfigModel):
"""
新增参数配置信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 新增参数配置对象
:return: 新增参数配置校验结果
"""
config = ConfigDao.get_config_detail_by_info(query_db, ConfigModel(configKey=page_object.config_key))
if config:
result = dict(is_success=False, message='参数键名已存在')
else:
try:
ConfigDao.add_config_dao(query_db, page_object)
query_db.commit()
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def edit_config_services(cls, request: Request, query_db: Session, page_object: ConfigModel):
"""
编辑参数配置信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 编辑参数配置对象
:return: 编辑参数配置校验结果
"""
edit_config = page_object.model_dump(exclude_unset=True)
config_info = cls.config_detail_services(query_db, edit_config.get('config_id'))
if config_info:
if config_info.config_key != page_object.config_key or config_info.config_value != page_object.config_value:
config = ConfigDao.get_config_detail_by_info(query_db, page_object)
if config:
result = dict(is_success=False, message='参数配置已存在')
return CrudResponseModel(**result)
try:
ConfigDao.edit_config_dao(query_db, edit_config)
query_db.commit()
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='参数配置不存在')
return CrudResponseModel(**result)
@classmethod
async def delete_config_services(cls, request: Request, query_db: Session, page_object: DeleteConfigModel):
"""
删除参数配置信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 删除参数配置对象
:return: 删除参数配置校验结果
"""
if page_object.config_ids.split(','):
config_id_list = page_object.config_ids.split(',')
try:
for config_id in config_id_list:
ConfigDao.delete_config_dao(query_db, ConfigModel(configId=config_id))
query_db.commit()
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入字典数据id为空')
return CrudResponseModel(**result)
@classmethod
def config_detail_services(cls, query_db: Session, config_id: int):
"""
获取参数配置详细信息service
:param query_db: orm对象
:param config_id: 参数配置id
:return: 参数配置id对应的信息
"""
config = ConfigDao.get_config_detail_by_id(query_db, config_id=config_id)
result = ConfigModel(**CamelCaseUtil.transform_result(config))
return result
@staticmethod
def export_config_list_services(config_list: List):
"""
导出参数配置信息service
:param config_list: 参数配置信息列表
:return: 参数配置信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"configId": "参数主键",
"configName": "参数名称",
"configKey": "参数键名",
"configValue": "参数键值",
"configType": "系统内置",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
}
data = config_list
for item in data:
if item.get('configType') == 'Y':
item['configType'] = ''
else:
item['configType'] = ''
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data]
binary_data = export_list2excel(new_data)
return binary_data
@classmethod
async def refresh_sys_config_services(cls, request: Request, query_db: Session):
"""
刷新字典缓存信息service
:param request: Request对象
:param query_db: orm对象
:return: 刷新字典缓存校验结果
"""
await cls.init_cache_sys_config_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='刷新成功')
return CrudResponseModel(**result)

View File

@@ -0,0 +1,213 @@
from module_admin.dao.dept_dao import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import CamelCaseUtil
class DeptService:
"""
部门管理模块服务层
"""
@classmethod
def get_dept_tree_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str):
"""
获取部门树信息service
:param query_db: orm对象
:param page_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门树信息对象
"""
dept_list_result = DeptDao.get_dept_list_for_tree(query_db, page_object, data_scope_sql)
dept_tree_result = cls.list_to_tree(dept_list_result)
return dept_tree_result
@classmethod
def get_dept_for_edit_option_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str):
"""
获取部门编辑部门树信息service
:param query_db: orm对象
:param page_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门树信息对象
"""
dept_list_result = DeptDao.get_dept_info_for_edit_option(query_db, page_object, data_scope_sql)
return CamelCaseUtil.transform_result(dept_list_result)
@classmethod
def get_dept_list_services(cls, query_db: Session, page_object: DeptModel, data_scope_sql: str):
"""
获取部门列表信息service
:param query_db: orm对象
:param page_object: 分页查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 部门列表信息对象
"""
dept_list_result = DeptDao.get_dept_list(query_db, page_object, data_scope_sql)
return CamelCaseUtil.transform_result(dept_list_result)
@classmethod
def add_dept_services(cls, query_db: Session, page_object: DeptModel):
"""
新增部门信息service
:param query_db: orm对象
:param page_object: 新增部门对象
:return: 新增部门校验结果
"""
parent_info = DeptDao.get_dept_by_id(query_db, page_object.parent_id)
if parent_info:
page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}'
else:
page_object.ancestors = '0'
dept = DeptDao.get_dept_detail_by_info(query_db, DeptModel(parentId=page_object.parent_id,
deptName=page_object.dept_name))
if dept:
result = dict(is_success=False, message='同一部门下不允许存在同名的部门')
else:
try:
DeptDao.add_dept_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_dept_services(cls, query_db: Session, page_object: DeptModel):
"""
编辑部门信息service
:param query_db: orm对象
:param page_object: 编辑部门对象
:return: 编辑部门校验结果
"""
parent_info = DeptDao.get_dept_by_id(query_db, page_object.parent_id)
if parent_info:
page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}'
else:
page_object.ancestors = '0'
edit_dept = page_object.model_dump(exclude_unset=True)
dept_info = cls.dept_detail_services(query_db, edit_dept.get('dept_id'))
if dept_info:
if dept_info.parent_id != page_object.parent_id or dept_info.dept_name != page_object.dept_name:
dept = DeptDao.get_dept_detail_by_info(query_db, DeptModel(parentId=page_object.parent_id,
deptName=page_object.dept_name))
if dept:
result = dict(is_success=False, message='同一部门下不允许存在同名的部门')
return CrudResponseModel(**result)
try:
DeptDao.edit_dept_dao(query_db, edit_dept)
cls.update_children_info(query_db, DeptModel(deptId=page_object.dept_id,
ancestors=page_object.ancestors,
updateBy=page_object.update_by,
updateTime=page_object.update_time
)
)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='部门不存在')
return CrudResponseModel(**result)
@classmethod
def delete_dept_services(cls, query_db: Session, page_object: DeleteDeptModel):
"""
删除部门信息service
:param query_db: orm对象
:param page_object: 删除部门对象
:return: 删除部门校验结果
"""
if page_object.dept_ids.split(','):
dept_id_list = page_object.dept_ids.split(',')
ancestors = DeptDao.get_dept_all_ancestors(query_db)
try:
for dept_id in dept_id_list:
for ancestor in ancestors:
if dept_id in ancestor[0]:
result = dict(is_success=False, message='该部门下有子部门,不允许删除')
return CrudResponseModel(**result)
DeptDao.delete_dept_dao(query_db, DeptModel(deptId=dept_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入部门id为空')
return CrudResponseModel(**result)
@classmethod
def dept_detail_services(cls, query_db: Session, dept_id: int):
"""
获取部门详细信息service
:param query_db: orm对象
:param dept_id: 部门id
:return: 部门id对应的信息
"""
dept = DeptDao.get_dept_detail_by_id(query_db, dept_id=dept_id)
result = DeptModel(**CamelCaseUtil.transform_result(dept))
return result
@classmethod
def list_to_tree(cls, permission_list: list) -> list:
"""
工具方法:根据部门列表信息生成树形嵌套数据
:param permission_list: 部门列表信息
:return: 部门树形嵌套数据
"""
permission_list = [dict(id=item.dept_id, label=item.dept_name, parentId=item.parent_id) for item in
permission_list]
# 转成id为key的字典
mapping: dict = dict(zip([i['id'] for i in permission_list], permission_list))
# 树容器
container: list = []
for d in permission_list:
# 如果找不到父级项,则是根节点
parent: dict = mapping.get(d['parentId'])
if parent is None:
container.append(d)
else:
children: list = parent.get('children')
if not children:
children = []
children.append(d)
parent.update({'children': children})
return container
@classmethod
def update_children_info(cls, query_db, page_object):
"""
工具方法:递归更新子部门信息
:param query_db: orm对象
:param page_object: 编辑部门对象
:return:
"""
children_info = DeptDao.get_children_dept(query_db, page_object.dept_id)
if children_info:
for child in children_info:
child.ancestors = f'{page_object.ancestors},{page_object.dept_id}'
DeptDao.edit_dept_dao(query_db,
dict(dept_id=child.dept_id,
ancestors=child.ancestors,
update_by=page_object.update_by,
update_time=page_object.update_time
)
)
cls.update_children_info(query_db, DeptModel(dept_id=child.dept_id,
ancestors=child.ancestors,
update_by=page_object.update_by,
update_time=page_object.update_time
))

View File

@@ -0,0 +1,363 @@
from fastapi import Request
import json
from config.env import RedisInitKeyConfig
from module_admin.dao.dict_dao import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
class DictTypeService:
"""
字典类型管理模块服务层
"""
@classmethod
def get_dict_type_list_services(cls, query_db: Session, query_object: DictTypeQueryModel):
"""
获取字典类型列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 字典类型列表信息对象
"""
dict_type_list_result = DictTypeDao.get_dict_type_list(query_db, query_object)
return CamelCaseUtil.transform_result(dict_type_list_result)
@classmethod
async def add_dict_type_services(cls, request: Request, query_db: Session, page_object: DictTypeModel):
"""
新增字典类型信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 新增岗位对象
:return: 新增字典类型校验结果
"""
dict_type = DictTypeDao.get_dict_type_detail_by_info(query_db, DictTypeModel(dictType=page_object.dict_type))
if dict_type:
result = dict(is_success=False, message='字典类型已存在')
else:
try:
DictTypeDao.add_dict_type_dao(query_db, page_object)
query_db.commit()
await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def edit_dict_type_services(cls, request: Request, query_db: Session, page_object: DictTypeModel):
"""
编辑字典类型信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 编辑字典类型对象
:return: 编辑字典类型校验结果
"""
edit_dict_type = page_object.model_dump(exclude_unset=True)
dict_type_info = cls.dict_type_detail_services(query_db, edit_dict_type.get('dict_id'))
if dict_type_info:
if dict_type_info.dict_type != page_object.dict_type or dict_type_info.dict_name != page_object.dict_name:
dict_type = DictTypeDao.get_dict_type_detail_by_info(query_db, DictTypeModel(dictType=page_object.dict_type))
if dict_type:
result = dict(is_success=False, message='字典类型已存在')
return CrudResponseModel(**result)
try:
if dict_type_info.dict_type != page_object.dict_type:
query_dict_data = DictDataModel(dictType=dict_type_info.dict_type)
dict_data_list = DictDataDao.get_dict_data_list(query_db, query_dict_data)
for dict_data in dict_data_list:
edit_dict_data = DictDataModel(dictCode=dict_data.dict_code, dictType=page_object.dict_type, updateBy=page_object.update_by).model_dump(exclude_unset=True)
DictDataDao.edit_dict_data_dao(query_db, edit_dict_data)
DictTypeDao.edit_dict_type_dao(query_db, edit_dict_type)
query_db.commit()
await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='字典类型不存在')
return CrudResponseModel(**result)
@classmethod
async def delete_dict_type_services(cls, request: Request, query_db: Session, page_object: DeleteDictTypeModel):
"""
删除字典类型信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 删除字典类型对象
:return: 删除字典类型校验结果
"""
if page_object.dict_ids.split(','):
dict_id_list = page_object.dict_ids.split(',')
try:
for dict_id in dict_id_list:
DictTypeDao.delete_dict_type_dao(query_db, DictTypeModel(dictId=dict_id))
query_db.commit()
await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入字典类型id为空')
return CrudResponseModel(**result)
@classmethod
def dict_type_detail_services(cls, query_db: Session, dict_id: int):
"""
获取字典类型详细信息service
:param query_db: orm对象
:param dict_id: 字典类型id
:return: 字典类型id对应的信息
"""
dict_type = DictTypeDao.get_dict_type_detail_by_id(query_db, dict_id=dict_id)
result = DictTypeModel(**CamelCaseUtil.transform_result(dict_type))
return result
@staticmethod
def export_dict_type_list_services(dict_type_list: List):
"""
导出字典类型信息service
:param dict_type_list: 字典信息列表
:return: 字典信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"dictId": "字典编号",
"dictName": "字典名称",
"dictType": "字典类型",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
}
data = dict_type_list
for item in data:
if item.get('status') == '0':
item['status'] = '正常'
else:
item['status'] = '停用'
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data]
binary_data = export_list2excel(new_data)
return binary_data
@classmethod
async def refresh_sys_dict_services(cls, request: Request, query_db: Session):
"""
刷新字典缓存信息service
:param request: Request对象
:param query_db: orm对象
:return: 刷新字典缓存校验结果
"""
await DictDataService.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='刷新成功')
return CrudResponseModel(**result)
class DictDataService:
"""
字典数据管理模块服务层
"""
@classmethod
def get_dict_data_list_services(cls, query_db: Session, query_object: DictDataModel):
"""
获取字典数据列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 字典数据列表信息对象
"""
dict_data_list_result = DictDataDao.get_dict_data_list(query_db, query_object)
return CamelCaseUtil.transform_result(dict_data_list_result)
@classmethod
def query_dict_data_list_services(cls, query_db: Session, dict_type: str):
"""
获取字典数据列表信息service
:param query_db: orm对象
:param dict_type: 字典类型
:return: 字典数据列表信息对象
"""
dict_data_list_result = DictDataDao.query_dict_data_list(query_db, dict_type)
return dict_data_list_result
@classmethod
async def init_cache_sys_dict_services(cls, query_db: Session, redis):
"""
应用初始化获取所有字典类型对应的字典数据信息并缓存service
:param query_db: orm对象
:param redis: redis对象
:return:
"""
# 获取以sys_dict:开头的键列表
keys = await redis.keys(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:*")
# 删除匹配的键
if keys:
await redis.delete(*keys)
dict_type_all = DictTypeDao.get_all_dict_type(query_db)
for dict_type_obj in [item for item in dict_type_all if item.status == '0']:
dict_type = dict_type_obj.dict_type
dict_data_list = DictDataDao.query_dict_data_list(query_db, dict_type)
dict_data = [CamelCaseUtil.transform_result(row) for row in dict_data_list if row]
await redis.set(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:{dict_type}", json.dumps(dict_data, ensure_ascii=False, default=str))
@classmethod
async def query_dict_data_list_from_cache_services(cls, redis, dict_type: str):
"""
从缓存获取字典数据列表信息service
:param redis: redis对象
:param dict_type: 字典类型
:return: 字典数据列表信息对象
"""
result = []
dict_data_list_result = await redis.get(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:{dict_type}")
if dict_data_list_result:
result = json.loads(dict_data_list_result)
return CamelCaseUtil.transform_result(result)
@classmethod
async def add_dict_data_services(cls, request: Request, query_db: Session, page_object: DictDataModel):
"""
新增字典数据信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 新增岗位对象
:return: 新增字典数据校验结果
"""
dict_data = DictDataDao.get_dict_data_detail_by_info(query_db, page_object)
if dict_data:
result = dict(is_success=False, message='字典数据已存在')
else:
try:
DictDataDao.add_dict_data_dao(query_db, page_object)
query_db.commit()
await cls.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def edit_dict_data_services(cls, request: Request, query_db: Session, page_object: DictDataModel):
"""
编辑字典数据信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 编辑字典数据对象
:return: 编辑字典数据校验结果
"""
edit_data_type = page_object.model_dump(exclude_unset=True)
dict_data_info = cls.dict_data_detail_services(query_db, edit_data_type.get('dict_code'))
if dict_data_info:
if dict_data_info.dict_type != page_object.dict_type or dict_data_info.dict_label != page_object.dict_label or dict_data_info.dict_value != page_object.dict_value:
dict_data = DictDataDao.get_dict_data_detail_by_info(query_db, page_object)
if dict_data:
result = dict(is_success=False, message='字典数据已存在')
return CrudResponseModel(**result)
try:
DictDataDao.edit_dict_data_dao(query_db, edit_data_type)
query_db.commit()
await cls.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='字典数据不存在')
return CrudResponseModel(**result)
@classmethod
async def delete_dict_data_services(cls, request: Request, query_db: Session, page_object: DeleteDictDataModel):
"""
删除字典数据信息service
:param request: Request对象
:param query_db: orm对象
:param page_object: 删除字典数据对象
:return: 删除字典数据校验结果
"""
if page_object.dict_codes.split(','):
dict_code_list = page_object.dict_codes.split(',')
try:
for dict_code in dict_code_list:
DictDataDao.delete_dict_data_dao(query_db, DictDataModel(dictCode=dict_code))
query_db.commit()
await cls.init_cache_sys_dict_services(query_db, request.app.state.redis)
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入字典数据id为空')
return CrudResponseModel(**result)
@classmethod
def dict_data_detail_services(cls, query_db: Session, dict_code: int):
"""
获取字典数据详细信息service
:param query_db: orm对象
:param dict_code: 字典数据id
:return: 字典数据id对应的信息
"""
dict_data = DictDataDao.get_dict_data_detail_by_id(query_db, dict_code=dict_code)
result = DictDataModel(**CamelCaseUtil.transform_result(dict_data))
return result
@staticmethod
def export_dict_data_list_services(dict_data_list: List):
"""
导出字典数据信息service
:param dict_data_list: 字典数据信息列表
:return: 字典数据信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"dictCode": "字典编码",
"dictSort": "字典标签",
"dictLabel": "字典键值",
"dictValue": "字典排序",
"dictType": "字典类型",
"cssClass": "样式属性",
"listClass": "表格回显样式",
"isDefault": "是否默认",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
}
data = dict_data_list
for item in data:
if item.get('status') == '0':
item['status'] = '正常'
else:
item['status'] = '停用'
if item.get('isDefault') == 'Y':
item['isDefault'] = ''
else:
item['isDefault'] = ''
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data]
binary_data = export_list2excel(new_data)
return binary_data

View File

@@ -0,0 +1,121 @@
from module_admin.dao.job_log_dao import *
from module_admin.dao.dict_dao import DictDataDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
class JobLogService:
"""
定时任务日志管理模块服务层
"""
@classmethod
def get_job_log_list_services(cls, query_db: Session, query_object: JobLogQueryModel):
"""
获取定时任务日志列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 定时任务日志列表信息对象
"""
job_log_list_result = JobLogDao.get_job_log_list(query_db, query_object)
return CamelCaseUtil.transform_result(job_log_list_result)
@classmethod
def add_job_log_services(cls, query_db: Session, page_object: JobLogModel):
"""
新增定时任务日志信息service
:param query_db: orm对象
:param page_object: 新增定时任务日志对象
:return: 新增定时任务日志校验结果
"""
try:
JobLogDao.add_job_log_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
result = dict(is_success=False, message=str(e))
return CrudResponseModel(**result)
@classmethod
def delete_job_log_services(cls, query_db: Session, page_object: DeleteJobLogModel):
"""
删除定时任务日志信息service
:param query_db: orm对象
:param page_object: 删除定时任务日志对象
:return: 删除定时任务日志校验结果
"""
if page_object.job_log_ids.split(','):
job_log_id_list = page_object.job_log_ids.split(',')
try:
for job_log_id in job_log_id_list:
JobLogDao.delete_job_log_dao(query_db, JobLogModel(jobLogId=job_log_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入定时任务日志id为空')
return CrudResponseModel(**result)
@classmethod
def clear_job_log_services(cls, query_db: Session):
"""
清除定时任务日志信息service
:param query_db: orm对象
:return: 清除定时任务日志校验结果
"""
try:
JobLogDao.clear_job_log_dao(query_db)
query_db.commit()
result = dict(is_success=True, message='清除成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@staticmethod
def export_job_log_list_services(query_db, job_log_list: List):
"""
导出定时任务日志信息service
:param query_db: orm对象
:param job_log_list: 定时任务日志信息列表
:return: 定时任务日志信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"jobLogId": "任务日志编码",
"jobName": "任务名称",
"jobGroup": "任务组名",
"jobExecutor": "任务执行器",
"invokeTarget": "调用目标字符串",
"jobArgs": "位置参数",
"jobKwargs": "关键字参数",
"jobTrigger": "任务触发器",
"jobMessage": "日志信息",
"status": "执行状态",
"exceptionInfo": "异常信息",
"createTime": "创建时间",
}
data = job_log_list
job_group_list = DictDataDao.query_dict_data_list(query_db, dict_type='sys_job_group')
job_group_option = [dict(label=item.dict_label, value=item.dict_value) for item in job_group_list]
job_group_option_dict = {item.get('value'): item for item in job_group_option}
for item in data:
if item.get('status') == '0':
item['status'] = '正常'
else:
item['status'] = '暂停'
if str(item.get('job_group')) in job_group_option_dict.keys():
item['job_group'] = job_group_option_dict.get(str(item.get('job_group'))).get('label')
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in
data]
binary_data = export_list2excel(new_data)
return binary_data

View File

@@ -0,0 +1,198 @@
from module_admin.dao.job_dao import *
from module_admin.service.dict_service import Request, DictDataService
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
from config.get_scheduler import SchedulerUtil
class JobService:
"""
定时任务管理模块服务层
"""
@classmethod
def get_job_list_services(cls, query_db: Session, query_object: JobModel):
"""
获取定时任务列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 定时任务列表信息对象
"""
job_list_result = JobDao.get_job_list(query_db, query_object)
return CamelCaseUtil.transform_result(job_list_result)
@classmethod
def add_job_services(cls, query_db: Session, page_object: JobModel):
"""
新增定时任务信息service
:param query_db: orm对象
:param page_object: 新增定时任务对象
:return: 新增定时任务校验结果
"""
job = JobDao.get_job_detail_by_info(query_db, page_object)
if job:
result = dict(is_success=False, message='定时任务已存在')
else:
try:
JobDao.add_job_dao(query_db, page_object)
job_info = JobDao.get_job_detail_by_info(query_db, page_object)
if job_info.status == '0':
SchedulerUtil.add_scheduler_job(job_info=job_info)
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_job_services(cls, query_db: Session, page_object: EditJobModel):
"""
编辑定时任务信息service
:param query_db: orm对象
:param page_object: 编辑定时任务对象
:return: 编辑定时任务校验结果
"""
edit_job = page_object.model_dump(exclude_unset=True)
if page_object.type == 'status':
del edit_job['type']
job_info = cls.job_detail_services(query_db, edit_job.get('job_id'))
if job_info:
if page_object.type != 'status' and (job_info.job_name != page_object.job_name or job_info.job_group != page_object.job_group or job_info.invoke_target != page_object.invoke_target or job_info.cron_expression != page_object.cron_expression):
job = JobDao.get_job_detail_by_info(query_db, page_object)
if job:
result = dict(is_success=False, message='定时任务已存在')
return CrudResponseModel(**result)
try:
JobDao.edit_job_dao(query_db, edit_job)
query_job = SchedulerUtil.get_scheduler_job(job_id=edit_job.get('job_id'))
if query_job:
SchedulerUtil.remove_scheduler_job(job_id=edit_job.get('job_id'))
if edit_job.get('status') == '0':
SchedulerUtil.add_scheduler_job(job_info=job_info)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='定时任务不存在')
return CrudResponseModel(**result)
@classmethod
def execute_job_once_services(cls, query_db: Session, page_object: JobModel):
"""
执行一次定时任务service
:param query_db: orm对象
:param page_object: 定时任务对象
:return: 执行一次定时任务结果
"""
query_job = SchedulerUtil.get_scheduler_job(job_id=page_object.job_id)
if query_job:
SchedulerUtil.remove_scheduler_job(job_id=page_object.job_id)
job_info = cls.job_detail_services(query_db, page_object.job_id)
if job_info:
SchedulerUtil.execute_scheduler_job_once(job_info=job_info)
result = dict(is_success=True, message='执行成功')
else:
result = dict(is_success=False, message='定时任务不存在')
return CrudResponseModel(**result)
@classmethod
def delete_job_services(cls, query_db: Session, page_object: DeleteJobModel):
"""
删除定时任务信息service
:param query_db: orm对象
:param page_object: 删除定时任务对象
:return: 删除定时任务校验结果
"""
if page_object.job_ids.split(','):
job_id_list = page_object.job_ids.split(',')
try:
for job_id in job_id_list:
JobDao.delete_job_dao(query_db, JobModel(jobId=job_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入定时任务id为空')
return CrudResponseModel(**result)
@classmethod
def job_detail_services(cls, query_db: Session, job_id: int):
"""
获取定时任务详细信息service
:param query_db: orm对象
:param job_id: 定时任务id
:return: 定时任务id对应的信息
"""
job = JobDao.get_job_detail_by_id(query_db, job_id=job_id)
result = JobModel(**CamelCaseUtil.transform_result(job))
return result
@staticmethod
async def export_job_list_services(request: Request, job_list: List):
"""
导出定时任务信息service
:param request: Request对象
:param job_list: 定时任务信息列表
:return: 定时任务信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"jobId": "任务编码",
"jobName": "任务名称",
"jobGroup": "任务组名",
"jobExecutor": "任务执行器",
"invokeTarget": "调用目标字符串",
"jobArgs": "位置参数",
"jobKwargs": "关键字参数",
"cronExpression": "cron执行表达式",
"misfirePolicy": "计划执行错误策略",
"concurrent": "是否并发执行",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
}
data = job_list
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group')
job_group_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_group_list]
job_group_option_dict = {item.get('value'): item for item in job_group_option}
job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_executor')
job_executor_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list]
job_executor_option_dict = {item.get('value'): item for item in job_executor_option}
for item in data:
if item.get('status') == '0':
item['status'] = '正常'
else:
item['status'] = '暂停'
if str(item.get('jobGroup')) in job_group_option_dict.keys():
item['jobGroup'] = job_group_option_dict.get(str(item.get('jobGroup'))).get('label')
if str(item.get('jobExecutor')) in job_executor_option_dict.keys():
item['jobExecutor'] = job_executor_option_dict.get(str(item.get('jobExecutor'))).get('label')
if item.get('misfirePolicy') == '1':
item['misfirePolicy'] = '立即执行'
elif item.get('misfirePolicy') == '2':
item['misfirePolicy'] = '执行一次'
else:
item['misfirePolicy'] = '放弃执行'
if item.get('concurrent') == '0':
item['concurrent'] = '允许'
else:
item['concurrent'] = '禁止'
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data]
binary_data = export_list2excel(new_data)
return binary_data

View File

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

View File

@@ -0,0 +1,316 @@
from fastapi import Request, Form
from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
import random
import uuid
from datetime import timedelta
from module_admin.service.user_service import *
from module_admin.entity.vo.login_vo import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.dao.login_dao import *
from config.env import JwtConfig, RedisInitKeyConfig
from utils.common_util import CamelCaseUtil
from utils.pwd_util import *
from utils.response_util import *
from utils.message_util import *
from config.get_db import get_db
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")
class CustomOAuth2PasswordRequestForm(OAuth2PasswordRequestForm):
"""
自定义OAuth2PasswordRequestForm类增加验证码及会话编号参数
"""
def __init__(
self,
grant_type: str = Form(default=None, regex="password"),
username: str = Form(),
password: str = Form(),
scope: str = Form(default=""),
client_id: Optional[str] = Form(default=None),
client_secret: Optional[str] = Form(default=None),
code: Optional[str] = Form(default=""),
uuid: Optional[str] = Form(default=""),
login_info: Optional[Dict[str, str]] = Form(default=None)
):
super().__init__(grant_type=grant_type, username=username, password=password,
scope=scope, client_id=client_id, client_secret=client_secret)
self.code = code
self.uuid = uuid
self.login_info = login_info
class LoginService:
"""
登录模块服务层
"""
@classmethod
async def authenticate_user(cls, request: Request, query_db: Session, login_user: UserLogin):
"""
根据用户名密码校验用户登录
:param request: Request对象
:param query_db: orm对象
:param login_user: 登录用户对象
:return: 校验结果
"""
account_lock = await request.app.state.redis.get(
f"{RedisInitKeyConfig.ACCOUNT_LOCK.get('key')}:{login_user.user_name}")
if login_user.user_name == account_lock:
logger.warning("账号已锁定,请稍后再试")
raise LoginException(data="", message="账号已锁定,请稍后再试")
# 判断是否开启验证码,开启则验证,否则不验证
if login_user.captcha_enabled:
await cls.__check_login_captcha(request, login_user)
user = login_by_account(query_db, login_user.user_name)
if not user:
logger.warning("用户不存在")
raise LoginException(data="", message="用户不存在")
if not PwdUtil.verify_password(login_user.password, user[0].password):
cache_password_error_count = await request.app.state.redis.get(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}")
password_error_counted = 0
if cache_password_error_count:
password_error_counted = cache_password_error_count
password_error_count = int(password_error_counted) + 1
await request.app.state.redis.set(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}", password_error_count,
ex=timedelta(minutes=10))
if password_error_count > 5:
await request.app.state.redis.delete(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}")
await request.app.state.redis.set(
f"{RedisInitKeyConfig.ACCOUNT_LOCK.get('key')}:{login_user.user_name}", login_user.user_name,
ex=timedelta(minutes=10))
logger.warning("10分钟内密码已输错超过5次账号已锁定请10分钟后再试")
raise LoginException(data="", message="10分钟内密码已输错超过5次账号已锁定请10分钟后再试")
logger.warning("密码错误")
raise LoginException(data="", message="密码错误")
if user[0].status == '1':
logger.warning("用户已停用")
raise LoginException(data="", message="用户已停用")
await request.app.state.redis.delete(
f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}")
return user
@classmethod
async def __check_login_captcha(cls, request: Request, login_user: UserLogin):
"""
校验用户登录验证码
:param request: Request对象
:param login_user: 登录用户对象
:return: 校验结果
"""
captcha_value = await request.app.state.redis.get(
f"{RedisInitKeyConfig.CAPTCHA_CODES.get('key')}:{login_user.uuid}")
if not captcha_value:
logger.warning("验证码已失效")
raise LoginException(data="", message="验证码已失效")
if login_user.code != str(captcha_value):
logger.warning("验证码错误")
raise LoginException(data="", message="验证码错误")
return True
@classmethod
def create_access_token(cls, data: dict, expires_delta: Union[timedelta, None] = None):
"""
根据登录信息创建当前用户token
:param data: 登录信息
:param expires_delta: token有效期
:return: token
"""
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, JwtConfig.SECRET_KEY, algorithm=JwtConfig.ALGORITHM)
return encoded_jwt
@classmethod
async def get_current_user(cls, request: Request = Request, token: str = Depends(oauth2_scheme),
query_db: Session = Depends(get_db)):
"""
根据token获取当前用户信息
:param request: Request对象
:param token: 用户token
:param query_db: orm对象
:return: 当前用户信息对象
:raise: 令牌异常AuthException
"""
# if token[:6] != 'Bearer':
# logger.warning("用户token不合法")
# raise AuthException(data="", message="用户token不合法")
try:
if token.startswith('Bearer'):
token = token.split(' ')[1]
payload = jwt.decode(token, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM])
user_id: str = payload.get("user_id")
session_id: str = payload.get("session_id")
if user_id is None:
logger.warning("用户token不合法")
raise AuthException(data="", message="用户token不合法")
token_data = TokenData(user_id=int(user_id))
except JWTError:
logger.warning("用户token已失效请重新登录")
raise AuthException(data="", message="用户token已失效请重新登录")
query_user = UserDao.get_user_by_id(query_db, user_id=token_data.user_id)
if query_user.get('user_basic_info') is None:
logger.warning("用户token不合法")
raise AuthException(data="", message="用户token不合法")
redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}")
# 此方法可实现同一账号同一时间只能登录一次
# redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info.user_id}")
if token == redis_token:
await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", redis_token,
ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES))
# await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info.user_id}", redis_token,
# ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES))
role_id_list = [item.role_id for item in query_user.get('user_role_info')]
if 1 in role_id_list:
permissions = ['*:*:*']
else:
permissions = [row.perms for row in query_user.get('user_menu_info')]
post_ids = ','.join([str(row.post_id) for row in query_user.get('user_post_info')])
role_ids = ','.join([str(row.role_id) for row in query_user.get('user_role_info')])
roles = [row.role_key for row in query_user.get('user_role_info')]
current_user = CurrentUserModel(
permissions=permissions,
roles=roles,
user=UserInfoModel(
**CamelCaseUtil.transform_result(query_user.get('user_basic_info')),
postIds=post_ids,
roleIds=role_ids,
dept=CamelCaseUtil.transform_result(query_user.get('user_dept_info')),
role=CamelCaseUtil.transform_result(query_user.get('user_role_info'))
)
)
return current_user
else:
logger.warning("用户token已失效请重新登录")
raise AuthException(data="", message="用户token已失效请重新登录")
@classmethod
async def get_current_user_routers(cls, user_id: int, query_db: Session):
"""
根据用户id获取当前用户路由信息
:param user_id: 用户id
:param query_db: orm对象
:return: 当前用户路由信息对象
"""
query_user = UserDao.get_user_by_id(query_db, user_id=user_id)
user_router_menu = [row for row in query_user.get('user_menu_info') if row.menu_type in ['M', 'C']]
user_router = cls.__generate_user_router_menu(0, user_router_menu)
return user_router
@classmethod
def __generate_user_router_menu(cls, pid: int, permission_list):
"""
工具方法:根据菜单信息生成路由信息树形嵌套数据
:param pid: 菜单id
:param permission_list: 菜单列表信息
:return: 路由信息树形嵌套数据
"""
router_list = []
for permission in permission_list:
if permission.parent_id == pid:
children = cls.__generate_user_router_menu(permission.menu_id, permission_list)
router_list_data = {}
if permission.menu_type == 'M':
router_list_data['name'] = permission.path.capitalize()
router_list_data['path'] = f'/{permission.path}'
router_list_data['hidden'] = False if permission.visible == '0' else True
if permission.is_frame == 1:
router_list_data['redirect'] = 'noRedirect'
if permission.parent_id == 0:
router_list_data['component'] = 'Layout'
else:
router_list_data['component'] = 'ParentView'
if children:
router_list_data['alwaysShow'] = True
router_list_data['children'] = children
router_list_data['meta'] = {
'title': permission.menu_name,
'icon': permission.icon,
'noCache': False if permission.is_cache == '0' else True,
'link': permission.path if permission.is_frame == 0 else None
}
elif permission.menu_type == 'C':
router_list_data['name'] = permission.path.capitalize()
router_list_data['path'] = permission.path
router_list_data['hidden'] = False if permission.visible == '0' else True
router_list_data['component'] = permission.component
router_list_data['meta'] = {
'title': permission.menu_name,
'icon': permission.icon,
'noCache': False if permission.is_cache == '0' else True,
'link': permission.path if permission.is_frame == 0 else None
}
router_list.append(router_list_data)
return router_list
async def get_sms_code_services(request: Request, query_db: Session, user: ResetUserModel):
"""
获取短信验证码service
:param request: Request对象
:param query_db: orm对象
:param user: 用户对象
:return: 短信验证码对象
"""
redis_sms_result = await request.app.state.redis.get(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{user.session_id}")
if redis_sms_result:
return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='短信验证码仍在有效期内'))
is_user = UserDao.get_user_by_name(query_db, user.user_name)
if is_user:
sms_code = str(random.randint(100000, 999999))
session_id = str(uuid.uuid4())
await request.app.state.redis.set(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{session_id}", sms_code, ex=timedelta(minutes=2))
# 此处模拟调用短信服务
message_service(sms_code)
return SmsCode(**dict(is_success=True, sms_code=sms_code, session_id=session_id, message='获取成功'))
return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='用户不存在'))
async def forget_user_services(request: Request, query_db: Session, forget_user: ResetUserModel):
"""
用户忘记密码services
:param request: Request对象
:param query_db: orm对象
:param forget_user: 重置用户对象
:return: 重置结果
"""
redis_sms_result = await request.app.state.redis.get(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}")
if forget_user.sms_code == redis_sms_result:
forget_user.password = PwdUtil.get_password_hash(forget_user.password)
forget_user.user_id = UserDao.get_user_by_name(query_db, forget_user.user_name).user_id
edit_result = UserService.reset_user_services(query_db, forget_user)
result = edit_result.dict()
elif not redis_sms_result:
result = dict(is_success=False, message='短信验证码已过期')
else:
await request.app.state.redis.delete(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}")
result = dict(is_success=False, message='短信验证码不正确')
return CrudResponseModel(**result)
async def logout_services(request: Request, session_id: str):
"""
退出登录services
:param request: Request对象
:param session_id: 会话编号
:return: 退出登录结果
"""
await request.app.state.redis.delete(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}")
# await request.app.state.redis.delete(f'{current_user.user.user_id}_access_token')
# await request.app.state.redis.delete(f'{current_user.user.user_id}_session_id')
return True

View File

@@ -0,0 +1,171 @@
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.entity.vo.role_vo import RoleMenuQueryModel
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.dao.role_dao import RoleDao
from module_admin.dao.menu_dao import *
from utils.common_util import CamelCaseUtil
class MenuService:
"""
菜单管理模块服务层
"""
@classmethod
def get_menu_tree_services(cls, query_db: Session, current_user: Optional[CurrentUserModel] = None):
"""
获取菜单树信息service
:param query_db: orm对象
:param current_user: 当前用户对象
:return: 菜单树信息对象
"""
menu_list_result = MenuDao.get_menu_list_for_tree(query_db, current_user.user.user_id, current_user.user.role)
menu_tree_result = cls.list_to_tree(menu_list_result)
return menu_tree_result
@classmethod
def get_role_menu_tree_services(cls, query_db: Session, role_id: int, current_user: Optional[CurrentUserModel] = None):
"""
根据角色id获取菜单树信息service
:param query_db: orm对象
:param role_id: 角色id
:param current_user: 当前用户对象
:return: 当前角色id的菜单树信息对象
"""
menu_list_result = MenuDao.get_menu_list_for_tree(query_db, current_user.user.user_id, current_user.user.role)
menu_tree_result = cls.list_to_tree(menu_list_result)
role_menu_list = RoleDao.get_role_menu_dao(query_db, role_id)
checked_keys = [row.menu_id for row in role_menu_list]
result = RoleMenuQueryModel(
menus=menu_tree_result,
checkedKeys=checked_keys
)
return result
@classmethod
def get_menu_list_services(cls, query_db: Session, page_object: MenuQueryModel, current_user: Optional[CurrentUserModel] = None):
"""
获取菜单列表信息service
:param query_db: orm对象
:param page_object: 分页查询参数对象
:param current_user: 当前用户对象
:return: 菜单列表信息对象
"""
menu_list_result = MenuDao.get_menu_list(query_db, page_object, current_user.user.user_id, current_user.user.role)
return CamelCaseUtil.transform_result(menu_list_result)
@classmethod
def add_menu_services(cls, query_db: Session, page_object: MenuModel):
"""
新增菜单信息service
:param query_db: orm对象
:param page_object: 新增菜单对象
:return: 新增菜单校验结果
"""
menu = MenuDao.get_menu_detail_by_info(query_db, MenuModel(parentId=page_object.parent_id, menuName=page_object.menu_name, menuType=page_object.menu_type))
if menu:
result = dict(is_success=False, message='同一目录下不允许存在同名同类型的菜单')
else:
try:
MenuDao.add_menu_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_menu_services(cls, query_db: Session, page_object: MenuModel):
"""
编辑菜单信息service
:param query_db: orm对象
:param page_object: 编辑部门对象
:return: 编辑菜单校验结果
"""
edit_menu = page_object.model_dump(exclude_unset=True)
menu_info = cls.menu_detail_services(query_db, edit_menu.get('menu_id'))
if menu_info:
if menu_info.parent_id != page_object.parent_id or menu_info.menu_name != page_object.menu_name or menu_info.menu_type != page_object.menu_type:
menu = MenuDao.get_menu_detail_by_info(query_db, MenuModel(parentId=page_object.parent_id, menuName=page_object.menu_name, menuType=page_object.menu_type))
if menu:
result = dict(is_success=False, message='同一目录下不允许存在同名同类型的菜单')
return CrudResponseModel(**result)
try:
MenuDao.edit_menu_dao(query_db, edit_menu)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='菜单不存在')
return CrudResponseModel(**result)
@classmethod
def delete_menu_services(cls, query_db: Session, page_object: DeleteMenuModel):
"""
删除菜单信息service
:param query_db: orm对象
:param page_object: 删除菜单对象
:return: 删除菜单校验结果
"""
if page_object.menu_ids.split(','):
menu_id_list = page_object.menu_ids.split(',')
try:
for menu_id in menu_id_list:
MenuDao.delete_menu_dao(query_db, MenuModel(menuId=menu_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入菜单id为空')
return CrudResponseModel(**result)
@classmethod
def menu_detail_services(cls, query_db: Session, menu_id: int):
"""
获取菜单详细信息service
:param query_db: orm对象
:param menu_id: 菜单id
:return: 菜单id对应的信息
"""
menu = MenuDao.get_menu_detail_by_id(query_db, menu_id=menu_id)
result = MenuModel(**CamelCaseUtil.transform_result(menu))
return result
@classmethod
def list_to_tree(cls, permission_list: list) -> list:
"""
工具方法:根据菜单列表信息生成树形嵌套数据
:param permission_list: 菜单列表信息
:return: 菜单树形嵌套数据
"""
permission_list = [dict(id=item.menu_id, label=item.menu_name, parentId=item.parent_id) for item in permission_list]
# 转成id为key的字典
mapping: dict = dict(zip([i['id'] for i in permission_list], permission_list))
# 树容器
container: list = []
for d in permission_list:
# 如果找不到父级项,则是根节点
parent: dict = mapping.get(d['parentId'])
if parent is None:
container.append(d)
else:
children: list = parent.get('children')
if not children:
children = []
children.append(d)
parent.update({'children': children})
return container

View File

@@ -0,0 +1,106 @@
from module_admin.dao.notice_dao import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
class NoticeService:
"""
通知公告管理模块服务层
"""
@classmethod
def get_notice_list_services(cls, query_db: Session, query_object: NoticeQueryModel):
"""
获取通知公告列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 通知公告列表信息对象
"""
notice_list_result = NoticeDao.get_notice_list(query_db, query_object)
return CamelCaseUtil.transform_result(notice_list_result)
@classmethod
def add_notice_services(cls, query_db: Session, page_object: NoticeModel):
"""
新增通知公告信息service
:param query_db: orm对象
:param page_object: 新增通知公告对象
:return: 新增通知公告校验结果
"""
notice = NoticeDao.get_notice_detail_by_info(query_db, page_object)
if notice:
result = dict(is_success=False, message='通知公告已存在')
else:
try:
NoticeDao.add_notice_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_notice_services(cls, query_db: Session, page_object: NoticeModel):
"""
编辑通知公告信息service
:param query_db: orm对象
:param page_object: 编辑通知公告对象
:return: 编辑通知公告校验结果
"""
edit_notice = page_object.model_dump(exclude_unset=True)
notice_info = cls.notice_detail_services(query_db, edit_notice.get('notice_id'))
if notice_info:
if notice_info.notice_title != page_object.notice_title or notice_info.notice_type != page_object.notice_type or notice_info.notice_content != page_object.notice_content:
notice = NoticeDao.get_notice_detail_by_info(query_db, page_object)
if notice:
result = dict(is_success=False, message='通知公告已存在')
return CrudResponseModel(**result)
try:
NoticeDao.edit_notice_dao(query_db, edit_notice)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='通知公告不存在')
return CrudResponseModel(**result)
@classmethod
def delete_notice_services(cls, query_db: Session, page_object: DeleteNoticeModel):
"""
删除通知公告信息service
:param query_db: orm对象
:param page_object: 删除通知公告对象
:return: 删除通知公告校验结果
"""
if page_object.notice_ids.split(','):
notice_id_list = page_object.notice_ids.split(',')
try:
for notice_id in notice_id_list:
NoticeDao.delete_notice_dao(query_db, NoticeModel(noticeId=notice_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入通知公告id为空')
return CrudResponseModel(**result)
@classmethod
def notice_detail_services(cls, query_db: Session, notice_id: int):
"""
获取通知公告详细信息service
:param query_db: orm对象
:param notice_id: 通知公告id
:return: 通知公告id对应的信息
"""
notice = NoticeDao.get_notice_detail_by_id(query_db, notice_id=notice_id)
result = NoticeModel(**CamelCaseUtil.transform_result(notice))
return result

View File

@@ -0,0 +1,71 @@
from fastapi import Request
from jose import jwt
from config.env import JwtConfig, RedisInitKeyConfig
from module_admin.entity.vo.online_vo import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import CamelCaseUtil
class OnlineService:
"""
在线用户管理模块服务层
"""
@classmethod
async def get_online_list_services(cls, request: Request, query_object: OnlineQueryModel):
"""
获取在线用户表信息service
:param request: Request对象
:param query_object: 查询参数对象
:return: 在线用户列表信息
"""
access_token_keys = await request.app.state.redis.keys(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}*")
if not access_token_keys:
access_token_keys = []
access_token_values_list = [await request.app.state.redis.get(key) for key in access_token_keys]
online_info_list = []
for item in access_token_values_list:
payload = jwt.decode(item, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM])
online_dict = dict(
token_id=payload.get('session_id'),
user_name=payload.get('user_name'),
dept_name=payload.get('dept_name'),
ipaddr=payload.get('login_info').get('ipaddr'),
login_location=payload.get('login_info').get('loginLocation'),
browser=payload.get('login_info').get('browser'),
os=payload.get('login_info').get('os'),
login_time=payload.get('login_info').get('loginTime')
)
if query_object.user_name and not query_object.ipaddr:
if query_object.user_name == payload.get('login_info').get('ipaddr'):
online_info_list = [online_dict]
break
elif not query_object.user_name and query_object.ipaddr:
if query_object.ipaddr == payload.get('ipaddr'):
online_info_list = [online_dict]
break
elif query_object.user_name and query_object.ipaddr:
if query_object.user_name == payload.get('user_name') and query_object.ipaddr == payload.get('login_info').get('ipaddr'):
online_info_list = [online_dict]
break
else:
online_info_list.append(online_dict)
return CamelCaseUtil.transform_result(online_info_list)
@classmethod
async def delete_online_services(cls, request: Request, page_object: DeleteOnlineModel):
"""
强退在线用户信息service
:param request: Request对象
:param page_object: 强退在线用户对象
:return: 强退在线用户校验结果
"""
if page_object.token_ids.split(','):
token_id_list = page_object.token_ids.split(',')
for token_id in token_id_list:
await request.app.state.redis.delete(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{token_id}")
result = dict(is_success=True, message='强退成功')
else:
result = dict(is_success=False, message='传入session_id为空')
return CrudResponseModel(**result)

View File

@@ -0,0 +1,138 @@
from module_admin.dao.post_dao import *
from module_admin.entity.vo.common_vo import CrudResponseModel
from utils.common_util import export_list2excel, CamelCaseUtil
class PostService:
"""
岗位管理模块服务层
"""
@classmethod
def get_post_list_services(cls, query_db: Session, query_object: PostModel):
"""
获取岗位列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 岗位列表信息对象
"""
post_list_result = PostDao.get_post_list(query_db, query_object)
return CamelCaseUtil.transform_result(post_list_result)
@classmethod
def add_post_services(cls, query_db: Session, page_object: PostModel):
"""
新增岗位信息service
:param query_db: orm对象
:param page_object: 新增岗位对象
:return: 新增岗位校验结果
"""
post = PostDao.get_post_detail_by_info(query_db, PostModel(postName=page_object.post_name))
if post:
result = dict(is_success=False, message='岗位名称已存在')
else:
try:
PostDao.add_post_dao(query_db, page_object)
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_post_services(cls, query_db: Session, page_object: PostModel):
"""
编辑岗位信息service
:param query_db: orm对象
:param page_object: 编辑岗位对象
:return: 编辑岗位校验结果
"""
edit_post = page_object.model_dump(exclude_unset=True)
post_info = cls.post_detail_services(query_db, edit_post.get('post_id'))
if post_info:
if post_info.post_name != page_object.post_name:
post = PostDao.get_post_detail_by_info(query_db, PostModel(postName=page_object.post_name))
if post:
result = dict(is_success=False, message='岗位名称已存在')
return CrudResponseModel(**result)
try:
PostDao.edit_post_dao(query_db, edit_post)
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='岗位不存在')
return CrudResponseModel(**result)
@classmethod
def delete_post_services(cls, query_db: Session, page_object: DeletePostModel):
"""
删除岗位信息service
:param query_db: orm对象
:param page_object: 删除岗位对象
:return: 删除岗位校验结果
"""
if page_object.post_ids.split(','):
post_id_list = page_object.post_ids.split(',')
try:
for post_id in post_id_list:
PostDao.delete_post_dao(query_db, PostModel(postId=post_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入岗位id为空')
return CrudResponseModel(**result)
@classmethod
def post_detail_services(cls, query_db: Session, post_id: int):
"""
获取岗位详细信息service
:param query_db: orm对象
:param post_id: 岗位id
:return: 岗位id对应的信息
"""
post = PostDao.get_post_detail_by_id(query_db, post_id=post_id)
result = PostModel(**CamelCaseUtil.transform_result(post))
return result
@staticmethod
def export_post_list_services(post_list: List):
"""
导出岗位信息service
:param post_list: 岗位信息列表
:return: 岗位信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"postId": "岗位编号",
"postCode": "岗位编码",
"postName": "岗位名称",
"postSort": "显示顺序",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
}
data = post_list
for item in data:
if item.get('status') == '0':
item['status'] = '正常'
else:
item['status'] = '停用'
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data]
binary_data = export_list2excel(new_data)
return binary_data

View File

@@ -0,0 +1,256 @@
from module_admin.entity.vo.user_vo import UserInfoModel, UserRoleQueryModel
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.dao.user_dao import UserDao
from module_admin.dao.role_dao import *
from utils.common_util import export_list2excel, CamelCaseUtil
class RoleService:
"""
角色管理模块服务层
"""
@classmethod
def get_role_select_option_services(cls, query_db: Session):
"""
获取角色列表不分页信息service
:param query_db: orm对象
:return: 角色列表不分页信息对象
"""
role_list_result = RoleDao.get_role_select_option_dao(query_db)
return CamelCaseUtil.transform_result(role_list_result)
@classmethod
def get_role_dept_tree_services(cls, query_db: Session, role_id: int):
"""
根据角色id获取部门树信息service
:param query_db: orm对象
:param role_id: 角色id
:return: 当前角色id的部门树信息对象
"""
role_dept_list = RoleDao.get_role_dept_dao(query_db, role_id)
checked_keys = [row.dept_id for row in role_dept_list]
result = RoleDeptQueryModel(
checkedKeys=checked_keys
)
return result
@classmethod
def get_role_list_services(cls, query_db: Session, query_object: RoleQueryModel):
"""
获取角色列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:return: 角色列表信息对象
"""
role_list_result = RoleDao.get_role_list(query_db, query_object)
return CamelCaseUtil.transform_result(role_list_result)
@classmethod
def add_role_services(cls, query_db: Session, page_object: AddRoleModel):
"""
新增角色信息service
:param query_db: orm对象
:param page_object: 新增角色对象
:return: 新增角色校验结果
"""
add_role = RoleModel(**page_object.model_dump(by_alias=True))
role_name = RoleDao.get_role_by_info(query_db, RoleModel(roleName=page_object.role_name))
role_key = RoleDao.get_role_by_info(query_db, RoleModel(roleKey=page_object.role_key))
if role_name:
result = dict(is_success=False, message='角色名称已存在')
elif role_key:
result = dict(is_success=False, message='权限字符已存在')
else:
try:
add_result = RoleDao.add_role_dao(query_db, add_role)
role_id = add_result.role_id
if page_object.menu_ids:
for menu in page_object.menu_ids:
RoleDao.add_role_menu_dao(query_db, RoleMenuModel(roleId=role_id, menuId=menu))
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_role_services(cls, query_db: Session, page_object: AddRoleModel):
"""
编辑角色信息service
:param query_db: orm对象
:param page_object: 编辑角色对象
:return: 编辑角色校验结果
"""
edit_role = page_object.model_dump(exclude_unset=True)
if page_object.type != 'status':
del edit_role['menu_ids']
if page_object.type == 'status':
del edit_role['type']
role_info = cls.role_detail_services(query_db, edit_role.get('role_id'))
if role_info:
if page_object.type != 'status' and role_info.role_name != page_object.role_name:
role_name = RoleDao.get_role_by_info(query_db, RoleModel(roleName=page_object.role_name))
if role_name:
result = dict(is_success=False, message='角色名称已存在')
return CrudResponseModel(**result)
elif page_object.type != 'status' and role_info.role_key != page_object.role_key:
role_key = RoleDao.get_role_by_info(query_db, RoleModel(roleKey=page_object.role_key))
if role_key:
result = dict(is_success=False, message='权限字符已存在')
return CrudResponseModel(**result)
try:
RoleDao.edit_role_dao(query_db, edit_role)
if page_object.type != 'status':
RoleDao.delete_role_menu_dao(query_db, RoleMenuModel(roleId=page_object.role_id))
if page_object.menu_ids:
for menu in page_object.menu_ids:
RoleDao.add_role_menu_dao(query_db, RoleMenuModel(roleId=page_object.role_id, menuId=menu))
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='角色不存在')
return CrudResponseModel(**result)
@classmethod
def role_datascope_services(cls, query_db: Session, page_object: AddRoleModel):
"""
分配角色数据权限service
:param query_db: orm对象
:param page_object: 角色数据权限对象
:return: 分配角色数据权限结果
"""
edit_role = page_object.model_dump(exclude_unset=True)
del edit_role['dept_ids']
role_info = cls.role_detail_services(query_db, edit_role.get('role_id'))
if role_info:
if role_info.role_name != page_object.role_name:
role_name = RoleDao.get_role_by_info(query_db, RoleModel(roleName=page_object.role_name))
if role_name:
result = dict(is_success=False, message='角色名称已存在')
return CrudResponseModel(**result)
elif role_info.role_key != page_object.role_key:
role_key = RoleDao.get_role_by_info(query_db, RoleModel(roleKey=page_object.role_key))
if role_key:
result = dict(is_success=False, message='权限字符已存在')
return CrudResponseModel(**result)
try:
RoleDao.edit_role_dao(query_db, edit_role)
RoleDao.delete_role_dept_dao(query_db, RoleDeptModel(roleId=page_object.role_id))
if page_object.dept_ids and page_object.data_scope == '2':
for dept in page_object.dept_ids:
RoleDao.add_role_dept_dao(query_db, RoleDeptModel(roleId=page_object.role_id, deptId=dept))
query_db.commit()
result = dict(is_success=True, message='分配成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='角色不存在')
return CrudResponseModel(**result)
@classmethod
def delete_role_services(cls, query_db: Session, page_object: DeleteRoleModel):
"""
删除角色信息service
:param query_db: orm对象
:param page_object: 删除角色对象
:return: 删除角色校验结果
"""
if page_object.role_ids.split(','):
role_id_list = page_object.role_ids.split(',')
try:
for role_id in role_id_list:
role_id_dict = dict(roleId=role_id, updateBy=page_object.update_by, updateTime=page_object.update_time)
RoleDao.delete_role_menu_dao(query_db, RoleMenuModel(**role_id_dict))
RoleDao.delete_role_dao(query_db, RoleModel(**role_id_dict))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入角色id为空')
return CrudResponseModel(**result)
@classmethod
def role_detail_services(cls, query_db: Session, role_id: int):
"""
获取角色详细信息service
:param query_db: orm对象
:param role_id: 角色id
:return: 角色id对应的信息
"""
role = RoleDao.get_role_detail_by_id(query_db, role_id=role_id)
result = RoleModel(**CamelCaseUtil.transform_result(role))
return result
@staticmethod
def export_role_list_services(role_list: List):
"""
导出角色列表信息service
:param role_list: 角色信息列表
:return: 角色列表信息对象
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"roleId": "角色编号",
"roleName": "角色名称",
"roleKey": "权限字符",
"roleSort": "显示顺序",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
}
data = role_list
for item in data:
if item.get('status') == '0':
item['status'] = '正常'
else:
item['status'] = '停用'
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data]
binary_data = export_list2excel(new_data)
return binary_data
@classmethod
def get_role_user_allocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel):
"""
根据角色id获取已分配用户列表
:param query_db: orm对象
:param page_object: 用户关联角色对象
:return: 已分配用户列表
"""
query_user_list = UserDao.get_user_role_allocated_list_by_role_id(query_db, page_object)
allocated_list = [UserInfoModel(**CamelCaseUtil.transform_result(row)) for row in query_user_list]
return allocated_list
@classmethod
def get_role_user_unallocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel):
"""
根据角色id获取未分配用户列表
:param query_db: orm对象
:param page_object: 用户关联角色对象
:return: 未分配用户列表
"""
query_user_list = UserDao.get_user_role_unallocated_list_by_role_id(query_db, page_object)
unallocated_list = [UserInfoModel(**CamelCaseUtil.transform_result(row)) for row in query_user_list]
return unallocated_list

View File

@@ -0,0 +1,94 @@
import psutil
from utils.common_util import bytes2human
import platform
import socket
import os
import time
from module_admin.entity.vo.server_vo import *
class ServerService:
"""
服务监控模块服务层
"""
@staticmethod
def get_server_monitor_info():
# CPU信息
# 获取CPU总核心数
cpu_num = psutil.cpu_count(logical=True)
cpu_usage_percent = psutil.cpu_times_percent()
cpu_used = cpu_usage_percent.user
cpu_sys = cpu_usage_percent.system
cpu_free = cpu_usage_percent.idle
cpu = CpuInfo(cpuNum=cpu_num, used=cpu_used, sys=cpu_sys, free=cpu_free)
# 内存信息
memory_info = psutil.virtual_memory()
memory_total = bytes2human(memory_info.total)
memory_used = bytes2human(memory_info.used)
memory_free = bytes2human(memory_info.free)
memory_usage = memory_info.percent
mem = MemoryInfo(total=memory_total, used=memory_used, free=memory_free, usage=memory_usage)
# 主机信息
# 获取主机名
hostname = socket.gethostname()
# 获取IP
computer_ip = socket.gethostbyname(hostname)
os_name = platform.platform()
computer_name = platform.node()
os_arch = platform.machine()
user_dir = os.path.abspath(os.getcwd())
sys = SysInfo(computerIp=computer_ip, computerName=computer_name, osArch=os_arch, osName=os_name, userDir=user_dir)
# python解释器信息
current_pid = os.getpid()
current_process = psutil.Process(current_pid)
python_name = current_process.name()
python_version = platform.python_version()
python_home = current_process.exe()
start_time_stamp = current_process.create_time()
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start_time_stamp))
current_time_stamp = time.time()
difference = current_time_stamp - start_time_stamp
# 将时间差转换为天、小时和分钟数
days = int(difference // (24 * 60 * 60)) # 每天的秒数
hours = int((difference % (24 * 60 * 60)) // (60 * 60)) # 每小时的秒数
minutes = int((difference % (60 * 60)) // 60) # 每分钟的秒数
run_time = f"{days}{hours}小时{minutes}分钟"
# 获取当前Python程序的pid
pid = os.getpid()
# 获取该进程的内存信息
current_process_memory_info = psutil.Process(pid).memory_info()
py = PyInfo(
name=python_name,
version=python_version,
startTime=start_time,
runTime=run_time,
home=python_home,
total=bytes2human(memory_info.available),
used=bytes2human(current_process_memory_info.rss),
free=bytes2human(memory_info.available - current_process_memory_info.rss),
usage=round((current_process_memory_info.rss / memory_info.available) * 100, 2)
)
# 磁盘信息
io = psutil.disk_partitions()
sys_files = []
for i in io:
o = psutil.disk_usage(i.device)
disk_data = SysFiles(
dirName=i.device,
sysTypeName=i.fstype,
typeName="本地固定磁盘(" + i.mountpoint.replace('\\', '') + "",
total=bytes2human(o.total),
used=bytes2human(o.used),
free=bytes2human(o.free),
usage=f'{psutil.disk_usage(i.device).percent}%'
)
sys_files.append(disk_data)
result = ServerMonitorModel(cpu=cpu, mem=mem, sys=sys, py=py, sysFiles=sys_files)
return result

View File

@@ -0,0 +1,475 @@
from fastapi import UploadFile
from module_admin.service.role_service import RoleService
from module_admin.service.post_service import PostService
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.dao.user_dao import *
from utils.pwd_util import *
from utils.common_util import *
class UserService:
"""
用户管理模块服务层
"""
@classmethod
def get_user_list_services(cls, query_db: Session, query_object: UserQueryModel, data_scope_sql: str):
"""
获取用户列表信息service
:param query_db: orm对象
:param query_object: 查询参数对象
:param data_scope_sql: 数据权限对应的查询sql语句
:return: 用户列表信息对象
"""
query_result = UserDao.get_user_list(query_db, query_object, data_scope_sql)
user_list_result = []
if query_result:
user_list_result = [{**CamelCaseUtil.transform_result(row[0]), 'dept': CamelCaseUtil.transform_result(row[1])} for row in query_result]
return user_list_result
@classmethod
def add_user_services(cls, query_db: Session, page_object: AddUserModel):
"""
新增用户信息service
:param query_db: orm对象
:param page_object: 新增用户对象
:return: 新增用户校验结果
"""
add_user = UserModel(**page_object.model_dump(by_alias=True))
user = UserDao.get_user_by_info(query_db, UserModel(userName=page_object.user_name))
if user:
result = dict(is_success=False, message='用户名已存在')
else:
try:
add_result = UserDao.add_user_dao(query_db, add_user)
user_id = add_result.user_id
if page_object.role_ids:
for role in page_object.role_ids:
UserDao.add_user_role_dao(query_db, UserRoleModel(userId=user_id, roleId=role))
if page_object.post_ids:
for post in page_object.post_ids:
UserDao.add_user_post_dao(query_db, UserPostModel(userId=user_id, postId=post))
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
def edit_user_services(cls, query_db: Session, page_object: EditUserModel):
"""
编辑用户信息service
:param query_db: orm对象
:param page_object: 编辑用户对象
:return: 编辑用户校验结果
"""
edit_user = page_object.model_dump(exclude_unset=True)
if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type != 'pwd':
del edit_user['role_ids']
del edit_user['post_ids']
del edit_user['role']
if page_object.type == 'status' or page_object.type == 'avatar' or page_object.type == 'pwd':
del edit_user['type']
user_info = cls.user_detail_services(query_db, edit_user.get('user_id'))
if user_info:
if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type == 'pwd' and user_info.data.user_name != page_object.user_name:
user = UserDao.get_user_by_info(query_db, UserModel(userName=page_object.user_name))
if user:
result = dict(is_success=False, message='用户名已存在')
return CrudResponseModel(**result)
try:
UserDao.edit_user_dao(query_db, edit_user)
if page_object.type != 'status' and page_object.type != 'avatar':
UserDao.delete_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
UserDao.delete_user_post_dao(query_db, UserPostModel(userId=page_object.user_id))
if page_object.role_ids:
for role in page_object.role_ids:
UserDao.add_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=role))
if page_object.post_ids:
for post in page_object.post_ids:
UserDao.add_user_post_dao(query_db, UserPostModel(userId=page_object.user_id, postId=post))
query_db.commit()
result = dict(is_success=True, message='更新成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='用户不存在')
return CrudResponseModel(**result)
@classmethod
def delete_user_services(cls, query_db: Session, page_object: DeleteUserModel):
"""
删除用户信息service
:param query_db: orm对象
:param page_object: 删除用户对象
:return: 删除用户校验结果
"""
if page_object.user_ids.split(','):
user_id_list = page_object.user_ids.split(',')
try:
for user_id in user_id_list:
user_id_dict = dict(userId=user_id, updateBy=page_object.update_by, updateTime=page_object.update_time)
UserDao.delete_user_role_dao(query_db, UserRoleModel(**user_id_dict))
UserDao.delete_user_post_dao(query_db, UserPostModel(**user_id_dict))
UserDao.delete_user_dao(query_db, UserModel(**user_id_dict))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='传入用户id为空')
return CrudResponseModel(**result)
@classmethod
def user_detail_services(cls, query_db: Session, user_id: Union[int, str]):
"""
获取用户详细信息service
:param query_db: orm对象
:param user_id: 用户id
:return: 用户id对应的信息
"""
posts = PostService.get_post_list_services(query_db, PostModel(**{}))
roles = RoleService.get_role_select_option_services(query_db)
if user_id != '':
query_user = UserDao.get_user_detail_by_id(query_db, user_id=user_id)
post_ids = ','.join([str(row.post_id) for row in query_user.get('user_post_info')])
post_ids_list = [row.post_id for row in query_user.get('user_post_info')]
role_ids = ','.join([str(row.role_id) for row in query_user.get('user_role_info')])
role_ids_list = [row.role_id for row in query_user.get('user_role_info')]
return UserDetailModel(
data=UserInfoModel(
**CamelCaseUtil.transform_result(query_user.get('user_basic_info')),
postIds=post_ids,
roleIds=role_ids,
dept=CamelCaseUtil.transform_result(query_user.get('user_dept_info')),
role=CamelCaseUtil.transform_result(query_user.get('user_role_info'))
),
postIds=post_ids_list,
posts=posts,
roleIds=role_ids_list,
roles=roles
)
return UserDetailModel(
posts=posts,
roles=roles
)
@classmethod
def user_profile_services(cls, query_db: Session, user_id: int):
"""
获取用户详细信息service
:param query_db: orm对象
:param user_id: 用户id
:return: 用户id对应的信息
"""
query_user = UserDao.get_user_detail_by_id(query_db, user_id=user_id)
post_ids = ','.join([str(row.post_id) for row in query_user.get('user_post_info')])
post_group = ','.join([row.post_name for row in query_user.get('user_post_info')])
role_ids = ','.join([str(row.role_id) for row in query_user.get('user_role_info')])
role_group = ','.join([row.role_name for row in query_user.get('user_role_info')])
return UserProfileModel(
data=UserInfoModel(
**CamelCaseUtil.transform_result(query_user.get('user_basic_info')),
postIds=post_ids,
roleIds=role_ids,
dept=CamelCaseUtil.transform_result(query_user.get('user_dept_info')),
role=CamelCaseUtil.transform_result(query_user.get('user_role_info'))
),
postGroup=post_group,
roleGroup=role_group
)
@classmethod
def reset_user_services(cls, query_db: Session, page_object: ResetUserModel):
"""
重置用户密码service
:param query_db: orm对象
:param page_object: 重置用户对象
:return: 重置用户校验结果
"""
reset_user = page_object.model_dump(exclude_unset=True)
if page_object.old_password:
user = UserDao.get_user_detail_by_id(query_db, user_id=page_object.user_id).get('user_basic_info')
if not PwdUtil.verify_password(page_object.old_password, user.password):
result = dict(is_success=False, message='旧密码不正确')
return CrudResponseModel(**result)
else:
del reset_user['old_password']
if page_object.sms_code and page_object.session_id:
del reset_user['sms_code']
del reset_user['session_id']
try:
UserDao.edit_user_dao(query_db, reset_user)
query_db.commit()
result = dict(is_success=True, message='重置成功')
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@classmethod
async def batch_import_user_services(cls, query_db: Session, file: UploadFile, update_support: bool, current_user: CurrentUserModel):
"""
批量导入用户service
:param query_db: orm对象
:param file: 用户导入文件对象
:param update_support: 用户存在时是否更新
:param current_user: 当前用户对象
:return: 批量导入用户结果
"""
header_dict = {
"部门编号": "dept_id",
"登录名称": "user_name",
"用户名称": "nick_name",
"用户邮箱": "email",
"手机号码": "phonenumber",
"用户性别": "sex",
"帐号状态": "status"
}
contents = await file.read()
df = pd.read_excel(io.BytesIO(contents))
await file.close()
df.rename(columns=header_dict, inplace=True)
add_error_result = []
count = 0
try:
for index, row in df.iterrows():
count = count + 1
if row['sex'] == '':
row['sex'] = '0'
if row['sex'] == '':
row['sex'] = '1'
if row['sex'] == '未知':
row['sex'] = '2'
if row['status'] == '正常':
row['status'] = '0'
if row['status'] == '停用':
row['status'] = '1'
add_user = UserModel(
deptId=row['dept_id'],
userName=row['user_name'],
password=PwdUtil.get_password_hash('123456'),
nickName=row['nick_name'],
email=row['email'],
phonenumber=str(row['phonenumber']),
sex=row['sex'],
status=row['status'],
createBy=current_user.user.user_name,
updateBy=current_user.user.user_name
)
user_info = UserDao.get_user_by_info(query_db, UserModel(userName=row['user_name']))
if user_info:
if update_support:
edit_user = UserModel(
userId=user_info.user_id,
deptId=row['dept_id'],
userName=row['user_name'],
nickName=row['nick_name'],
email=row['email'],
phonenumber=str(row['phonenumber']),
sex=row['sex'],
status=row['status'],
updateBy=current_user.user.user_name
).model_dump(exclude_unset=True)
UserDao.edit_user_dao(query_db, edit_user)
else:
add_error_result.append(f"{count}.用户账号{row['user_name']}已存在")
else:
UserDao.add_user_dao(query_db, add_user)
query_db.commit()
result = dict(is_success=True, message='\n'.join(add_error_result))
except Exception as e:
query_db.rollback()
raise e
return CrudResponseModel(**result)
@staticmethod
def get_user_import_template_services():
"""
获取用户导入模板service
:return: 用户导入模板excel的二进制数据
"""
header_list = ["部门编号", "登录名称", "用户名称", "用户邮箱", "手机号码", "用户性别", "帐号状态"]
selector_header_list = ["用户性别", "帐号状态"]
option_list = [{"用户性别": ["", "", "未知"]}, {"帐号状态": ["正常", "停用"]}]
binary_data = get_excel_template(header_list=header_list, selector_header_list=selector_header_list, option_list=option_list)
return binary_data
@staticmethod
def export_user_list_services(user_list: List):
"""
导出用户信息service
:param user_list: 用户信息列表
:return: 用户信息对应excel的二进制数据
"""
# 创建一个映射字典,将英文键映射到中文键
mapping_dict = {
"userId": "用户编号",
"userName": "用户名称",
"nickName": "用户昵称",
"deptName": "部门",
"email": "邮箱地址",
"phonenumber": "手机号码",
"sex": "性别",
"status": "状态",
"createBy": "创建者",
"createTime": "创建时间",
"updateBy": "更新者",
"updateTime": "更新时间",
"remark": "备注",
}
data = user_list
for item in data:
if item.get('status') == '0':
item['status'] = '正常'
else:
item['status'] = '停用'
if item.get('sex') == '0':
item['sex'] = ''
elif item.get('sex') == '1':
item['sex'] = ''
else:
item['sex'] = '未知'
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data]
binary_data = export_list2excel(new_data)
return binary_data
@classmethod
def get_user_role_allocated_list_services(cls, query_db: Session, page_object: UserRoleQueryModel):
"""
根据用户id获取已分配角色列表
:param query_db: orm对象
:param page_object: 用户关联角色对象
:return: 已分配角色列表
"""
query_user = UserDao.get_user_detail_by_id(query_db, page_object.user_id)
post_ids = ','.join([str(row.post_id) for row in query_user.get('user_post_info')])
role_ids = ','.join([str(row.role_id) for row in query_user.get('user_role_info')])
user = UserInfoModel(
**CamelCaseUtil.transform_result(query_user.get('user_basic_info')),
postIds=post_ids,
roleIds=role_ids,
dept=CamelCaseUtil.transform_result(query_user.get('user_dept_info')),
role=CamelCaseUtil.transform_result(query_user.get('user_role_info'))
)
query_role_list = [SelectedRoleModel(**row) for row in RoleService.get_role_select_option_services(query_db)]
for model_a in query_role_list:
for model_b in user.role:
if model_a.role_id == model_b.role_id:
model_a.flag = True
result = UserRoleResponseModel(
roles=query_role_list,
user=user
)
return result
@classmethod
def add_user_role_services(cls, query_db: Session, page_object: CrudUserRoleModel):
"""
新增用户关联角色信息service
:param query_db: orm对象
:param page_object: 新增用户关联角色对象
:return: 新增用户关联角色校验结果
"""
if page_object.user_id and page_object.role_ids:
role_id_list = page_object.role_ids.split(',')
try:
for role_id in role_id_list:
user_role = cls.detail_user_role_services(query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id))
if user_role:
continue
else:
UserDao.add_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=role_id))
query_db.commit()
result = dict(is_success=True, message='分配成功')
except Exception as e:
query_db.rollback()
raise e
elif page_object.user_id and not page_object.role_ids:
try:
UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
query_db.commit()
result = dict(is_success=True, message='分配成功')
except Exception as e:
query_db.rollback()
raise e
elif page_object.user_ids and page_object.role_id:
user_id_list = page_object.user_ids.split(',')
try:
for user_id in user_id_list:
user_role = cls.detail_user_role_services(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id))
if user_role:
continue
else:
UserDao.add_user_role_dao(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id))
query_db.commit()
result = dict(is_success=True, message='新增成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='不满足新增条件')
return CrudResponseModel(**result)
@classmethod
def delete_user_role_services(cls, query_db: Session, page_object: CrudUserRoleModel):
"""
删除用户关联角色信息service
:param query_db: orm对象
:param page_object: 删除用户关联角色对象
:return: 删除用户关联角色校验结果
"""
if (page_object.user_id and page_object.role_id) or (page_object.user_ids and page_object.role_id):
if page_object.user_id and page_object.role_id:
try:
UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=page_object.user_id, roleId=page_object.role_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
elif page_object.user_ids and page_object.role_id:
user_id_list = page_object.user_ids.split(',')
try:
for user_id in user_id_list:
UserDao.delete_user_role_by_user_and_role_dao(query_db, UserRoleModel(userId=user_id, roleId=page_object.role_id))
query_db.commit()
result = dict(is_success=True, message='删除成功')
except Exception as e:
query_db.rollback()
raise e
else:
result = dict(is_success=False, message='不满足删除条件')
else:
result = dict(is_success=False, message='传入用户角色关联信息为空')
return CrudResponseModel(**result)
@classmethod
def detail_user_role_services(cls, query_db: Session, page_object: UserRoleModel):
"""
获取用户关联角色详细信息service
:param query_db: orm对象
:param page_object: 用户关联角色对象
:return: 用户关联角色详细信息
"""
user_role = UserDao.get_user_role_detail(query_db, page_object)
return user_role

View File

@@ -0,0 +1 @@
from . import scheduler_test

View File

@@ -0,0 +1,7 @@
from datetime import datetime
def job(*args, **kwargs):
print(args)
print(kwargs)
print(f"{datetime.now()}执行了")

View File

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

View File

@@ -0,0 +1,184 @@
import pandas as pd
import io
import os
from openpyxl import Workbook
from openpyxl.styles import Alignment, PatternFill
from openpyxl.utils import get_column_letter
from openpyxl.worksheet.datavalidation import DataValidation
from typing import List
from config.env import CachePathConfig
def worship():
print("""
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////
""")
class CamelCaseUtil:
"""
下划线形式(snake_case)转换为小驼峰形式(camelCase)工具方法
"""
@classmethod
def __to_camel_case(cls, snake_str):
"""
下划线形式字符串(snake_case)转换为小驼峰形式字符串(camelCase)
:param snake_str: 下划线形式字符串
:return: 小驼峰形式字符串
"""
# 分割字符串
words = snake_str.split('_')
# 小驼峰命名,第一个词首字母小写,其余词首字母大写
return words[0] + ''.join(word.capitalize() for word in words[1:])
@classmethod
def transform_result(cls, result):
"""
针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法
:param result: 输入数据
:return: 小驼峰形式结果
"""
if result is None:
return result
# 如果是字典,直接转换键
elif isinstance(result, dict):
return {cls.__to_camel_case(k): v for k, v in result.items()}
# 如果是一组字典或其他类型的列表,遍历列表进行转换
elif isinstance(result, list):
return [cls.transform_result(row) if isinstance(row, dict) else cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) for row in result]
# 如果是其他类型,如模型实例,先转换为字典
else:
return cls.transform_result({c.name: getattr(result, c.name) for c in result.__table__.columns})
def bytes2human(n, format_str="%(value).1f%(symbol)s"):
"""Used by various scripts. See:
http://goo.gl/zeJZl
>>> bytes2human(10000)
'9.8K'
>>> bytes2human(100001221)
'95.4M'
"""
symbols = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
prefix = {}
for i, s in enumerate(symbols[1:]):
prefix[s] = 1 << (i + 1) * 10
for symbol in reversed(symbols[1:]):
if n >= prefix[symbol]:
value = float(n) / prefix[symbol]
return format_str % locals()
return format_str % dict(symbol=symbols[0], value=n)
def bytes2file_response(bytes_info):
yield bytes_info
def export_list2excel(list_data: List):
"""
工具方法将需要导出的list数据转化为对应excel的二进制数据
:param list_data: 数据列表
:return: 字典信息对应excel的二进制数据
"""
df = pd.DataFrame(list_data)
binary_data = io.BytesIO()
df.to_excel(binary_data, index=False, engine='openpyxl')
binary_data = binary_data.getvalue()
return binary_data
def get_excel_template(header_list: List, selector_header_list: List, option_list: List[dict]):
"""
工具方法将需要导出的list数据转化为对应excel的二进制数据
:param header_list: 表头数据列表
:param selector_header_list: 需要设置为选择器格式的表头数据列表
:param option_list: 选择器格式的表头预设的选项列表
:return: 模板excel的二进制数据
"""
# 创建Excel工作簿
wb = Workbook()
# 选择默认的活动工作表
ws = wb.active
# 设置表头文字
headers = header_list
# 设置表头背景样式为灰色,前景色为白色
header_fill = PatternFill(start_color="ababab", end_color="ababab", fill_type="solid")
# 将表头写入第一行
for col_num, header in enumerate(headers, 1):
cell = ws.cell(row=1, column=col_num)
cell.value = header
cell.fill = header_fill
# 设置列宽度为16
ws.column_dimensions[chr(64 + col_num)].width = 12
# 设置水平居中对齐
cell.alignment = Alignment(horizontal='center')
# 设置选择器的预设选项
options = option_list
# 获取selector_header的字母索引
for selector_header in selector_header_list:
column_selector_header_index = headers.index(selector_header) + 1
# 创建数据有效性规则
header_option = []
for option in options:
if option.get(selector_header):
header_option = option.get(selector_header)
dv = DataValidation(type="list", formula1=f'"{",".join(header_option)}"')
# 设置数据有效性规则的起始单元格和结束单元格
dv.add(
f'{get_column_letter(column_selector_header_index)}2:{get_column_letter(column_selector_header_index)}1048576')
# 添加数据有效性规则到工作表
ws.add_data_validation(dv)
# 保存Excel文件为字节类型的数据
file = io.BytesIO()
wb.save(file)
file.seek(0)
# 读取字节数据
excel_data = file.getvalue()
return excel_data
def get_filepath_from_url(url: str):
"""
工具方法:根据请求参数获取文件路径
:param url: 请求参数中的url参数
:return: 文件路径
"""
file_info = url.split("?")[1].split("&")
task_id = file_info[0].split("=")[1]
file_name = file_info[1].split("=")[1]
task_path = file_info[2].split("=")[1]
filepath = os.path.join(CachePathConfig.PATH, task_path, task_id, file_name)
return filepath

View File

@@ -0,0 +1,11 @@
import os
import time
from loguru import logger
log_path = os.path.join(os.getcwd(), 'logs')
if not os.path.exists(log_path):
os.mkdir(log_path)
log_path_error = os.path.join(log_path, f'{time.strftime("%Y-%m-%d")}_error.log')
logger.add(log_path_error, rotation="50MB", encoding="utf-8", enqueue=True, compression="zip")

View File

@@ -0,0 +1,5 @@
from utils.log_util import logger
def message_service(sms_code: str):
logger.info(f"短信验证码为{sms_code}")

View File

@@ -0,0 +1,98 @@
import math
from typing import Optional, List
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
class PageModel(BaseModel):
"""
分页模型
"""
offset: int
page_num: int
page_size: int
total: int
has_next: bool
class PageObjectResponse(BaseModel):
"""
用户管理列表分页查询返回模型
"""
rows: List = []
page_num: int
page_size: int
total: int
has_next: bool
class PageResponseModel(BaseModel):
"""
列表分页查询返回模型
"""
model_config = ConfigDict(alias_generator=to_camel)
rows: List = []
page_num: Optional[int] = None
page_size: Optional[int] = None
total: int
has_next: Optional[bool] = None
def get_page_info(offset: int, page_num: int, page_size: int, count: int):
"""
根据分页参数获取分页信息
:param offset: 起始数据位置
:param page_num: 当前页码
:param page_size: 当前页面数据量
:param count: 数据总数
:return: 分页信息对象
"""
has_next = False
if offset >= count:
res_offset_1 = (page_num - 2) * page_size
if res_offset_1 < 0:
res_offset = 0
res_page_num = 1
else:
res_offset = res_offset_1
res_page_num = page_num - 1
else:
res_offset = offset
if (res_offset + page_size) < count:
has_next = True
res_page_num = page_num
result = dict(offset=res_offset, page_num=res_page_num, page_size=page_size, total=count, has_next=has_next)
return PageModel(**result)
def get_page_obj(data_list: List, page_num: int, page_size: int):
"""
输入数据列表data_list和分页信息返回分页数据列表结果
:param data_list: 原始数据列表
:param page_num: 当前页码
:param page_size: 当前页面数据量
:return: 分页数据对象
"""
# 计算起始索引和结束索引
start = (page_num - 1) * page_size
end = page_num * page_size
# 根据计算得到的起始索引和结束索引对数据列表进行切片
paginated_data = data_list[start:end]
has_next = True if math.ceil(len(data_list) / page_size) > page_num else False
result = PageResponseModel(
rows=paginated_data,
pageNum=page_num,
pageSize=page_size,
total=len(data_list),
hasNext=has_next
)
return result

View File

@@ -0,0 +1,28 @@
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
class PwdUtil:
"""
密码工具类
"""
@classmethod
def verify_password(cls, plain_password, hashed_password):
"""
工具方法:校验当前输入的密码与数据库存储的密码是否一致
:param plain_password: 当前输入的密码
:param hashed_password: 数据库存储的密码
:return: 校验结果
"""
return pwd_context.verify(plain_password, hashed_password)
@classmethod
def get_password_hash(cls, input_password):
"""
工具方法:对当前输入的密码进行加密
:param input_password: 输入的密码
:return: 加密成功的密码
"""
return pwd_context.hash(input_password)

View File

@@ -0,0 +1,301 @@
from fastapi import status
from fastapi.responses import JSONResponse, Response, StreamingResponse
from fastapi.encoders import jsonable_encoder
from typing import Any, Dict, Optional
from pydantic import BaseModel
from datetime import datetime
class ResponseUtil:
"""
响应工具类
"""
@classmethod
def success(cls, msg: str = '操作成功', data: Optional[Any] = None, rows: Optional[Any] = None,
dict_content: Optional[Dict] = None, model_content: Optional[BaseModel] = None) -> Response:
"""
成功响应方法
:param msg: 可选,自定义成功响应信息
:param data: 可选成功响应结果中属性为data的值
:param rows: 可选成功响应结果中属性为rows的值
:param dict_content: 可选dict类型成功响应结果中自定义属性的值
:param model_content: 可选BaseModel类型成功响应结果中自定义属性的值
:return: 成功响应结果
"""
result = {
'code': 200,
'msg': msg
}
if data is not None:
result['data'] = data
if rows is not None:
result['rows'] = rows
if dict_content is not None:
result.update(dict_content)
if model_content is not None:
result.update(model_content.model_dump(by_alias=True))
result.update({'success': True, 'time': datetime.now()})
return JSONResponse(
status_code=status.HTTP_200_OK,
content=jsonable_encoder(result)
)
@classmethod
def failure(cls, msg: str = '操作失败', data: Optional[Any] = None, rows: Optional[Any] = None,
dict_content: Optional[Dict] = None, model_content: Optional[BaseModel] = None) -> Response:
"""
失败响应方法
:param msg: 可选,自定义失败响应信息
:param data: 可选失败响应结果中属性为data的值
:param rows: 可选失败响应结果中属性为rows的值
:param dict_content: 可选dict类型失败响应结果中自定义属性的值
:param model_content: 可选BaseModel类型失败响应结果中自定义属性的值
:return: 失败响应结果
"""
result = {
'code': 601,
'msg': msg
}
if data is not None:
result['data'] = data
if rows is not None:
result['rows'] = rows
if dict_content is not None:
result.update(dict_content)
if model_content is not None:
result.update(model_content.model_dump(by_alias=True))
result.update({'success': False, 'time': datetime.now()})
return JSONResponse(
status_code=status.HTTP_200_OK,
content=jsonable_encoder(result)
)
@classmethod
def unauthorized(cls, msg: str = '登录信息已过期,访问系统资源失败', data: Optional[Any] = None, rows: Optional[Any] = None,
dict_content: Optional[Dict] = None, model_content: Optional[BaseModel] = None) -> Response:
"""
未认证响应方法
:param msg: 可选,自定义未认证响应信息
:param data: 可选未认证响应结果中属性为data的值
:param rows: 可选未认证响应结果中属性为rows的值
:param dict_content: 可选dict类型未认证响应结果中自定义属性的值
:param model_content: 可选BaseModel类型未认证响应结果中自定义属性的值
:return: 未认证响应结果
"""
result = {
'code': 401,
'msg': msg
}
if data is not None:
result['data'] = data
if rows is not None:
result['rows'] = rows
if dict_content is not None:
result.update(dict_content)
if model_content is not None:
result.update(model_content.model_dump(by_alias=True))
result.update({'success': False, 'time': datetime.now()})
return JSONResponse(
status_code=status.HTTP_200_OK,
content=jsonable_encoder(result)
)
@classmethod
def forbidden(cls, msg: str = '该用户无此接口权限', data: Optional[Any] = None, rows: Optional[Any] = None,
dict_content: Optional[Dict] = None, model_content: Optional[BaseModel] = None) -> Response:
"""
未认证响应方法
:param msg: 可选,自定义未认证响应信息
:param data: 可选未认证响应结果中属性为data的值
:param rows: 可选未认证响应结果中属性为rows的值
:param dict_content: 可选dict类型未认证响应结果中自定义属性的值
:param model_content: 可选BaseModel类型未认证响应结果中自定义属性的值
:return: 未认证响应结果
"""
result = {
'code': 403,
'msg': msg
}
if data is not None:
result['data'] = data
if rows is not None:
result['rows'] = rows
if dict_content is not None:
result.update(dict_content)
if model_content is not None:
result.update(model_content.model_dump(by_alias=True))
result.update({'success': False, 'time': datetime.now()})
return JSONResponse(
status_code=status.HTTP_200_OK,
content=jsonable_encoder(result)
)
@classmethod
def error(cls, msg: str = '接口异常', data: Optional[Any] = None, rows: Optional[Any] = None,
dict_content: Optional[Dict] = None, model_content: Optional[BaseModel] = None) -> Response:
"""
错误响应方法
:param msg: 可选,自定义错误响应信息
:param data: 可选错误响应结果中属性为data的值
:param rows: 可选错误响应结果中属性为rows的值
:param dict_content: 可选dict类型错误响应结果中自定义属性的值
:param model_content: 可选BaseModel类型错误响应结果中自定义属性的值
:return: 错误响应结果
"""
result = {
'code': 500,
'msg': msg
}
if data is not None:
result['data'] = data
if rows is not None:
result['rows'] = rows
if dict_content is not None:
result.update(dict_content)
if model_content is not None:
result.update(model_content.model_dump(by_alias=True))
result.update({'success': False, 'time': datetime.now()})
return JSONResponse(
status_code=status.HTTP_200_OK,
content=jsonable_encoder(result)
)
@classmethod
def streaming(cls, *, data: Any = None):
"""
流式响应方法
:param data: 流式传输的内容
:return: 流式响应结果
"""
return StreamingResponse(
status_code=status.HTTP_200_OK,
content=data
)
def response_200(*, data: Any = None, message="获取成功") -> Response:
return JSONResponse(
status_code=status.HTTP_200_OK,
content=jsonable_encoder(
{
'code': 200,
'message': message,
'data': data,
'success': 'true',
'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
)
)
def response_400(*, data: Any = None, message: str = "获取失败") -> Response:
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content=jsonable_encoder(
{
'code': 400,
'message': message,
'data': data,
'success': 'false',
'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
)
)
def response_401(*, data: Any = None, message: str = "获取失败") -> Response:
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content=jsonable_encoder(
{
'code': 401,
'message': message,
'data': data,
'success': 'false',
'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
)
)
def response_403(*, data: Any = None, message: str = "获取失败") -> Response:
return JSONResponse(
status_code=status.HTTP_403_FORBIDDEN,
content=jsonable_encoder(
{
'code': 403,
'message': message,
'data': data,
'success': 'false',
'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
)
)
def response_500(*, data: Any = None, message: str = "接口异常") -> Response:
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=jsonable_encoder(
{
'code': 500,
'message': message,
'data': data,
'success': 'false',
'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
)
)
def streaming_response_200(*, data: Any = None):
return StreamingResponse(
status_code=status.HTTP_200_OK,
content=data,
)
class AuthException(Exception):
"""
自定义令牌异常AuthException
"""
def __init__(self, data: str = None, message: str = None):
self.data = data
self.message = message
class PermissionException(Exception):
"""
自定义权限异常PermissionException
"""
def __init__(self, data: str = None, message: str = None):
self.data = data
self.message = message
class LoginException(Exception):
"""
自定义登录异常LoginException
"""
def __init__(self, data: str = None, message: str = None):
self.data = data
self.message = message

View File

@@ -0,0 +1,51 @@
import datetime
def object_format_datetime(obj):
"""
:param obj: 输入一个对象
:return:对目标对象所有datetime类型的属性格式化
"""
for attr in dir(obj):
value = getattr(obj, attr)
if isinstance(value, datetime.datetime):
setattr(obj, attr, value.strftime('%Y-%m-%d %H:%M:%S'))
return obj
def list_format_datetime(lst):
"""
:param lst: 输入一个嵌套对象的列表
:return: 对目标列表中所有对象的datetime类型的属性格式化
"""
for obj in lst:
for attr in dir(obj):
value = getattr(obj, attr)
if isinstance(value, datetime.datetime):
setattr(obj, attr, value.strftime('%Y-%m-%d %H:%M:%S'))
return lst
def format_datetime_dict_list(dicts):
"""
递归遍历嵌套字典,并将 datetime 值转换为字符串格式
:param dicts: 输入一个嵌套字典的列表
:return: 对目标列表中所有字典的datetime类型的属性格式化
"""
result = []
for item in dicts:
new_item = {}
for k, v in item.items():
if isinstance(v, dict):
# 递归遍历子字典
new_item[k] = format_datetime_dict_list([v])[0]
elif isinstance(v, datetime.datetime):
# 如果值是 datetime 类型,则格式化为字符串
new_item[k] = v.strftime('%Y-%m-%d %H:%M:%S')
else:
# 否则保留原始值
new_item[k] = v
result.append(new_item)
return result

View File

@@ -0,0 +1,8 @@
# 页面标题
VITE_APP_TITLE = 若依管理系统
# 开发环境配置
VITE_APP_ENV = 'development'
# 若依管理系统/开发环境
VITE_APP_BASE_API = '/dev-api'

View File

@@ -0,0 +1,11 @@
# 页面标题
VITE_APP_TITLE = 若依管理系统
# 生产环境配置
VITE_APP_ENV = 'production'
# 若依管理系统/生产环境
VITE_APP_BASE_API = '/prod-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip

View File

@@ -0,0 +1,11 @@
# 页面标题
VITE_APP_TITLE = 若依管理系统
# 生产环境配置
VITE_APP_ENV = 'staging'
# 若依管理系统/生产环境
VITE_APP_BASE_API = '/stage-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip

23
ruoyi-fastapi-frontend/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*.log
tests/**/coverage/
tests/e2e/reports
selenium-debug.log
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.local
package-lock.json
yarn.lock

View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 RuoYi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,109 @@
<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 v3.8.7</h1>
<h4 align="center">基于SpringBoot+Vue3前后端分离的Java快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.7-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>
## 平台简介
* 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。
* 配套后端代码仓库地址[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 或 [RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast) 版本。
* 前端技术栈([Vue2](https://cn.vuejs.org) + [Element](https://github.com/ElemeFE/element) + [Vue CLI](https://cli.vuejs.org/zh)),请移步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue/tree/master/ruoyi-ui)。
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
## 前端运行
```bash
# 克隆项目
git clone https://github.com/yangzongzhuan/RuoYi-Vue3.git
# 进入项目目录
cd RuoYi-Vue3
# 安装依赖
yarn --registry=https://registry.npmmirror.com
# 启动服务
yarn dev
# 构建测试环境 yarn build:stage
# 构建生产环境 yarn build:prod
# 前端访问地址 http://localhost:80
```
## 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 通知公告:系统通知公告信息发布维护。
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。
14. 系统接口根据业务代码自动生成相关的api接口文档。
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 缓存监控:对系统的缓存信息查询,命令统计等。
17. 在线构建器拖动表单元素生成相应的HTML代码。
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
## 在线体验
- admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://vue.ruoyi.vip
文档地址http://doc.ruoyi.vip
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
</tr>
</table>
## 若依前后端分离交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) 点击按钮入群。

View File

@@ -0,0 +1,12 @@
@echo off
echo.
echo [<5B><>Ϣ] <20><><EFBFBD><EFBFBD>Web<65><62><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD>dist<73>ļ<EFBFBD><C4BC><EFBFBD>
echo.
%~d0
cd %~dp0
cd ..
yarn build:prod
pause

View File

@@ -0,0 +1,12 @@
@echo off
echo.
echo [<5B><>Ϣ] <20><>װWeb<65><62><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD>node_modules<65>ļ<EFBFBD><C4BC><EFBFBD>
echo.
%~d0
cd %~dp0
cd ..
yarn --registry=https://registry.npmmirror.com
pause

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