Browse Source

style: 使用ruff格式化定时任务模块,优化导入

master
insistence 7 months ago
parent
commit
659163d662
  1. 113
      ruoyi-fastapi-backend/module_admin/controller/job_controller.py
  2. 52
      ruoyi-fastapi-backend/module_admin/dao/job_dao.py
  3. 29
      ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py
  4. 33
      ruoyi-fastapi-backend/module_admin/entity/do/job_do.py
  5. 19
      ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py
  6. 54
      ruoyi-fastapi-backend/module_admin/service/job_log_service.py
  7. 71
      ruoyi-fastapi-backend/module_admin/service/job_service.py

113
ruoyi-fastapi-backend/module_admin/controller/job_controller.py

@ -1,24 +1,40 @@
from fastapi import APIRouter from datetime import datetime
from fastapi import Depends from fastapi import APIRouter, Depends, Request
from pydantic_validation_decorator import ValidateFields from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from config.enums import BusinessType
from config.get_db import get_db from 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 module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import log_decorator from module_admin.annotation.log_annotation import log_decorator
from config.enums import BusinessType from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from utils.response_util import * from module_admin.entity.vo.job_vo import (
from utils.log_util import * DeleteJobLogModel,
from utils.page_util import * DeleteJobModel,
EditJobModel,
JobLogPageQueryModel,
JobModel,
JobPageQueryModel,
)
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.job_log_service import JobLogService
from module_admin.service.job_service import JobService
from module_admin.service.login_service import LoginService
from utils.common_util import bytes2file_response from utils.common_util import bytes2file_response
from utils.log_util import logger
from utils.page_util import PageResponseModel
from utils.response_util import ResponseUtil
jobController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)]) jobController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)])
@jobController.get("/job/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) @jobController.get(
async def get_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query), query_db: AsyncSession = Depends(get_db)): '/job/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]
)
async def get_system_job_list(
request: Request,
job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
try: try:
# 获取分页数据 # 获取分页数据
notice_page_query_result = await JobService.get_job_list_services(query_db, job_page_query, is_page=True) notice_page_query_result = await JobService.get_job_list_services(query_db, job_page_query, is_page=True)
@ -29,10 +45,15 @@ async def get_system_job_list(request: Request, job_page_query: JobPageQueryMode
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.post("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))]) @jobController.post('/job', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))])
@ValidateFields(validate_model='add_job') @ValidateFields(validate_model='add_job')
@log_decorator(title='定时任务管理', business_type=BusinessType.INSERT) @log_decorator(title='定时任务管理', business_type=BusinessType.INSERT)
async def add_system_job(request: Request, add_job: JobModel, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): async def add_system_job(
request: Request,
add_job: JobModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
try: try:
add_job.create_by = current_user.user.user_name add_job.create_by = current_user.user.user_name
add_job.create_time = datetime.now() add_job.create_time = datetime.now()
@ -50,10 +71,15 @@ async def add_system_job(request: Request, add_job: JobModel, query_db: AsyncSes
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.put("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))]) @jobController.put('/job', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))])
@ValidateFields(validate_model='edit_job') @ValidateFields(validate_model='edit_job')
@log_decorator(title='定时任务管理', business_type=BusinessType.UPDATE) @log_decorator(title='定时任务管理', business_type=BusinessType.UPDATE)
async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): async def edit_system_job(
request: Request,
edit_job: EditJobModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
try: try:
edit_job.update_by = current_user.user.user_name edit_job.update_by = current_user.user.user_name
edit_job.update_time = datetime.now() edit_job.update_time = datetime.now()
@ -69,9 +95,14 @@ async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: As
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.put("/job/changeStatus", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))]) @jobController.put('/job/changeStatus', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))])
@log_decorator(title='定时任务管理', business_type=BusinessType.UPDATE) @log_decorator(title='定时任务管理', business_type=BusinessType.UPDATE)
async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user)): async def change_system_job_status(
request: Request,
edit_job: EditJobModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user),
):
try: try:
edit_job.update_by = current_user.user.user_name edit_job.update_by = current_user.user.user_name
edit_job.update_time = datetime.now() edit_job.update_time = datetime.now()
@ -88,7 +119,7 @@ async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: As
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.put("/job/run", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))]) @jobController.put('/job/run', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))])
@log_decorator(title='定时任务管理', business_type=BusinessType.UPDATE) @log_decorator(title='定时任务管理', business_type=BusinessType.UPDATE)
async def execute_system_job(request: Request, execute_job: JobModel, query_db: AsyncSession = Depends(get_db)): async def execute_system_job(request: Request, execute_job: JobModel, query_db: AsyncSession = Depends(get_db)):
try: try:
@ -104,7 +135,7 @@ async def execute_system_job(request: Request, execute_job: JobModel, query_db:
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.delete("/job/{job_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) @jobController.delete('/job/{job_ids}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务管理', business_type=BusinessType.DELETE) @log_decorator(title='定时任务管理', business_type=BusinessType.DELETE)
async def delete_system_job(request: Request, job_ids: str, query_db: AsyncSession = Depends(get_db)): async def delete_system_job(request: Request, job_ids: str, query_db: AsyncSession = Depends(get_db)):
try: try:
@ -121,7 +152,9 @@ async def delete_system_job(request: Request, job_ids: str, query_db: AsyncSessi
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.get("/job/{job_id}", response_model=JobModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))]) @jobController.get(
'/job/{job_id}', response_model=JobModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))]
)
async def query_detail_system_job(request: Request, job_id: int, query_db: AsyncSession = Depends(get_db)): async def query_detail_system_job(request: Request, job_id: int, query_db: AsyncSession = Depends(get_db)):
try: try:
job_detail_result = await JobService.job_detail_services(query_db, job_id) job_detail_result = await JobService.job_detail_services(query_db, job_id)
@ -132,9 +165,13 @@ async def query_detail_system_job(request: Request, job_id: int, query_db: Async
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.post("/job/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))]) @jobController.post('/job/export', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@log_decorator(title='定时任务管理', business_type=BusinessType.EXPORT) @log_decorator(title='定时任务管理', business_type=BusinessType.EXPORT)
async def export_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_form), query_db: AsyncSession = Depends(get_db)): async def export_system_job_list(
request: Request,
job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_form),
query_db: AsyncSession = Depends(get_db),
):
try: try:
# 获取全量数据 # 获取全量数据
job_query_result = await JobService.get_job_list_services(query_db, job_page_query, is_page=False) job_query_result = await JobService.get_job_list_services(query_db, job_page_query, is_page=False)
@ -146,11 +183,19 @@ async def export_system_job_list(request: Request, job_page_query: JobPageQueryM
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.get("/jobLog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) @jobController.get(
async def get_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_query), query_db: AsyncSession = Depends(get_db)): '/jobLog/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]
)
async def get_system_job_log_list(
request: Request,
job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_query),
query_db: AsyncSession = Depends(get_db),
):
try: try:
# 获取分页数据 # 获取分页数据
job_log_page_query_result = await JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=True) job_log_page_query_result = await JobLogService.get_job_log_list_services(
query_db, job_log_page_query, is_page=True
)
logger.info('获取成功') logger.info('获取成功')
return ResponseUtil.success(model_content=job_log_page_query_result) return ResponseUtil.success(model_content=job_log_page_query_result)
except Exception as e: except Exception as e:
@ -158,7 +203,7 @@ async def get_system_job_log_list(request: Request, job_log_page_query: JobLogPa
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.delete("/jobLog/clean", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) @jobController.delete('/jobLog/clean', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务日志管理', business_type=BusinessType.CLEAN) @log_decorator(title='定时任务日志管理', business_type=BusinessType.CLEAN)
async def clear_system_job_log(request: Request, query_db: AsyncSession = Depends(get_db)): async def clear_system_job_log(request: Request, query_db: AsyncSession = Depends(get_db)):
try: try:
@ -174,7 +219,7 @@ async def clear_system_job_log(request: Request, query_db: AsyncSession = Depend
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.delete("/jobLog/{job_log_ids}", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) @jobController.delete('/jobLog/{job_log_ids}', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))])
@log_decorator(title='定时任务日志管理', business_type=BusinessType.DELETE) @log_decorator(title='定时任务日志管理', business_type=BusinessType.DELETE)
async def delete_system_job_log(request: Request, job_log_ids: str, query_db: AsyncSession = Depends(get_db)): async def delete_system_job_log(request: Request, job_log_ids: str, query_db: AsyncSession = Depends(get_db)):
try: try:
@ -191,12 +236,18 @@ async def delete_system_job_log(request: Request, job_log_ids: str, query_db: As
return ResponseUtil.error(msg=str(e)) return ResponseUtil.error(msg=str(e))
@jobController.post("/jobLog/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))]) @jobController.post('/jobLog/export', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))])
@log_decorator(title='定时任务日志管理', business_type=BusinessType.EXPORT) @log_decorator(title='定时任务日志管理', business_type=BusinessType.EXPORT)
async def export_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_form), query_db: AsyncSession = Depends(get_db)): async def export_system_job_log_list(
request: Request,
job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_form),
query_db: AsyncSession = Depends(get_db),
):
try: try:
# 获取全量数据 # 获取全量数据
job_log_query_result = await JobLogService.get_job_log_list_services(query_db, job_log_page_query, is_page=False) job_log_query_result = await JobLogService.get_job_log_list_services(
query_db, job_log_page_query, is_page=False
)
job_log_export_result = await JobLogService.export_job_log_list_services(request, job_log_query_result) job_log_export_result = await JobLogService.export_job_log_list_services(request, job_log_query_result)
logger.info('导出成功') logger.info('导出成功')
return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result)) return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result))

