diff --git a/README.md b/README.md index b7cb215..4bd2a86 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@
-
+
diff --git a/dash-fastapi-backend/.env.dev b/dash-fastapi-backend/.env.dev
index f79f19e..8b2d308 100644
--- a/dash-fastapi-backend/.env.dev
+++ b/dash-fastapi-backend/.env.dev
@@ -10,7 +10,7 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 9099
# 应用版本
-APP_VERSION= '2.1.0'
+APP_VERSION= '2.1.1'
# 应用是否开启热重载
APP_RELOAD = true
# 应用是否开启IP归属区域查询
diff --git a/dash-fastapi-backend/.env.prod b/dash-fastapi-backend/.env.prod
index 55c011d..fb89360 100644
--- a/dash-fastapi-backend/.env.prod
+++ b/dash-fastapi-backend/.env.prod
@@ -10,7 +10,7 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 9099
# 应用版本
-APP_VERSION= '2.1.0'
+APP_VERSION= '2.1.1'
# 应用是否开启热重载
APP_RELOAD = false
# 应用是否开启IP归属区域查询
diff --git a/dash-fastapi-backend/config/get_scheduler.py b/dash-fastapi-backend/config/get_scheduler.py
index bf7547d..3fb66c4 100644
--- a/dash-fastapi-backend/config/get_scheduler.py
+++ b/dash-fastapi-backend/config/get_scheduler.py
@@ -1,11 +1,13 @@
import json
from apscheduler.events import EVENT_ALL
-from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
-from apscheduler.schedulers.background import BackgroundScheduler
+from apscheduler.executors.asyncio import AsyncIOExecutor
+from apscheduler.executors.pool import ProcessPoolExecutor
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.jobstores.redis import RedisJobStore
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
+from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
+from asyncio import iscoroutinefunction
from datetime import datetime, timedelta
from sqlalchemy.engine import create_engine
from sqlalchemy.orm import sessionmaker
@@ -109,9 +111,9 @@ def __find_recent_workday(cls, day: int):
)
),
}
-executors = {'default': ThreadPoolExecutor(20), 'processpool': ProcessPoolExecutor(5)}
+executors = {'default': AsyncIOExecutor(), 'processpool': ProcessPoolExecutor(5)}
job_defaults = {'coalesce': False, 'max_instance': 1}
-scheduler = BackgroundScheduler()
+scheduler = AsyncIOScheduler()
scheduler.configure(jobstores=job_stores, executors=executors, job_defaults=job_defaults)
@@ -132,9 +134,7 @@ async def init_system_scheduler(cls):
async with AsyncSessionLocal() as session:
job_list = await JobDao.get_job_list_for_scheduler(session)
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.remove_scheduler_job(job_id=str(item.job_id))
cls.add_scheduler_job(item)
scheduler.add_listener(cls.scheduler_event_listener, EVENT_ALL)
logger.info('系统初始定时任务加载成功')
@@ -169,6 +169,10 @@ def add_scheduler_job(cls, job_info: JobModel):
:param job_info: 任务对象信息
:return:
"""
+ job_func = eval(job_info.invoke_target)
+ job_executor = job_info.job_executor
+ if iscoroutinefunction(job_func):
+ job_executor = 'default'
scheduler.add_job(
func=eval(job_info.invoke_target),
trigger=MyCronTrigger.from_crontab(job_info.cron_expression),
@@ -180,7 +184,7 @@ def add_scheduler_job(cls, job_info: JobModel):
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,
+ executor=job_executor,
)
@classmethod
@@ -191,6 +195,10 @@ def execute_scheduler_job_once(cls, job_info: JobModel):
:param job_info: 任务对象信息
:return:
"""
+ job_func = eval(job_info.invoke_target)
+ job_executor = job_info.job_executor
+ if iscoroutinefunction(job_func):
+ job_executor = 'default'
scheduler.add_job(
func=eval(job_info.invoke_target),
trigger='date',
@@ -203,7 +211,7 @@ def execute_scheduler_job_once(cls, job_info: JobModel):
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,
+ executor=job_executor,
)
@classmethod
@@ -214,7 +222,9 @@ def remove_scheduler_job(cls, job_id: Union[str, int]):
:param job_id: 任务id
:return:
"""
- scheduler.remove_job(job_id=str(job_id))
+ query_job = cls.get_scheduler_job(job_id=job_id)
+ if query_job:
+ scheduler.remove_job(job_id=str(job_id))
@classmethod
def scheduler_event_listener(cls, event):
diff --git a/dash-fastapi-backend/module_admin/service/job_service.py b/dash-fastapi-backend/module_admin/service/job_service.py
index 5a8c3bd..91f784f 100644
--- a/dash-fastapi-backend/module_admin/service/job_service.py
+++ b/dash-fastapi-backend/module_admin/service/job_service.py
@@ -129,9 +129,7 @@ async def edit_job_services(cls, query_db: AsyncSession, page_object: EditJobMod
raise ServiceException(message=f'修改定时任务{page_object.job_name}失败,定时任务已存在')
try:
await 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'))
+ SchedulerUtil.remove_scheduler_job(job_id=edit_job.get('job_id'))
if edit_job.get('status') == '0':
job_info = await cls.job_detail_services(query_db, edit_job.get('job_id'))
SchedulerUtil.add_scheduler_job(job_info=job_info)
@@ -152,9 +150,7 @@ async def execute_job_once_services(cls, query_db: AsyncSession, page_object: Jo
: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)
+ SchedulerUtil.remove_scheduler_job(job_id=page_object.job_id)
job_info = await cls.job_detail_services(query_db, page_object.job_id)
if job_info:
SchedulerUtil.execute_scheduler_job_once(job_info=job_info)
@@ -176,9 +172,7 @@ async def delete_job_services(cls, query_db: AsyncSession, page_object: DeleteJo
try:
for job_id in job_id_list:
await JobDao.delete_job_dao(query_db, JobModel(job_id=job_id))
- query_job = SchedulerUtil.get_scheduler_job(job_id=job_id)
- if query_job:
- SchedulerUtil.remove_scheduler_job(job_id=job_id)
+ SchedulerUtil.remove_scheduler_job(job_id=job_id)
await query_db.commit()
return CrudResponseModel(is_success=True, message='删除成功')
except Exception as e:
diff --git a/dash-fastapi-backend/module_admin/service/menu_service.py b/dash-fastapi-backend/module_admin/service/menu_service.py
index 2cf7639..af636f7 100644
--- a/dash-fastapi-backend/module_admin/service/menu_service.py
+++ b/dash-fastapi-backend/module_admin/service/menu_service.py
@@ -99,9 +99,9 @@ async def add_menu_services(cls, query_db: AsyncSession, page_object: MenuModel)
:return: 新增菜单校验结果
"""
if not await cls.check_menu_name_unique_services(query_db, page_object):
- raise ServiceException(message=f'新增菜单{page_object.post_name}失败,菜单名称已存在')
+ raise ServiceException(message=f'新增菜单{page_object.menu_name}失败,菜单名称已存在')
elif page_object.is_frame == MenuConstant.YES_FRAME and not StringUtil.is_http(page_object.path):
- raise ServiceException(message=f'新增菜单{page_object.post_name}失败,地址必须以http(s)://开头')
+ raise ServiceException(message=f'新增菜单{page_object.menu_name}失败,地址必须以http(s)://开头')
else:
try:
await MenuDao.add_menu_dao(query_db, page_object)
@@ -124,11 +124,11 @@ async def edit_menu_services(cls, query_db: AsyncSession, page_object: MenuModel
menu_info = await cls.menu_detail_services(query_db, page_object.menu_id)
if menu_info.menu_id:
if not await cls.check_menu_name_unique_services(query_db, page_object):
- raise ServiceException(message=f'修改菜单{page_object.post_name}失败,菜单名称已存在')
+ raise ServiceException(message=f'修改菜单{page_object.menu_name}失败,菜单名称已存在')
elif page_object.is_frame == MenuConstant.YES_FRAME and not StringUtil.is_http(page_object.path):
- raise ServiceException(message=f'修改菜单{page_object.post_name}失败,地址必须以http(s)://开头')
+ raise ServiceException(message=f'修改菜单{page_object.menu_name}失败,地址必须以http(s)://开头')
elif page_object.menu_id == page_object.parent_id:
- raise ServiceException(message=f'修改菜单{page_object.post_name}失败,上级菜单不能选择自己')
+ raise ServiceException(message=f'修改菜单{page_object.menu_name}失败,上级菜单不能选择自己')
else:
try:
await MenuDao.edit_menu_dao(query_db, edit_menu)
diff --git a/dash-fastapi-backend/module_task/scheduler_test.py b/dash-fastapi-backend/module_task/scheduler_test.py
index 1c8441f..b282732 100644
--- a/dash-fastapi-backend/module_task/scheduler_test.py
+++ b/dash-fastapi-backend/module_task/scheduler_test.py
@@ -2,6 +2,18 @@
def job(*args, **kwargs):
+ """
+ 定时任务执行同步函数示例
+ """
print(args)
print(kwargs)
- print(f'{datetime.now()}执行了')
+ print(f'{datetime.now()}同步函数执行了')
+
+
+async def async_job(*args, **kwargs):
+ """
+ 定时任务执行异步函数示例
+ """
+ print(args)
+ print(kwargs)
+ print(f'{datetime.now()}异步函数执行了')
diff --git a/dash-fastapi-frontend/.env.dev b/dash-fastapi-frontend/.env.dev
index 1c39a51..b2cb98f 100644
--- a/dash-fastapi-frontend/.env.dev
+++ b/dash-fastapi-frontend/.env.dev
@@ -16,7 +16,7 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 8088
# 应用版本
-APP_VERSION= '2.1.0'
+APP_VERSION= '2.1.1'
# 应用是否开启debug模式
APP_DEBUG = true
# flask-compress压缩配置
diff --git a/dash-fastapi-frontend/.env.prod b/dash-fastapi-frontend/.env.prod
index 8d9b01e..71e3dc3 100644
--- a/dash-fastapi-frontend/.env.prod
+++ b/dash-fastapi-frontend/.env.prod
@@ -16,7 +16,7 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 8088
# 应用版本
-APP_VERSION= '2.1.0'
+APP_VERSION= '2.1.1'
# 应用是否开启debug模式
APP_DEBUG = false
# flask-compress压缩配置
diff --git a/requirements-pg.txt b/requirements-pg.txt
index 24b2c64..26e3ff0 100644
--- a/requirements-pg.txt
+++ b/requirements-pg.txt
@@ -1,11 +1,11 @@
APScheduler==3.10.4
asyncpg==0.30.0
-cachebox==4.1.2
-dash==2.18.1
+cachebox==4.2.3
+dash==2.18.2
DateTime==5.5
fastapi[all]==0.115.0
feffery-antd-charts==0.1.0rc5
-feffery-antd-components==0.3.8
+feffery-antd-components==0.3.10
feffery-markdown-components==0.2.10
feffery-utils-components==0.2.0rc24
Flask-Compress==1.15
@@ -16,11 +16,11 @@ pandas==2.2.2
passlib[bcrypt]==1.7.4
Pillow==10.4.0
psutil==6.0.0
-pydantic-validation-decorator==0.1.2
+pydantic-validation-decorator==0.1.4
PyJWT[crypto]==2.8.0
psycopg2==2.9.10
redis==5.0.7
requests==2.32.3
SQLAlchemy[asyncio]==2.0.31
user-agents==2.2.0
-waitress==3.0.0
+waitress==3.0.1
diff --git a/requirements.txt b/requirements.txt
index 790b650..d88aec7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,11 +1,11 @@
APScheduler==3.10.4
asyncmy==0.2.9
-cachebox==4.1.2
-dash==2.18.1
+cachebox==4.2.3
+dash==2.18.2
DateTime==5.5
fastapi[all]==0.115.0
feffery-antd-charts==0.1.0rc5
-feffery-antd-components==0.3.8
+feffery-antd-components==0.3.10
feffery-markdown-components==0.2.10
feffery-utils-components==0.2.0rc24
Flask-Compress==1.15
@@ -16,11 +16,11 @@ pandas==2.2.2
passlib[bcrypt]==1.7.4
Pillow==10.4.0
psutil==6.0.0
-pydantic-validation-decorator==0.1.2
+pydantic-validation-decorator==0.1.4
PyJWT[crypto]==2.8.0
PyMySQL==1.1.1
redis==5.0.7
requests==2.32.3
SQLAlchemy[asyncio]==2.0.31
user-agents==2.2.0
-waitress==3.0.0
+waitress==3.0.1