From 305dd21dd54a13ab5b8b133c6ed5bc7f6dad2239 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Apr 2026 09:35:34 +0800 Subject: [PATCH] feat: enhance psd template editor workflow --- .../agent-workflow-settings-client.tsx | 48 +++++ .../psd-templates-settings-client.tsx | 39 ++++ app/api/admin/psd-templates/[id]/route.ts | 3 + app/api/admin/psd-templates/route.ts | 6 + app/api/psd-templates/route.ts | 17 +- app/api/site-settings/route.ts | 54 +++++ .../agents/AgentPsdTemplateEditorDialog.tsx | 199 +++++++++++++----- lib/agents/psd-template-config.ts | 4 + lib/agents/psd-template-renderer.ts | 52 ++++- .../psd-template-secondary-category-config.ts | 23 ++ 10 files changed, 388 insertions(+), 57 deletions(-) create mode 100644 lib/agents/psd-template-secondary-category-config.ts diff --git a/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx b/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx index 2bd271fbc..09d1e7bee 100644 --- a/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx +++ b/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx @@ -67,6 +67,11 @@ import { defaultAgentPsdTextColorConfig, normalizeAgentPsdTextColorConfig, } from "@/lib/agents/psd-text-color-config"; +import { + defaultAgentPsdTemplateSecondaryCategoryConfig, + type AgentPsdTemplateSecondaryCategoryConfig, + normalizeAgentPsdTemplateSecondaryCategoryConfig, +} from "@/lib/agents/psd-template-secondary-category-config"; import { normalizeHexColor } from "@/lib/agents/psd-text-layout"; import { fetchUploadWithRetry } from "@/lib/client/upload-with-retry"; import { Button } from "@/components/ui/button"; @@ -474,6 +479,7 @@ export function AgentWorkflowSettingsClient({ agentWorkflowBrandModelConfig?: AgentWorkflowBrandModelConfig; agentWorkflowShowcaseConfig?: AgentWorkflowShowcaseConfig; agentPsdTextColorConfig?: AgentPsdTextColorConfig; + agentPsdTemplateSecondaryCategoryConfig?: AgentPsdTemplateSecondaryCategoryConfig; }>("/api/site-settings", fetcher); const [presetLibraryConfig, setPresetLibraryConfig] = useState( defaultAgentPresetLibraryConfig @@ -491,6 +497,10 @@ export function AgentWorkflowSettingsClient({ const [psdTextColorConfig, setPsdTextColorConfig] = useState( defaultAgentPsdTextColorConfig ); + const [psdTemplateSecondaryCategoryConfig, setPsdTemplateSecondaryCategoryConfig] = + useState( + defaultAgentPsdTemplateSecondaryCategoryConfig + ); const [brandModelConfig, setBrandModelConfig] = useState( defaultAgentWorkflowBrandModelConfig ); @@ -536,6 +546,11 @@ export function AgentWorkflowSettingsClient({ setPsdTextColorConfig( normalizeAgentPsdTextColorConfig(data.agentPsdTextColorConfig) ); + setPsdTemplateSecondaryCategoryConfig( + normalizeAgentPsdTemplateSecondaryCategoryConfig( + data.agentPsdTemplateSecondaryCategoryConfig + ) + ); setBrandModelConfig( normalizeAgentWorkflowBrandModelConfig(data.agentWorkflowBrandModelConfig) ); @@ -1062,6 +1077,7 @@ export function AgentWorkflowSettingsClient({ agentWorkflowBrandModelConfig: brandModelConfig, agentWorkflowShowcaseConfig: showcaseConfig, agentPsdTextColorConfig: psdTextColorConfig, + agentPsdTemplateSecondaryCategoryConfig: psdTemplateSecondaryCategoryConfig, }), }); @@ -2646,6 +2662,38 @@ export function AgentWorkflowSettingsClient({ + + +
+
+ +
+
+ PSD 模板二级分类 + + 控制前台“选择模板”下拉是否按二级分类分组展示。 + +
+
+
+ +
+
+
启用 PSD 模板二级分类
+
+ 开启后,用户前台会按模板配置里的二级分类分组显示;未填写分类的模板会归入“未分组”。 +
+
+ + setPsdTemplateSecondaryCategoryConfig({ enabled: checked }) + } + /> +
+
+
+
diff --git a/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx b/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx index 76e6c4d10..f5eb94279 100644 --- a/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx +++ b/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx @@ -163,6 +163,7 @@ export function PsdTemplatesSettingsClient({ const [layerKeyword, setLayerKeyword] = useState(""); const [uploadName, setUploadName] = useState(""); const [uploadBrandName, setUploadBrandName] = useState(""); + const [uploadSecondaryCategory, setUploadSecondaryCategory] = useState(""); const [uploadDescription, setUploadDescription] = useState(""); const [uploadFile, setUploadFile] = useState(null); const [fontUploadName, setFontUploadName] = useState(""); @@ -305,6 +306,7 @@ export function PsdTemplatesSettingsClient({ const formData = new FormData(); formData.set("name", uploadName.trim() || uploadFile.name.replace(/\.[^.]+$/, "")); formData.set("brandName", uploadBrandName.trim()); + formData.set("secondaryCategory", uploadSecondaryCategory.trim()); formData.set("description", uploadDescription.trim()); formData.set("status", "disabled"); formData.set("file", uploadFile); @@ -370,6 +372,7 @@ export function PsdTemplatesSettingsClient({ ); setUploadName(""); setUploadBrandName(""); + setUploadSecondaryCategory(""); setUploadDescription(""); setUploadFile(null); await mutate(); @@ -472,6 +475,7 @@ export function PsdTemplatesSettingsClient({ body: JSON.stringify({ name: draftTemplate.name, brandName: draftTemplate.brandName, + secondaryCategory: draftTemplate.secondaryCategory || "", description: draftTemplate.description || "", status: draftTemplate.status, layers: draftTemplate.layers, @@ -731,6 +735,18 @@ export function PsdTemplatesSettingsClient({ /> )}
+
+ + setUploadSecondaryCategory(event.target.value)} + placeholder="例如:凳子类 / 升降桌类" + /> +

+ 开启前台模板二级分类后,会按这里的分类分组展示模板。 +

+