52
ruoyi-fastapi-backend/module_admin/dao/job_dao.py

@ -1,7 +1,7 @@
from sqlalchemy import select, update, delete from sqlalchemy import delete, select, update
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.job_do import SysJob from module_admin.entity.do.job_do import SysJob
from module_admin.entity.vo.job_vo import * from module_admin.entity.vo.job_vo import JobModel, JobPageQueryModel
from utils.page_util import PageUtil from utils.page_util import PageUtil
@ -18,10 +18,7 @@ class JobDao:
:param job_id: 定时任务id :param job_id: 定时任务id
:return: 定时任务信息对象 :return: 定时任务信息对象
""" """
job_info = (await db.execute( job_info = (await db.execute(select(SysJob).where(SysJob.job_id == job_id))).scalars().first()
select(SysJob)
.where(SysJob.job_id == job_id)
)).scalars().first()
return job_info return job_info
@ -33,13 +30,20 @@ class JobDao:
:param job: 定时任务参数对象 :param job: 定时任务参数对象
:return: 定时任务信息对象 :return: 定时任务信息对象
""" """
job_info = (await db.execute( job_info = (
select(SysJob) (
.where(SysJob.job_name == job.job_name if job.job_name else True, await db.execute(
select(SysJob).where(
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.job_group == job.job_group if job.job_group else True,
SysJob.invoke_target == job.invoke_target if job.invoke_target 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) SysJob.cron_expression == job.cron_expression if job.cron_expression else True,
)).scalars().first() )
)
)
.scalars()
.first()
)
return job_info return job_info
@ -52,11 +56,15 @@ class JobDao:
:param is_page: 是否开启分页 :param is_page: 是否开启分页
:return: 定时任务列表信息对象 :return: 定时任务列表信息对象
""" """
query = select(SysJob) \ query = (
.where(SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, select(SysJob)
.where(
SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJob.job_group == query_object.job_group if query_object.job_group else True, SysJob.job_group == query_object.job_group if query_object.job_group else True,
SysJob.status == query_object.status if query_object.status else True) \ SysJob.status == query_object.status if query_object.status else True,
)
.distinct() .distinct()
)
job_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page) job_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return job_list return job_list
@ -68,11 +76,7 @@ class JobDao:
:param db: orm对象 :param db: orm对象
:return: 定时任务列表信息对象 :return: 定时任务列表信息对象
""" """
job_list = (await db.execute( job_list = (await db.execute(select(SysJob).where(SysJob.status == '0').distinct())).scalars().all()
select(SysJob)
.where(SysJob.status == '0')
.distinct()
)).scalars().all()
return job_list return job_list
@ -98,10 +102,7 @@ class JobDao:
:param job: 需要更新的定时任务字典 :param job: 需要更新的定时任务字典
:return: :return:
""" """
await db.execute( await db.execute(update(SysJob), [job])
update(SysJob),
[job]
)
@classmethod @classmethod
async def delete_job_dao(cls, db: AsyncSession, job: JobModel): async def delete_job_dao(cls, db: AsyncSession, job: JobModel):
@ -111,7 +112,4 @@ class JobDao:
:param job: 定时任务对象 :param job: 定时任务对象
:return: :return:
""" """
await db.execute( await db.execute(delete(SysJob).where(SysJob.job_id.in_([job.job_id])))
delete(SysJob)
.where(SysJob.job_id.in_([job.job_id]))
)

