feat: 实现通知渠道管理功能
All checks were successful
continuous-integration/drone/push Build is passing

- 新增 platform_notification_channels 表管理通知渠道(钉钉/企微机器人)
- 新增通知渠道管理页面,支持创建、编辑、测试、删除
- 定时任务增加通知渠道选择和企微应用选择
- 脚本执行支持返回值(result变量),自动发送到配置的渠道
- 调度器执行脚本后根据配置自动发送通知

使用方式:
1. 在「通知渠道」页面为租户配置钉钉/企微机器人
2. 创建定时任务时选择通知渠道
3. 脚本中设置 result = {'content': '内容', 'title': '标题'}
4. 任务执行后自动发送到配置的渠道
This commit is contained in:
2026-01-28 17:02:20 +08:00
parent d9fa9708ce
commit 2fbba63884
12 changed files with 800 additions and 25 deletions

View File

@@ -33,6 +33,8 @@ class TaskCreate(BaseModel):
retry_interval: Optional[int] = 60
alert_on_failure: Optional[bool] = False
alert_webhook: Optional[str] = None
notify_channels: Optional[List[int]] = None # 通知渠道ID列表
notify_wecom_app_id: Optional[int] = None # 企微应用ID
class TaskUpdate(BaseModel):
@@ -51,6 +53,8 @@ class TaskUpdate(BaseModel):
alert_on_failure: Optional[bool] = None
alert_webhook: Optional[str] = None
is_enabled: Optional[bool] = None
notify_channels: Optional[List[int]] = None
notify_wecom_app_id: Optional[int] = None
class SecretCreate(BaseModel):
@@ -126,6 +130,8 @@ async def create_task(data: TaskCreate, db: Session = Depends(get_db)):
retry_interval=data.retry_interval,
alert_on_failure=data.alert_on_failure,
alert_webhook=data.alert_webhook,
notify_channels=data.notify_channels,
notify_wecom_app_id=data.notify_wecom_app_id,
is_enabled=True
)
@@ -175,6 +181,10 @@ async def update_task(task_id: int, data: TaskUpdate, db: Session = Depends(get_
task.alert_on_failure = data.alert_on_failure
if data.alert_webhook is not None:
task.alert_webhook = data.alert_webhook
if data.notify_channels is not None:
task.notify_channels = data.notify_channels
if data.notify_wecom_app_id is not None:
task.notify_wecom_app_id = data.notify_wecom_app_id
if data.is_enabled is not None:
task.is_enabled = data.is_enabled
@@ -490,6 +500,14 @@ def format_task(task: ScheduledTask, include_content: bool = False) -> dict:
except:
time_points = []
# 处理 notify_channels
notify_channels = task.notify_channels
if isinstance(notify_channels, str):
try:
notify_channels = json.loads(notify_channels)
except:
notify_channels = []
data = {
"id": task.id,
"tenant_id": task.tenant_id,
@@ -505,6 +523,8 @@ def format_task(task: ScheduledTask, include_content: bool = False) -> dict:
"retry_interval": task.retry_interval,
"alert_on_failure": bool(task.alert_on_failure),
"alert_webhook": task.alert_webhook,
"notify_channels": notify_channels or [],
"notify_wecom_app_id": task.notify_wecom_app_id,
"created_at": task.created_at,
"updated_at": task.updated_at
}