feat: 任务模板支持预设分类与任务级拦截/允许规则

- db: task_templates 加 category_id(FK task_categories, ON DELETE SET NULL)
  与 intercept_rules JSONB(规则快照);带幂等 ALTER 补旧库。
- db/task_templates.go: 用 JSONB 存取规则;PATCH 用 Set 标志区分改/清。
- server: 模板请求体加 category_id + intercept_rules,复用 buildTaskInterceptRules
  校验;PATCH 靠原始 key presence 判断是否更新(可清分类为 null)。
- web: 抽共享组件 asset-intercept-rules-editor(NativeSelect 版,避免 Sheet 内
  下拉 portal 误关抽屉),创建表单与模板管理器共用;模板管理器新增分类下拉与
  规则编辑区,另存为模板带当前分类/规则;应用模板回填分类与规则。
This commit is contained in:
Autumn-27 committed 2026-09-19 09:27:03 -04:00
1 parent d5359e1f04
commit 777730e255
8 files changed
+342 -143

No files matched your search

+7 -4
View File
@@ -276,10 +276,13 @@ export const api = {
category_id: categoryId ?? null,
}),
taskTemplates: () => get<{ templates: TaskTemplate[] }>("/task-templates").then((r) => arr(r.templates)),
createTaskTemplate: (input: Pick<TaskTemplate, "name" | "description" | "goal">) =>
post<TaskTemplate>("/task-templates", input),
updateTaskTemplate: (id: number, input: Partial<Pick<TaskTemplate, "name" | "description" | "goal">>) =>
patch<TaskTemplate>(`/task-templates/${id}`, input),
createTaskTemplate: (
input: Pick<TaskTemplate, "name" | "description" | "goal" | "category_id" | "intercept_rules">,
) => post<TaskTemplate>("/task-templates", input),
updateTaskTemplate: (
id: number,
input: Partial<Pick<TaskTemplate, "name" | "description" | "goal" | "category_id" | "intercept_rules">>,
) => patch<TaskTemplate>(`/task-templates/${id}`, input),
deleteTaskTemplate: (id: number) => del<{ deleted: number }>(`/task-templates/${id}`),
updateTaskLLMProfiles: (id: string, llmProfileIds: number[], activeLLMProfileId?: number) =>
put<{
+2
View File
@@ -53,6 +53,8 @@ export interface TaskTemplate {
name: string;
description: string;
goal: string;
category_id?: number | null; // 预设分类;null/缺省=无
intercept_rules?: AssetInterceptRuleInput[]; // 预设的任务级拦截/允许规则
created_at: string;
updated_at: string;
}