29
ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py

@ -1,10 +1,10 @@
from sqlalchemy import select, delete from datetime import datetime, time
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from module_admin.entity.do.job_do import SysJobLog from module_admin.entity.do.job_do import SysJobLog
from module_admin.entity.vo.job_vo import * from module_admin.entity.vo.job_vo import JobLogModel, JobLogPageQueryModel
from utils.page_util import PageUtil from utils.page_util import PageUtil
from datetime import datetime, time
class JobLogDao: class JobLogDao:
@ -21,15 +21,21 @@ class JobLogDao:
:param is_page: 是否开启分页 :param is_page: 是否开启分页
:return: 定时任务日志列表信息对象 :return: 定时任务日志列表信息对象
""" """
query = select(SysJobLog) \ query = (
.where(SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, select(SysJobLog)
.where(
SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True,
SysJobLog.job_group == query_object.job_group if query_object.job_group else True, SysJobLog.job_group == query_object.job_group if query_object.job_group else True,
SysJobLog.status == query_object.status if query_object.status else True, SysJobLog.status == query_object.status if query_object.status else True,
SysJobLog.create_time.between( 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.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59))) datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)),
if query_object.begin_time and query_object.end_time else True) \ )
if query_object.begin_time and query_object.end_time
else True,
)
.distinct() .distinct()
)
job_log_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page) job_log_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return job_log_list return job_log_list
@ -56,10 +62,7 @@ class JobLogDao:
:param job_log: 定时任务日志对象 :param job_log: 定时任务日志对象
:return: :return:
""" """
await db.execute( await db.execute(delete(SysJobLog).where(SysJobLog.job_log_id.in_([job_log.job_log_id])))
delete(SysJobLog)
.where(SysJobLog.job_log_id.in_([job_log.job_log_id]))
)
@classmethod @classmethod
async def clear_job_log_dao(cls, db: AsyncSession): async def clear_job_log_dao(cls, db: AsyncSession):
@ -68,6 +71,4 @@ class JobLogDao:
:param db: orm对象 :param db: orm对象
:return: :return:
""" """
await db.execute( await db.execute(delete(SysJobLog))
delete(SysJobLog)
)

