diff --git a/docs/docs.go b/docs/docs.go index df52c739..73bbe84d 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1458,7 +1458,7 @@ const docTemplate = `{ "SessionCookie": [] } ], - "description": "绑定系统内置事件、推送渠道、接收目标并创建通知事件配置,需要管理员权限", + "description": "绑定系统内置事件或异步任务、推送渠道、接收目标并创建通知事件配置,需要管理员权限", "consumes": [ "application/json" ], @@ -6012,6 +6012,10 @@ const docTemplate = `{ "type": "string" } }, + "task_type": { + "description": "关联的异步任务类型", + "type": "string" + }, "template": { "description": "消息模板 JSON", "type": "string" @@ -6513,9 +6517,6 @@ const docTemplate = `{ }, "push.CreateEventRequest": { "type": "object", - "required": [ - "event_key" - ], "properties": { "channels": { "type": "array", @@ -6535,6 +6536,10 @@ const docTemplate = `{ "type": "string" } }, + "task_type": { + "description": "关联的异步任务类型", + "type": "string" + }, "template": { "type": "string" } diff --git a/docs/swagger.json b/docs/swagger.json index 8308bdb2..5505a383 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1451,7 +1451,7 @@ "SessionCookie": [] } ], - "description": "绑定系统内置事件、推送渠道、接收目标并创建通知事件配置,需要管理员权限", + "description": "绑定系统内置事件或异步任务、推送渠道、接收目标并创建通知事件配置,需要管理员权限", "consumes": [ "application/json" ], @@ -6005,6 +6005,10 @@ "type": "string" } }, + "task_type": { + "description": "关联的异步任务类型", + "type": "string" + }, "template": { "description": "消息模板 JSON", "type": "string" @@ -6506,9 +6510,6 @@ }, "push.CreateEventRequest": { "type": "object", - "required": [ - "event_key" - ], "properties": { "channels": { "type": "array", @@ -6528,6 +6529,10 @@ "type": "string" } }, + "task_type": { + "description": "关联的异步任务类型", + "type": "string" + }, "template": { "type": "string" } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index c25ee54b..13c3309d 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -361,6 +361,9 @@ definitions: items: type: string type: array + task_type: + description: 关联的异步任务类型 + type: string template: description: 消息模板 JSON type: string @@ -715,10 +718,11 @@ definitions: items: type: string type: array + task_type: + description: 关联的异步任务类型 + type: string template: type: string - required: - - event_key type: object push.Definition: properties: @@ -2268,7 +2272,7 @@ paths: post: consumes: - application/json - description: 绑定系统内置事件、推送渠道、接收目标并创建通知事件配置,需要管理员权限 + description: 绑定系统内置事件或异步任务、推送渠道、接收目标并创建通知事件配置,需要管理员权限 parameters: - description: 创建参数 in: body diff --git a/frontend/components/common/admin/push/events-tab.tsx b/frontend/components/common/admin/push/events-tab.tsx index 269b764b..774e6178 100644 --- a/frontend/components/common/admin/push/events-tab.tsx +++ b/frontend/components/common/admin/push/events-tab.tsx @@ -63,6 +63,12 @@ export function EventsTab() { queryFn: () => services.push.listBuiltInEvents(), }) + // --- 获取所有系统可调度任务类型 --- + const taskTypesQuery = useQuery({ + queryKey: ["admin", "task-types"], + queryFn: () => services.admin.getTaskTypes(), + }) + // --- 修改保存事件 Mutation --- const updateEventMutation = useMutation({ mutationFn: ({ id, data }: { id: number; data: UpdatePushEventRequest }) => services.push.updateEvent(id, data), @@ -93,6 +99,8 @@ export function EventsTab() { queryClient.invalidateQueries({ queryKey: ["admin", "push-events"] }) setCreateEventOpen(false) setNewEventKey("") + setNewEventType("builtin") + setNewEventTaskType("") setNewEventChannels([]) setNewEventEnabled(true) }, @@ -121,7 +129,9 @@ export function EventsTab() { // 事件创建对话框状态 const [createEventOpen, setCreateEventOpen] = React.useState(false) + const [newEventType, setNewEventType] = React.useState<"builtin" | "task">("builtin") const [newEventKey, setNewEventKey] = React.useState("") + const [newEventTaskType, setNewEventTaskType] = React.useState("") const [newEventChannels, setNewEventChannels] = React.useState([]) const [newEventTargets, setNewEventTargets] = React.useState("") const [newEventTemplate, setNewEventTemplate] = React.useState("") @@ -168,6 +178,8 @@ export function EventsTab() { const handleCreateEventClick = () => { setNewEventKey("") + setNewEventType("builtin") + setNewEventTaskType("") setNewEventChannels([]) setNewEventTargets("") setNewEventTemplate("") @@ -185,11 +197,30 @@ export function EventsTab() { } } + const handleNewEventTaskTypeChange = (taskType: string) => { + setNewEventTaskType(taskType) + const taskMeta = (taskTypesQuery.data ?? []).find(t => t.asynq_task === taskType) + if (taskMeta) { + const defaultTemplate = { + title: `任务完成: ${taskMeta.name}`, + content: `异步任务 {{task_name}} 已完成。状态: {{task_status}},耗时: {{task_duration}} ms。`, + level: "INFO", + } + setNewEventTemplate(JSON.stringify(defaultTemplate, null, 2)) + } else { + setNewEventTemplate("") + } + } + const handleCreateEvent = () => { - if (!newEventKey) { + if (newEventType === "builtin" && !newEventKey) { toast.error("请选择系统事件") return } + if (newEventType === "task" && !newEventTaskType) { + toast.error("请选择异步任务") + return + } if (newEventTemplate) { try { @@ -206,7 +237,8 @@ export function EventsTab() { .filter(t => t !== "") createEventMutation.mutate({ - event_key: newEventKey, + event_key: newEventType === "builtin" ? newEventKey : undefined, + task_type: newEventType === "task" ? newEventTaskType : undefined, channels: newEventChannels, targets: targets.length > 0 ? targets : undefined, template: newEventTemplate || undefined, @@ -253,7 +285,14 @@ export function EventsTab() { {event.id}
- {event.name} +
+ {event.name} + {event.task_type && ( + + 任务 + + )} +
{event.event_key}
@@ -353,33 +392,96 @@ export function EventsTab() {
- - {builtInEventsQuery.isLoading ? ( -
- - 加载系统事件中... -
- ) : availableBuiltInEvents.length === 0 ? ( -
- 所有内置事件都已配置,没有可新增的事件。 -
- ) : ( - - )} + +
+ + +
- {newEventKey && ( + {newEventType === "builtin" ? ( +
+ + {builtInEventsQuery.isLoading ? ( +
+ + 加载系统事件中... +
+ ) : availableBuiltInEvents.length === 0 ? ( +
+ 所有内置事件都已配置,没有可新增的事件。 +
+ ) : ( + + )} +
+ ) : ( +
+ + {taskTypesQuery.isLoading ? ( +
+ + 加载异步任务中... +
+ ) : (taskTypesQuery.data ?? []).length === 0 ? ( +
+ 暂无可用的系统任务。 +
+ ) : ( + + )} +
+ )} + + {newEventType === "builtin" && newEventKey && (
事件说明: @@ -388,6 +490,15 @@ export function EventsTab() {
)} + {newEventType === "task" && newEventTaskType && ( +
+ 任务说明: + + {(taskTypesQuery.data ?? []).find(t => t.asynq_task === newEventTaskType)?.description || "无描述信息"} + +
+ )} +
@@ -419,7 +530,7 @@ export function EventsTab() { }} /> - {ch === "email" ? "邮件推送 (内置)" : ch} + {ch === "email" ? "邮件推送" : ch} ))} @@ -448,7 +559,9 @@ export function EventsTab() {
- 支持变量:{"{{user.username}}"}, {"{{ip}}"}, {"{{time}}"} + {newEventType === "task" + ? "支持变量:{{task_name}}, {{task_status}}, {{task_duration}}, {{user.username}}" + : "支持变量:{{user.username}}, {{ip}}, {{time}}"}