- 新增 platform_scheduled_tasks, platform_task_logs, platform_script_vars, platform_secrets 数据库表 - 实现 ScriptSDK 提供 AI/通知/DB/HTTP/变量存储/参数获取等功能 - 实现安全的脚本执行器,支持沙箱环境和禁止危险操作 - 实现 APScheduler 调度服务,支持简单时间点和 CRON 表达式 - 新增定时任务 API 路由,包含 CRUD、执行、日志、密钥管理 - 新增定时任务前端页面,支持脚本编辑、测试运行、日志查看
This commit is contained in:
@@ -8,6 +8,7 @@ from .stats import AICallEvent, TenantUsageDaily
|
||||
from .logs import PlatformLog
|
||||
from .alert import AlertRule, AlertRecord, NotificationChannel
|
||||
from .pricing import ModelPricing, TenantBilling
|
||||
from .scheduled_task import ScheduledTask, TaskLog, ScriptVar, Secret
|
||||
|
||||
__all__ = [
|
||||
"Tenant",
|
||||
@@ -24,5 +25,9 @@ __all__ = [
|
||||
"AlertRecord",
|
||||
"NotificationChannel",
|
||||
"ModelPricing",
|
||||
"TenantBilling"
|
||||
"TenantBilling",
|
||||
"ScheduledTask",
|
||||
"TaskLog",
|
||||
"ScriptVar",
|
||||
"Secret"
|
||||
]
|
||||
|
||||
@@ -18,11 +18,6 @@ class App(Base):
|
||||
# [{"code": "brainstorm", "name": "头脑风暴", "path": "/brainstorm"}, ...]
|
||||
tools = Column(Text)
|
||||
|
||||
# 配置项定义(JSON 数组)- 定义租户可配置的参数
|
||||
# [{"key": "industry", "label": "行业类型", "type": "radio", "options": [...], "default": "...", "required": false}, ...]
|
||||
# type: text(文本) | radio(单选) | select(下拉多选) | switch(开关)
|
||||
config_schema = Column(Text)
|
||||
|
||||
# 是否需要企微JS-SDK
|
||||
require_jssdk = Column(SmallInteger, default=0) # 0-不需要 1-需要
|
||||
|
||||
|
||||
96
backend/app/models/scheduled_task.py
Normal file
96
backend/app/models/scheduled_task.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""定时任务相关模型"""
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, BigInteger, Integer, String, Text, Enum, SmallInteger, TIMESTAMP, DateTime
|
||||
from ..database import Base
|
||||
|
||||
|
||||
class ScheduledTask(Base):
|
||||
"""定时任务表"""
|
||||
__tablename__ = "platform_scheduled_tasks"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
tenant_id = Column(String(50))
|
||||
task_name = Column(String(100), nullable=False)
|
||||
task_type = Column(Enum('webhook', 'script'), nullable=False, default='script')
|
||||
|
||||
# 调度配置
|
||||
schedule_type = Column(Enum('simple', 'cron'), nullable=False, default='simple')
|
||||
time_points = Column(Text) # JSON数组 ["08:00", "12:00"]
|
||||
cron_expression = Column(String(100))
|
||||
|
||||
# Webhook配置
|
||||
webhook_url = Column(String(500))
|
||||
webhook_method = Column(String(10), default='POST')
|
||||
webhook_headers = Column(Text) # JSON格式
|
||||
|
||||
# 脚本配置
|
||||
script_content = Column(Text)
|
||||
script_timeout = Column(Integer, default=300)
|
||||
|
||||
# 输入参数
|
||||
input_params = Column(Text) # JSON格式
|
||||
|
||||
# 重试配置
|
||||
retry_count = Column(Integer, default=0)
|
||||
retry_interval = Column(Integer, default=60)
|
||||
|
||||
# 告警配置
|
||||
alert_on_failure = Column(SmallInteger, default=0)
|
||||
alert_webhook = Column(String(500))
|
||||
|
||||
# 状态
|
||||
status = Column(SmallInteger, default=1) # 0-禁用 1-启用
|
||||
last_run_at = Column(DateTime)
|
||||
last_run_status = Column(String(20))
|
||||
|
||||
created_at = Column(TIMESTAMP, default=datetime.now)
|
||||
updated_at = Column(TIMESTAMP, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
|
||||
class TaskLog(Base):
|
||||
"""任务执行日志"""
|
||||
__tablename__ = "platform_task_logs"
|
||||
|
||||
id = Column(BigInteger, primary_key=True, autoincrement=True)
|
||||
task_id = Column(Integer, nullable=False)
|
||||
tenant_id = Column(String(50))
|
||||
trace_id = Column(String(100))
|
||||
|
||||
status = Column(Enum('running', 'success', 'failed'), nullable=False)
|
||||
started_at = Column(DateTime, nullable=False)
|
||||
finished_at = Column(DateTime)
|
||||
duration_ms = Column(Integer)
|
||||
|
||||
output = Column(Text)
|
||||
error = Column(Text)
|
||||
retry_count = Column(Integer, default=0)
|
||||
|
||||
created_at = Column(TIMESTAMP, default=datetime.now)
|
||||
|
||||
|
||||
class ScriptVar(Base):
|
||||
"""脚本变量存储"""
|
||||
__tablename__ = "platform_script_vars"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
task_id = Column(Integer, nullable=False)
|
||||
tenant_id = Column(String(50))
|
||||
var_key = Column(String(100), nullable=False)
|
||||
var_value = Column(Text) # JSON格式
|
||||
|
||||
created_at = Column(TIMESTAMP, default=datetime.now)
|
||||
updated_at = Column(TIMESTAMP, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
|
||||
class Secret(Base):
|
||||
"""密钥管理"""
|
||||
__tablename__ = "platform_secrets"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
tenant_id = Column(String(50)) # NULL为全局
|
||||
secret_key = Column(String(100), nullable=False)
|
||||
secret_value = Column(Text, nullable=False)
|
||||
description = Column(String(255))
|
||||
|
||||
created_at = Column(TIMESTAMP, default=datetime.now)
|
||||
updated_at = Column(TIMESTAMP, default=datetime.now, onupdate=datetime.now)
|
||||
@@ -23,10 +23,6 @@ class TenantApp(Base):
|
||||
# 功能权限
|
||||
allowed_tools = Column(Text) # JSON 数组
|
||||
|
||||
# 自定义配置(JSON 数组)
|
||||
# [{"key": "industry", "value": "medical_beauty", "remark": "医美行业"}, ...]
|
||||
custom_configs = Column(Text)
|
||||
|
||||
status = Column(SmallInteger, default=1)
|
||||
created_at = Column(TIMESTAMP, default=datetime.now)
|
||||
updated_at = Column(TIMESTAMP, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
Reference in New Issue
Block a user