33
ruoyi-fastapi-backend/module_admin/entity/do/job_do.py

@ -1,24 +1,36 @@
from sqlalchemy import Column, Integer, String, DateTime
from config.database import Base
from datetime import datetime from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, String
from config.database import Base
class SysJob(Base): class SysJob(Base):
""" """
定时任务调度表 定时任务调度表
""" """
__tablename__ = 'sys_job' __tablename__ = 'sys_job'
job_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务ID') job_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务ID')
job_name = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务名称') 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_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='任务执行器') 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='调用目标字符串') 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_args = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='位置参数')
job_kwargs = 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执行表达式') cron_expression = Column(
misfire_policy = Column(String(20, collation='utf8_general_ci'), nullable=True, default='3', comment='计划执行错误策略(1立即执行 2执行一次 3放弃执行)') String(255, collation='utf8_general_ci'), nullable=True, default='', comment='cron执行表达式'
concurrent = Column(String(1, collation='utf8_general_ci'), nullable=True, default='1', comment='是否并发执行(0允许 1禁止)') )
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暂停)') 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_by = Column(String(64, collation='utf8_general_ci'), nullable=True, default='', comment='创建者')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间') create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
@ -31,17 +43,22 @@ class SysJobLog(Base):
""" """
定时任务调度日志表 定时任务调度日志表
""" """
__tablename__ = 'sys_job_log' __tablename__ = 'sys_job_log'
job_log_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务日志ID') 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_name = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务名称')
job_group = 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='任务执行器') 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='调用目标字符串') 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_args = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='位置参数')
job_kwargs = 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_trigger = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='任务触发器')
job_message = Column(String(500, collation='utf8_general_ci'), nullable=True, default='', 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失败)') 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='异常信息') exception_info = Column(String(2000, collation='utf8_general_ci'), nullable=True, default='', comment='异常信息')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间') create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')

