From 659163d662cee164f5f5a29eae6b166e962319e0 Mon Sep 17 00:00:00 2001 From: insistence <3055204202@qq.com> Date: Fri, 12 Jul 2024 10:28:28 +0800 Subject: [PATCH] =?UTF-8?q?style:=20=E4=BD=BF=E7=94=A8ruff=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E4=BC=98=E5=8C=96=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module_admin/controller/job_controller.py | 115 +++++++++++++----- .../module_admin/dao/job_dao.py | 58 +++++---- .../module_admin/dao/job_log_dao.py | 37 +++--- .../module_admin/entity/do/job_do.py | 33 +++-- .../module_admin/entity/vo/job_vo.py | 19 ++- .../module_admin/service/job_log_service.py | 54 +++++--- .../module_admin/service/job_service.py | 71 +++++++---- 7 files changed, 249 insertions(+), 138 deletions(-) diff --git a/ruoyi-fastapi-backend/module_admin/controller/job_controller.py b/ruoyi-fastapi-backend/module_admin/controller/job_controller.py index f3d536b..961c472 100644 --- a/ruoyi-fastapi-backend/module_admin/controller/job_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/job_controller.py @@ -1,24 +1,40 @@ -from fastapi import APIRouter -from fastapi import Depends +from datetime import datetime +from fastapi import APIRouter, Depends, Request from pydantic_validation_decorator import ValidateFields -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 sqlalchemy.ext.asyncio import AsyncSession from config.enums import BusinessType -from utils.response_util import * -from utils.log_util import * -from utils.page_util import * +from config.get_db import get_db +from module_admin.annotation.log_annotation import log_decorator +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.entity.vo.job_vo import ( + DeleteJobLogModel, + DeleteJobModel, + EditJobModel, + JobLogPageQueryModel, + JobModel, + JobPageQueryModel, +) +from module_admin.entity.vo.user_vo import CurrentUserModel +from module_admin.service.job_log_service import JobLogService +from module_admin.service.job_service import JobService +from module_admin.service.login_service import LoginService from utils.common_util import bytes2file_response +from utils.log_util import logger +from utils.page_util import PageResponseModel +from utils.response_util import ResponseUtil jobController = APIRouter(prefix='/monitor', dependencies=[Depends(LoginService.get_current_user)]) -@jobController.get("/job/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) -async def get_system_job_list(request: Request, job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query), query_db: AsyncSession = Depends(get_db)): +@jobController.get( + '/job/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))] +) +async def get_system_job_list( + request: Request, + job_page_query: JobPageQueryModel = Depends(JobPageQueryModel.as_query), + query_db: AsyncSession = Depends(get_db), +): try: # 获取分页数据 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)) -@jobController.post("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))]) +@jobController.post('/job', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))]) @ValidateFields(validate_model='add_job') @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: add_job.create_by = current_user.user.user_name 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)) -@jobController.put("/job", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))]) +@jobController.put('/job', dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))]) @ValidateFields(validate_model='edit_job') @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: edit_job.update_by = current_user.user.user_name 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)) -@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) -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: edit_job.update_by = current_user.user.user_name 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)) -@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) async def execute_system_job(request: Request, execute_job: JobModel, query_db: AsyncSession = Depends(get_db)): try: @@ -104,7 +135,7 @@ async def execute_system_job(request: Request, execute_job: JobModel, query_db: 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) async def delete_system_job(request: Request, job_ids: str, query_db: AsyncSession = Depends(get_db)): try: @@ -121,7 +152,9 @@ async def delete_system_job(request: Request, job_ids: str, query_db: AsyncSessi 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)): try: 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)) -@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) -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: # 获取全量数据 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)) -@jobController.get("/jobLog/list", response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) -async def get_system_job_log_list(request: Request, job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_query), query_db: AsyncSession = Depends(get_db)): +@jobController.get( + '/jobLog/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))] +) +async def get_system_job_log_list( + request: Request, + job_log_page_query: JobLogPageQueryModel = Depends(JobLogPageQueryModel.as_query), + query_db: AsyncSession = Depends(get_db), +): 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('获取成功') return ResponseUtil.success(model_content=job_log_page_query_result) 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)) -@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) async def clear_system_job_log(request: Request, query_db: AsyncSession = Depends(get_db)): try: @@ -174,7 +219,7 @@ async def clear_system_job_log(request: Request, query_db: AsyncSession = Depend 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) async def delete_system_job_log(request: Request, job_log_ids: str, query_db: AsyncSession = Depends(get_db)): 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)) -@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) -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: # 获取全量数据 - 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) logger.info('导出成功') return ResponseUtil.streaming(data=bytes2file_response(job_log_export_result)) diff --git a/ruoyi-fastapi-backend/module_admin/dao/job_dao.py b/ruoyi-fastapi-backend/module_admin/dao/job_dao.py index 6fd1181..4c984f8 100644 --- a/ruoyi-fastapi-backend/module_admin/dao/job_dao.py +++ b/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 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 @@ -18,10 +18,7 @@ class JobDao: :param job_id: 定时任务id :return: 定时任务信息对象 """ - job_info = (await db.execute( - select(SysJob) - .where(SysJob.job_id == job_id) - )).scalars().first() + job_info = (await db.execute(select(SysJob).where(SysJob.job_id == job_id))).scalars().first() return job_info @@ -33,13 +30,20 @@ class JobDao: :param job: 定时任务参数对象 :return: 定时任务信息对象 """ - job_info = (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.invoke_target == job.invoke_target if job.invoke_target else True, - SysJob.cron_expression == job.cron_expression if job.cron_expression else True) - )).scalars().first() + job_info = ( + ( + 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.invoke_target == job.invoke_target if job.invoke_target else True, + SysJob.cron_expression == job.cron_expression if job.cron_expression else True, + ) + ) + ) + .scalars() + .first() + ) return job_info @@ -52,11 +56,15 @@ class JobDao: :param is_page: 是否开启分页 :return: 定时任务列表信息对象 """ - query = select(SysJob) \ - .where(SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, - SysJob.job_group == query_object.job_group if query_object.job_group else True, - SysJob.status == query_object.status if query_object.status else True) \ + query = ( + select(SysJob) + .where( + SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, + SysJob.job_group == query_object.job_group if query_object.job_group else True, + SysJob.status == query_object.status if query_object.status else True, + ) .distinct() + ) job_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page) return job_list @@ -68,11 +76,7 @@ class JobDao: :param db: orm对象 :return: 定时任务列表信息对象 """ - job_list = (await db.execute( - select(SysJob) - .where(SysJob.status == '0') - .distinct() - )).scalars().all() + job_list = (await db.execute(select(SysJob).where(SysJob.status == '0').distinct())).scalars().all() return job_list @@ -98,10 +102,7 @@ class JobDao: :param job: 需要更新的定时任务字典 :return: """ - await db.execute( - update(SysJob), - [job] - ) + await db.execute(update(SysJob), [job]) @classmethod async def delete_job_dao(cls, db: AsyncSession, job: JobModel): @@ -111,7 +112,4 @@ class JobDao: :param job: 定时任务对象 :return: """ - await db.execute( - delete(SysJob) - .where(SysJob.job_id.in_([job.job_id])) - ) + await db.execute(delete(SysJob).where(SysJob.job_id.in_([job.job_id]))) diff --git a/ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py b/ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py index 7bc8abe..6d64a91 100644 --- a/ruoyi-fastapi-backend/module_admin/dao/job_log_dao.py +++ b/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.orm import Session from module_admin.entity.do.job_do import SysJobLog -from module_admin.entity.vo.job_vo import * +from module_admin.entity.vo.job_vo import JobLogModel, JobLogPageQueryModel from utils.page_util import PageUtil -from datetime import datetime, time class JobLogDao: @@ -21,15 +21,21 @@ class JobLogDao: :param is_page: 是否开启分页 :return: 定时任务日志列表信息对象 """ - query = select(SysJobLog) \ - .where(SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, - SysJobLog.job_group == query_object.job_group if query_object.job_group else True, - SysJobLog.status == query_object.status if query_object.status else True, - SysJobLog.create_time.between( - datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59))) - if query_object.begin_time and query_object.end_time else True) \ + query = ( + select(SysJobLog) + .where( + SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, + SysJobLog.job_group == query_object.job_group if query_object.job_group else True, + SysJobLog.status == query_object.status if query_object.status else True, + SysJobLog.create_time.between( + datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)), + ) + if query_object.begin_time and query_object.end_time + else True, + ) .distinct() + ) job_log_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page) return job_log_list @@ -56,10 +62,7 @@ class JobLogDao: :param job_log: 定时任务日志对象 :return: """ - await db.execute( - delete(SysJobLog) - .where(SysJobLog.job_log_id.in_([job_log.job_log_id])) - ) + await db.execute(delete(SysJobLog).where(SysJobLog.job_log_id.in_([job_log.job_log_id]))) @classmethod async def clear_job_log_dao(cls, db: AsyncSession): @@ -68,6 +71,4 @@ class JobLogDao: :param db: orm对象 :return: """ - await db.execute( - delete(SysJobLog) - ) + await db.execute(delete(SysJobLog)) diff --git a/ruoyi-fastapi-backend/module_admin/entity/do/job_do.py b/ruoyi-fastapi-backend/module_admin/entity/do/job_do.py index aef168f..c6d671b 100644 --- a/ruoyi-fastapi-backend/module_admin/entity/do/job_do.py +++ b/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 sqlalchemy import Column, DateTime, Integer, String +from config.database import Base class SysJob(Base): """ 定时任务调度表 """ + __tablename__ = 'sys_job' job_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务ID') job_name = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务名称') job_group = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务组名') - job_executor = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务执行器') + 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禁止)') + 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='创建时间') @@ -31,17 +43,22 @@ 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='任务执行器') + 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失败)') + 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='创建时间') diff --git a/ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py b/ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py index f39cc21..4dd9e38 100644 --- a/ruoyi-fastapi-backend/module_admin/entity/vo/job_vo.py +++ b/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.alias_generators import to_camel from pydantic_validation_decorator import NotBlank, Size -from typing import Union, Optional, List, Literal -from datetime import datetime -from module_admin.annotation.pydantic_annotation import as_query, as_form +from typing import Literal, Optional +from module_admin.annotation.pydantic_annotation import as_form, as_query class JobModel(BaseModel): """ 定时任务调度表对应pydantic模型 """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) 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_kwargs: Optional[str] = Field(default=None, description='关键字参数') cron_expression: Optional[str] = Field(default=None, description='cron执行表达式') - misfire_policy: Optional[Literal['1', '2', '3']] = Field(default=None, description='计划执行错误策略(1立即执行 2执行一次 3放弃执行)') + misfire_policy: Optional[Literal['1', '2', '3']] = Field( + default=None, description='计划执行错误策略(1立即执行 2执行一次 3放弃执行)' + ) concurrent: Optional[Literal['0', '1']] = Field(default=None, description='是否并发执行(0允许 1禁止)') status: Optional[Literal['0', '1']] = Field(default=None, description='状态(0正常 1暂停)') create_by: Optional[str] = Field(default=None, description='创建者') @@ -48,6 +51,7 @@ class JobLogModel(BaseModel): """ 定时任务调度日志表对应pydantic模型 """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) 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='开始时间') end_time: Optional[str] = Field(default=None, description='结束时间') @@ -78,6 +83,7 @@ class JobPageQueryModel(JobQueryModel): """ 定时任务管理分页查询模型 """ + page_num: int = Field(default=1, description='当前页码') page_size: int = Field(default=10, description='每页记录数') @@ -86,6 +92,7 @@ class EditJobModel(JobModel): """ 编辑定时任务模型 """ + type: Optional[str] = Field(default=None, description='操作类型') @@ -93,6 +100,7 @@ class DeleteJobModel(BaseModel): """ 删除定时任务模型 """ + model_config = ConfigDict(alias_generator=to_camel) job_ids: str = Field(description='需要删除的定时任务ID') @@ -102,6 +110,7 @@ class JobLogQueryModel(JobLogModel): """ 定时任务日志不分页查询模型 """ + begin_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_size: int = Field(default=10, description='每页记录数') @@ -120,6 +130,7 @@ class DeleteJobLogModel(BaseModel): """ 删除定时任务日志模型 """ + model_config = ConfigDict(alias_generator=to_camel) job_log_ids: str = Field(description='需要删除的定时任务日志ID') diff --git a/ruoyi-fastapi-backend/module_admin/service/job_log_service.py b/ruoyi-fastapi-backend/module_admin/service/job_log_service.py index 99d2231..a425b0b 100644 --- a/ruoyi-fastapi-backend/module_admin/service/job_log_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/job_log_service.py @@ -1,6 +1,11 @@ -from module_admin.dao.job_log_dao import * -from module_admin.service.dict_service import Request, DictDataService +from fastapi import Request +from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.orm import Session +from typing import List +from module_admin.dao.job_log_dao import JobLogDao from module_admin.entity.vo.common_vo import CrudResponseModel +from module_admin.entity.vo.job_vo import DeleteJobLogModel, JobLogModel, JobLogPageQueryModel +from module_admin.service.dict_service import DictDataService from utils.common_util import export_list2excel @@ -10,7 +15,9 @@ class JobLogService: """ @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 :param query_db: orm对象 @@ -89,26 +96,32 @@ class JobLogService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "jobLogId": "任务日志编码", - "jobName": "任务名称", - "jobGroup": "任务组名", - "jobExecutor": "任务执行器", - "invokeTarget": "调用目标字符串", - "jobArgs": "位置参数", - "jobKwargs": "关键字参数", - "jobTrigger": "任务触发器", - "jobMessage": "日志信息", - "status": "执行状态", - "exceptionInfo": "异常信息", - "createTime": "创建时间", + 'jobLogId': '任务日志编码', + 'jobName': '任务名称', + 'jobGroup': '任务组名', + 'jobExecutor': '任务执行器', + 'invokeTarget': '调用目标字符串', + 'jobArgs': '位置参数', + 'jobKwargs': '关键字参数', + 'jobTrigger': '任务触发器', + 'jobMessage': '日志信息', + 'status': '执行状态', + 'exceptionInfo': '异常信息', + 'createTime': '创建时间', } data = job_log_list - job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group') + job_group_list = await DictDataService.query_dict_data_list_from_cache_services( + request.app.state.redis, dict_type='sys_job_group' + ) job_group_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_group_list] job_group_option_dict = {item.get('value'): item for item in job_group_option} - job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_executor') - job_executor_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list] + job_executor_list = await DictDataService.query_dict_data_list_from_cache_services( + request.app.state.redis, dict_type='sys_job_executor' + ) + job_executor_option = [ + dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list + ] job_executor_option_dict = {item.get('value'): item for item in job_executor_option} for item in data: @@ -120,8 +133,9 @@ class JobLogService: item['jobGroup'] = job_group_option_dict.get(str(item.get('jobGroup'))).get('label') if str(item.get('jobExecutor')) in job_executor_option_dict.keys(): item['jobExecutor'] = job_executor_option_dict.get(str(item.get('jobExecutor'))).get('label') - new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in - data] + new_data = [ + {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data + ] binary_data = export_list2excel(new_data) return binary_data diff --git a/ruoyi-fastapi-backend/module_admin/service/job_service.py b/ruoyi-fastapi-backend/module_admin/service/job_service.py index 78775d4..87e460f 100644 --- a/ruoyi-fastapi-backend/module_admin/service/job_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/job_service.py @@ -1,8 +1,12 @@ -from module_admin.dao.job_dao import * -from module_admin.service.dict_service import Request, DictDataService -from module_admin.entity.vo.common_vo import CrudResponseModel -from utils.common_util import export_list2excel, CamelCaseUtil +from fastapi import Request +from sqlalchemy.ext.asyncio import AsyncSession +from typing import List from config.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: @@ -11,7 +15,9 @@ class JobService: """ @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 :param query_db: orm对象 @@ -61,7 +67,12 @@ class JobService: del edit_job['type'] job_info = await 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): + 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) if job: result = dict(is_success=False, message='定时任务已存在') @@ -152,30 +163,36 @@ class JobService: """ # 创建一个映射字典,将英文键映射到中文键 mapping_dict = { - "jobId": "任务编码", - "jobName": "任务名称", - "jobGroup": "任务组名", - "jobExecutor": "任务执行器", - "invokeTarget": "调用目标字符串", - "jobArgs": "位置参数", - "jobKwargs": "关键字参数", - "cronExpression": "cron执行表达式", - "misfirePolicy": "计划执行错误策略", - "concurrent": "是否并发执行", - "status": "状态", - "createBy": "创建者", - "createTime": "创建时间", - "updateBy": "更新者", - "updateTime": "更新时间", - "remark": "备注", + 'jobId': '任务编码', + 'jobName': '任务名称', + 'jobGroup': '任务组名', + 'jobExecutor': '任务执行器', + 'invokeTarget': '调用目标字符串', + 'jobArgs': '位置参数', + 'jobKwargs': '关键字参数', + 'cronExpression': 'cron执行表达式', + 'misfirePolicy': '计划执行错误策略', + 'concurrent': '是否并发执行', + 'status': '状态', + 'createBy': '创建者', + 'createTime': '创建时间', + 'updateBy': '更新者', + 'updateTime': '更新时间', + 'remark': '备注', } data = job_list - job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group') + job_group_list = await DictDataService.query_dict_data_list_from_cache_services( + request.app.state.redis, dict_type='sys_job_group' + ) job_group_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_group_list] job_group_option_dict = {item.get('value'): item for item in job_group_option} - job_executor_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_executor') - job_executor_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list] + job_executor_list = await DictDataService.query_dict_data_list_from_cache_services( + request.app.state.redis, dict_type='sys_job_executor' + ) + job_executor_option = [ + dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in job_executor_list + ] job_executor_option_dict = {item.get('value'): item for item in job_executor_option} for item in data: @@ -197,7 +214,9 @@ class JobService: item['concurrent'] = '允许' else: item['concurrent'] = '禁止' - new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + new_data = [ + {mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data + ] binary_data = export_list2excel(new_data) return binary_data