diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx index cf3497fea..d1d4d82d1 100644 --- a/app/(admin)/settings/admin-settings-client.tsx +++ b/app/(admin)/settings/admin-settings-client.tsx @@ -1002,11 +1002,13 @@ export function AdminSettingsClient() { // 快捷短语状态 const [questions, setQuestions] = useState([]); const { data: questionsData, mutate: mutateQuestions } = useSWR("/api/starter-questions", fetcher); + const [canvasSkillTagsEnabled, setCanvasSkillTagsEnabled] = useState(true); const [canvasSkillTags, setCanvasSkillTags] = useState( DEFAULT_CANVAS_SKILL_TAGS ); const [canvasSkillTagUploadingId, setCanvasSkillTagUploadingId] = useState(null); const { data: canvasSkillTagsData, mutate: mutateCanvasSkillTags } = useSWR<{ + enabled?: boolean; tags?: CanvasSkillTag[]; }>("/api/canvas-skill-tags", fetcher); @@ -1051,6 +1053,7 @@ export function AdminSettingsClient() { useEffect(() => { if (canvasSkillTagsData) { + setCanvasSkillTagsEnabled(canvasSkillTagsData.enabled !== false); setCanvasSkillTags(normalizeCanvasSkillTags(canvasSkillTagsData.tags)); } }, [canvasSkillTagsData]); @@ -1148,11 +1151,12 @@ export function AdminSettingsClient() { const res = await fetch("/api/canvas-skill-tags", { method: "PUT", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ tags: payload }), + body: JSON.stringify({ enabled: canvasSkillTagsEnabled, tags: payload }), }); if (!res.ok) throw new Error("Failed"); const data = await res.json().catch(() => ({})); + setCanvasSkillTagsEnabled(data?.enabled !== false); setCanvasSkillTags(normalizeCanvasSkillTags(data?.tags ?? payload)); toast.success("快捷标签已更新"); mutateCanvasSkillTags(); @@ -5747,6 +5751,18 @@ export function AdminSettingsClient() { +
+
+ +

+ 关闭后,对话框将不显示快捷标签区域。 +

+
+ +
{canvasSkillTags.map((tag, index) => { const TagIcon = getCanvasSkillIconComponent(tag.iconName); return ( diff --git a/app/api/canvas-skill-tags/route.ts b/app/api/canvas-skill-tags/route.ts index d34a0d186..c96ab1bb4 100644 --- a/app/api/canvas-skill-tags/route.ts +++ b/app/api/canvas-skill-tags/route.ts @@ -5,6 +5,7 @@ import { db } from "@/lib/db"; import { systemSettings } from "@/lib/db/schema"; import { CANVAS_SKILL_TAGS_SETTING_KEY, + normalizeCanvasSkillTagSettings, normalizeCanvasSkillTags, } from "@/lib/canvas-skill-tags"; @@ -16,14 +17,11 @@ export async function GET() { .where(eq(systemSettings.key, CANVAS_SKILL_TAGS_SETTING_KEY)) .limit(1); - return NextResponse.json({ - tags: normalizeCanvasSkillTags(setting?.value), - }); + const settings = normalizeCanvasSkillTagSettings(setting?.value); + return NextResponse.json(settings); } catch (error) { console.error("[CanvasSkillTags API] Get error:", error); - return NextResponse.json({ - tags: normalizeCanvasSkillTags(null), - }); + return NextResponse.json(normalizeCanvasSkillTagSettings(null)); } } @@ -37,6 +35,8 @@ export async function PUT(request: NextRequest) { const body = await request.json(); const rawTags = Array.isArray(body) ? body : body?.tags; const tags = normalizeCanvasSkillTags(rawTags); + const enabled = Array.isArray(body) ? true : body?.enabled !== false; + const nextValue = { enabled, tags }; const [existing] = await db .select() @@ -48,7 +48,7 @@ export async function PUT(request: NextRequest) { await db .update(systemSettings) .set({ - value: tags, + value: nextValue, updatedAt: new Date(), updatedBy: session.user.id, }) @@ -56,12 +56,12 @@ export async function PUT(request: NextRequest) { } else { await db.insert(systemSettings).values({ key: CANVAS_SKILL_TAGS_SETTING_KEY, - value: tags, + value: nextValue, updatedBy: session.user.id, }); } - return NextResponse.json({ success: true, tags }); + return NextResponse.json({ success: true, enabled, tags }); } catch (error) { console.error("[CanvasSkillTags API] Update error:", error); return NextResponse.json({ error: "Failed to update" }, { status: 500 }); diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index df1a52296..30739246c 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -2250,7 +2250,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF canvasAutoModeDefaultModelId?: string | null; canvasDetailDefaultModelId?: string | null; }>("/api/site-settings", fetcher); - const { data: canvasSkillTagsData } = useSWR<{ tags?: CanvasSkillTag[] }>( + const { data: canvasSkillTagsData } = useSWR<{ enabled?: boolean; tags?: CanvasSkillTag[] }>( "/api/canvas-skill-tags", fetcher ); @@ -2289,9 +2289,10 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF : "Hi, 我是你的AI设计师"; const totalGeneratedImages = Number(userImageStats?.totalImages ?? NaN); const aiDetailGenerationEnabled = siteSettings?.aiDetailGenerationEnabled === true; + const canvasSkillTagsEnabled = canvasSkillTagsData?.enabled !== false; const canvasSkillTags = useMemo( - () => normalizeCanvasSkillTags(canvasSkillTagsData?.tags), - [canvasSkillTagsData?.tags] + () => (canvasSkillTagsEnabled ? normalizeCanvasSkillTags(canvasSkillTagsData?.tags) : []), + [canvasSkillTagsData?.tags, canvasSkillTagsEnabled] ); const selectedSkillTag = useMemo( () => canvasSkillTags.find((tag) => tag.id === selectedSkillTagId) || null, diff --git a/lib/canvas-skill-tags.ts b/lib/canvas-skill-tags.ts index d23cc0146..73b8b8b60 100644 --- a/lib/canvas-skill-tags.ts +++ b/lib/canvas-skill-tags.ts @@ -1,5 +1,10 @@ export const CANVAS_SKILL_TAGS_SETTING_KEY = "canvas_skill_tags"; +export type CanvasSkillTagSettings = { + enabled: boolean; + tags: CanvasSkillTag[]; +}; + export type CanvasSkillTag = { id: string; name: string; @@ -108,3 +113,27 @@ export function normalizeCanvasSkillTags(value: unknown): CanvasSkillTag[] { return normalized.slice(0, 30); } + +export function normalizeCanvasSkillTagSettings( + value: unknown +): CanvasSkillTagSettings { + if (Array.isArray(value)) { + return { + enabled: true, + tags: normalizeCanvasSkillTags(value), + }; + } + + if (value && typeof value === "object") { + const row = value as Record; + return { + enabled: row.enabled !== false, + tags: normalizeCanvasSkillTags(row.tags), + }; + } + + return { + enabled: true, + tags: normalizeCanvasSkillTags(null), + }; +}