19
ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py

@ -1,15 +1,16 @@
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel from pydantic.alias_generators import to_camel
from pydantic_validation_decorator import NotBlank, Size from pydantic_validation_decorator import NotBlank, Size
from typing import Union, Optional, List, Literal from typing import Literal, Optional
from datetime import datetime from module_admin.annotation.pydantic_annotation import as_form, as_query
from module_admin.annotation.pydantic_annotation import as_query, as_form
class JobModel(BaseModel): class JobModel(BaseModel):
""" """
定时任务调度表对应pydantic模型 定时任务调度表对应pydantic模型
""" """
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
job_id: Optional[int] = Field(default=None, description='任务ID') job_id: Optional[int] = Field(default=None, description='任务ID')
@ -20,7 +21,9 @@ class JobModel(BaseModel):
job_args: Optional[str] = Field(default=None, description='位置参数') job_args: Optional[str] = Field(default=None, description='位置参数')
job_kwargs: Optional[str] = Field(default=None, description='关键字参数') job_kwargs: Optional[str] = Field(default=None, description='关键字参数')
cron_expression: Optional[str] = Field(default=None, description='cron执行表达式') cron_expression: Optional[str] = Field(default=None, description='cron执行表达式')
misfire_policy: Optional[Literal['1', '2', '3']] = Field(default=None, description='计划执行错误策略(1立即执行 2执行一次 3放弃执行)') misfire_policy: Optional[Literal['1', '2', '3']] = Field(
default=None, description='计划执行错误策略(1立即执行 2执行一次 3放弃执行)'
)
concurrent: Optional[Literal['0', '1']] = Field(default=None, description='是否并发执行(0允许 1禁止)') concurrent: Optional[Literal['0', '1']] = Field(default=None, description='是否并发执行(0允许 1禁止)')
status: Optional[Literal['0', '1']] = Field(default=None, description='状态(0正常 1暂停)') status: Optional[Literal['0', '1']] = Field(default=None, description='状态(0正常 1暂停)')
create_by: Optional[str] = Field(default=None, description='创建者') create_by: Optional[str] = Field(default=None, description='创建者')
@ -48,6 +51,7 @@ class JobLogModel(BaseModel):
""" """
定时任务调度日志表对应pydantic模型 定时任务调度日志表对应pydantic模型
""" """
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
job_log_id: Optional[int] = Field(default=None, description='任务日志ID') job_log_id: Optional[int] = Field(default=None, description='任务日志ID')
@ -68,6 +72,7 @@ class JobQueryModel(JobModel):
""" """
定时任务管理不分页查询模型 定时任务管理不分页查询模型
""" """
begin_time: Optional[str] = Field(default=None, description='开始时间') begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间') end_time: Optional[str] = Field(default=None, description='结束时间')
@ -78,6 +83,7 @@ class JobPageQueryModel(JobQueryModel):
""" """
定时任务管理分页查询模型 定时任务管理分页查询模型
""" """
page_num: int = Field(default=1, description='当前页码') page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数') page_size: int = Field(default=10, description='每页记录数')
@ -86,6 +92,7 @@ class EditJobModel(JobModel):
""" """
编辑定时任务模型 编辑定时任务模型
""" """
type: Optional[str] = Field(default=None, description='操作类型') type: Optional[str] = Field(default=None, description='操作类型')
@ -93,6 +100,7 @@ class DeleteJobModel(BaseModel):
""" """
删除定时任务模型 删除定时任务模型
""" """
model_config = ConfigDict(alias_generator=to_camel) model_config = ConfigDict(alias_generator=to_camel)
job_ids: str = Field(description='需要删除的定时任务ID') job_ids: str = Field(description='需要删除的定时任务ID')
@ -102,6 +110,7 @@ class JobLogQueryModel(JobLogModel):
""" """
定时任务日志不分页查询模型 定时任务日志不分页查询模型
""" """
begin_time: Optional[str] = Field(default=None, description='开始时间') begin_time: Optional[str] = Field(default=None, description='开始时间')
end_time: Optional[str] = Field(default=None, description='结束时间') end_time: Optional[str] = Field(default=None, description='结束时间')
@ -112,6 +121,7 @@ class JobLogPageQueryModel(JobLogQueryModel):
""" """
定时任务日志管理分页查询模型 定时任务日志管理分页查询模型
""" """
page_num: int = Field(default=1, description='当前页码') page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数') page_size: int = Field(default=10, description='每页记录数')
@ -120,6 +130,7 @@ class DeleteJobLogModel(BaseModel):
""" """
删除定时任务日志模型 删除定时任务日志模型
""" """
model_config = ConfigDict(alias_generator=to_camel) model_config = ConfigDict(alias_generator=to_camel)
job_log_ids: str = Field(description='需要删除的定时任务日志ID') job_log_ids: str = Field(description='需要删除的定时任务日志ID')

54
ruoyi-fastapi-backend/module_admin/service/job_log_service.py

@ -1,6 +1,11 @@
from module_admin.dao.job_log_dao import * from fastapi import Request
from module_admin.service.dict_service import Request, DictDataService from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session
from typing import List
from module_admin.dao.job_log_dao import JobLogDao
from module_admin.entity.vo.common_vo import CrudResponseModel from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.job_vo import DeleteJobLogModel, JobLogModel, JobLogPageQueryModel
from module_admin.service.dict_service import DictDataService
from utils.common_util import export_list2excel from utils.common_util import export_list2excel
@ -10,7 +15,9 @@ class JobLogService:
""" """
@classmethod @classmethod
async def get_job_log_list_services(cls, query_db: AsyncSession, query_object: JobLogPageQueryModel, is_page: bool = False): async def get_job_log_list_services(
cls, query_db: AsyncSession, query_object: JobLogPageQueryModel, is_page: bool = False
):
""" """
获取定时任务日志列表信息service 获取定时任务日志列表信息service
:param query_db: orm对象 :param query_db: orm对象
@ -89,26 +96,32 @@ class JobLogService:
""" """
# 创建一个映射字典,将英文键映射到中文键 # 创建一个映射字典,将英文键映射到中文键
mapping_dict = { mapping_dict = {
"jobLogId": "任务日志编码", 'jobLogId': '任务日志编码',
"jobName": "任务名称", 'jobName': '任务名称',
"jobGroup": "任务组名", 'jobGroup': '任务组名',
"jobExecutor": "任务执行器", 'jobExecutor': '任务执行器',
"invokeTarget": "调用目标字符串", 'invokeTarget': '调用目标字符串',
"jobArgs": "位置参数", 'jobArgs': '位置参数',
"jobKwargs": "关键字参数", 'jobKwargs': '关键字参数',
"jobTrigger": "任务触发器", 'jobTrigger': '任务触发器',
"jobMessage": "日志信息", 'jobMessage': '日志信息',
"status": "执行状态", 'status': '执行状态',
"exceptionInfo": "异常信息", 'exceptionInfo': '异常信息',
"createTime": "创建时间", 'createTime': '创建时间',
} }
data = job_log_list data = job_log_list
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group') job_group_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(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_group_list]
job_group_option_dict = {item.get('value'): item for item in job_group_option} job_group_option_dict = {item.get('value'): item for item in job_group_option}
job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_executor') job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(
job_executor_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list] 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} job_executor_option_dict = {item.get('value'): item for item in job_executor_option}
for item in data: for item in data:
@ -120,8 +133,9 @@ class JobLogService:
item['jobGroup'] = job_group_option_dict.get(str(item.get('jobGroup'))).get('label') item['jobGroup'] = job_group_option_dict.get(str(item.get('jobGroup'))).get('label')
if str(item.get('jobExecutor')) in job_executor_option_dict.keys(): if str(item.get('jobExecutor')) in job_executor_option_dict.keys():
item['jobExecutor'] = job_executor_option_dict.get(str(item.get('jobExecutor'))).get('label') item['jobExecutor'] = job_executor_option_dict.get(str(item.get('jobExecutor'))).get('label')
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in new_data = [
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) binary_data = export_list2excel(new_data)
return binary_data return binary_data

71
ruoyi-fastapi-backend/module_admin/service/job_service.py

@ -1,8 +1,12 @@
from module_admin.dao.job_dao import * from fastapi import Request
from module_admin.service.dict_service import Request, DictDataService from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.vo.common_vo import CrudResponseModel from typing import List
from utils.common_util import export_list2excel, CamelCaseUtil
from config.get_scheduler import SchedulerUtil from config.get_scheduler import SchedulerUtil
from module_admin.dao.job_dao import JobDao
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.job_vo import DeleteJobModel, EditJobModel, JobModel, JobPageQueryModel
from module_admin.service.dict_service import DictDataService
from utils.common_util import CamelCaseUtil, export_list2excel
class JobService: class JobService:
@ -11,7 +15,9 @@ class JobService:
""" """
@classmethod @classmethod
async def get_job_list_services(cls, query_db: AsyncSession, query_object: JobPageQueryModel, is_page: bool = False): async def get_job_list_services(
cls, query_db: AsyncSession, query_object: JobPageQueryModel, is_page: bool = False
):
""" """
获取定时任务列表信息service 获取定时任务列表信息service
:param query_db: orm对象 :param query_db: orm对象
@ -61,7 +67,12 @@ class JobService:
del edit_job['type'] del edit_job['type']
job_info = await cls.job_detail_services(query_db, edit_job.get('job_id')) job_info = await cls.job_detail_services(query_db, edit_job.get('job_id'))
if job_info: 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): 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 = await JobDao.get_job_detail_by_info(query_db, page_object) job = await JobDao.get_job_detail_by_info(query_db, page_object)
if job: if job:
result = dict(is_success=False, message='定时任务已存在') result = dict(is_success=False, message='定时任务已存在')
@ -152,30 +163,36 @@ class JobService:
""" """
# 创建一个映射字典,将英文键映射到中文键 # 创建一个映射字典,将英文键映射到中文键
mapping_dict = { mapping_dict = {
"jobId": "任务编码", 'jobId': '任务编码',
"jobName": "任务名称", 'jobName': '任务名称',
"jobGroup": "任务组名", 'jobGroup': '任务组名',
"jobExecutor": "任务执行器", 'jobExecutor': '任务执行器',
"invokeTarget": "调用目标字符串", 'invokeTarget': '调用目标字符串',
"jobArgs": "位置参数", 'jobArgs': '位置参数',
"jobKwargs": "关键字参数", 'jobKwargs': '关键字参数',
"cronExpression": "cron执行表达式", 'cronExpression': 'cron执行表达式',
"misfirePolicy": "计划执行错误策略", 'misfirePolicy': '计划执行错误策略',
"concurrent": "是否并发执行", 'concurrent': '是否并发执行',
"status": "状态", 'status': '状态',
"createBy": "创建者", 'createBy': '创建者',
"createTime": "创建时间", 'createTime': '创建时间',
"updateBy": "更新者", 'updateBy': '更新者',
"updateTime": "更新时间", 'updateTime': '更新时间',
"remark": "备注", 'remark': '备注',
} }
data = job_list data = job_list
job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group') job_group_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(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_group_list]
job_group_option_dict = {item.get('value'): item for item in job_group_option} job_group_option_dict = {item.get('value'): item for item in job_group_option}
job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_executor') job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(
job_executor_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list] 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} job_executor_option_dict = {item.get('value'): item for item in job_executor_option}
for item in data: for item in data:
@ -197,7 +214,9 @@ class JobService:
item['concurrent'] = '允许' item['concurrent'] = '允许'
else: else:
item['concurrent'] = '禁止' item['concurrent'] = '禁止'
new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] new_data = [
{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data
]
binary_data = export_list2excel(new_data) binary_data = export_list2excel(new_data)
return binary_data return binary_data

Loading…
Cancel
Save