feat: support custom canvas skill tag title
This commit is contained in:
parent
c01e0a0cb8
commit
26b5e55ee8
@ -91,6 +91,7 @@ import {
|
||||
} from "@/lib/payment/dulupay-config";
|
||||
import {
|
||||
DEFAULT_CANVAS_SKILL_TAGS,
|
||||
DEFAULT_CANVAS_SKILL_TAGS_TITLE,
|
||||
normalizeCanvasSkillTags,
|
||||
type CanvasSkillTag,
|
||||
} from "@/lib/canvas-skill-tags";
|
||||
@ -1002,6 +1003,9 @@ export function AdminSettingsClient() {
|
||||
// 快捷短语状态
|
||||
const [questions, setQuestions] = useState<string[]>([]);
|
||||
const { data: questionsData, mutate: mutateQuestions } = useSWR<string[]>("/api/starter-questions", fetcher);
|
||||
const [canvasSkillTagsTitle, setCanvasSkillTagsTitle] = useState(
|
||||
DEFAULT_CANVAS_SKILL_TAGS_TITLE
|
||||
);
|
||||
const [canvasSkillTagsEnabled, setCanvasSkillTagsEnabled] = useState(true);
|
||||
const [canvasSkillTags, setCanvasSkillTags] = useState<CanvasSkillTag[]>(
|
||||
DEFAULT_CANVAS_SKILL_TAGS
|
||||
@ -1009,6 +1013,7 @@ export function AdminSettingsClient() {
|
||||
const [canvasSkillTagUploadingId, setCanvasSkillTagUploadingId] = useState<string | null>(null);
|
||||
const { data: canvasSkillTagsData, mutate: mutateCanvasSkillTags } = useSWR<{
|
||||
enabled?: boolean;
|
||||
title?: string;
|
||||
tags?: CanvasSkillTag[];
|
||||
}>("/api/canvas-skill-tags", fetcher);
|
||||
|
||||
@ -1054,6 +1059,9 @@ export function AdminSettingsClient() {
|
||||
useEffect(() => {
|
||||
if (canvasSkillTagsData) {
|
||||
setCanvasSkillTagsEnabled(canvasSkillTagsData.enabled !== false);
|
||||
setCanvasSkillTagsTitle(
|
||||
String(canvasSkillTagsData.title || "").trim() || DEFAULT_CANVAS_SKILL_TAGS_TITLE
|
||||
);
|
||||
setCanvasSkillTags(normalizeCanvasSkillTags(canvasSkillTagsData.tags));
|
||||
}
|
||||
}, [canvasSkillTagsData]);
|
||||
@ -1151,12 +1159,20 @@ export function AdminSettingsClient() {
|
||||
const res = await fetch("/api/canvas-skill-tags", {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ enabled: canvasSkillTagsEnabled, tags: payload }),
|
||||
body: JSON.stringify({
|
||||
enabled: canvasSkillTagsEnabled,
|
||||
title: canvasSkillTagsTitle,
|
||||
tags: payload,
|
||||
}),
|
||||
});
|
||||
if (!res.ok) throw new Error("Failed");
|
||||
|
||||
const data = await res.json().catch(() => ({}));
|
||||
setCanvasSkillTagsEnabled(data?.enabled !== false);
|
||||
setCanvasSkillTagsTitle(
|
||||
String(data?.title || canvasSkillTagsTitle || "").trim() ||
|
||||
DEFAULT_CANVAS_SKILL_TAGS_TITLE
|
||||
);
|
||||
setCanvasSkillTags(normalizeCanvasSkillTags(data?.tags ?? payload));
|
||||
toast.success("快捷标签已更新");
|
||||
mutateCanvasSkillTags();
|
||||
@ -5763,6 +5779,14 @@ export function AdminSettingsClient() {
|
||||
onCheckedChange={setCanvasSkillTagsEnabled}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>标签区标题</Label>
|
||||
<Input
|
||||
value={canvasSkillTagsTitle}
|
||||
onChange={(event) => setCanvasSkillTagsTitle(event.target.value)}
|
||||
placeholder={DEFAULT_CANVAS_SKILL_TAGS_TITLE}
|
||||
/>
|
||||
</div>
|
||||
{canvasSkillTags.map((tag, index) => {
|
||||
const TagIcon = getCanvasSkillIconComponent(tag.iconName);
|
||||
return (
|
||||
|
||||
@ -6,7 +6,6 @@ import { systemSettings } from "@/lib/db/schema";
|
||||
import {
|
||||
CANVAS_SKILL_TAGS_SETTING_KEY,
|
||||
normalizeCanvasSkillTagSettings,
|
||||
normalizeCanvasSkillTags,
|
||||
} from "@/lib/canvas-skill-tags";
|
||||
|
||||
export async function GET() {
|
||||
@ -33,10 +32,11 @@ 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 normalized = normalizeCanvasSkillTagSettings(body);
|
||||
const enabled = normalized.enabled;
|
||||
const title = normalized.title;
|
||||
const tags = normalized.tags;
|
||||
const nextValue = { enabled, title, tags };
|
||||
|
||||
const [existing] = await db
|
||||
.select()
|
||||
@ -61,7 +61,7 @@ export async function PUT(request: NextRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true, enabled, tags });
|
||||
return NextResponse.json({ success: true, enabled, title, tags });
|
||||
} catch (error) {
|
||||
console.error("[CanvasSkillTags API] Update error:", error);
|
||||
return NextResponse.json({ error: "Failed to update" }, { status: 500 });
|
||||
|
||||
@ -48,7 +48,11 @@ import {
|
||||
import { buildImageProxyUrl } from "@/lib/image-delivery";
|
||||
import type { Attachment, ChatMessage } from "@/lib/types";
|
||||
import { type CanvasLaunchPayload, getCanvasLaunchStorageKey } from "@/lib/canvas-launch";
|
||||
import { normalizeCanvasSkillTags, type CanvasSkillTag } from "@/lib/canvas-skill-tags";
|
||||
import {
|
||||
DEFAULT_CANVAS_SKILL_TAGS_TITLE,
|
||||
normalizeCanvasSkillTags,
|
||||
type CanvasSkillTag,
|
||||
} from "@/lib/canvas-skill-tags";
|
||||
import { getCanvasSkillIconComponent } from "@/components/canvas/canvas-skill-icons";
|
||||
import { ImageParamsBar, type ImageGenerationParams } from "@/components/image-params-bar";
|
||||
import { VideoParamsBar, type VideoGenerationParams } from "@/components/video-params-bar";
|
||||
@ -2250,7 +2254,11 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
canvasAutoModeDefaultModelId?: string | null;
|
||||
canvasDetailDefaultModelId?: string | null;
|
||||
}>("/api/site-settings", fetcher);
|
||||
const { data: canvasSkillTagsData } = useSWR<{ enabled?: boolean; tags?: CanvasSkillTag[] }>(
|
||||
const { data: canvasSkillTagsData } = useSWR<{
|
||||
enabled?: boolean;
|
||||
title?: string;
|
||||
tags?: CanvasSkillTag[];
|
||||
}>(
|
||||
"/api/canvas-skill-tags",
|
||||
fetcher
|
||||
);
|
||||
@ -2287,6 +2295,8 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
const totalGeneratedImages = Number(userImageStats?.totalImages ?? NaN);
|
||||
const aiDetailGenerationEnabled = siteSettings?.aiDetailGenerationEnabled === true;
|
||||
const canvasSkillTagsEnabled = canvasSkillTagsData?.enabled !== false;
|
||||
const canvasSkillTagsTitle =
|
||||
String(canvasSkillTagsData?.title || "").trim() || DEFAULT_CANVAS_SKILL_TAGS_TITLE;
|
||||
const canvasSkillTags = useMemo(
|
||||
() => (canvasSkillTagsEnabled ? normalizeCanvasSkillTags(canvasSkillTagsData?.tags) : []),
|
||||
[canvasSkillTagsData?.tags, canvasSkillTagsEnabled]
|
||||
@ -6362,7 +6372,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
{canvasSkillTags.length > 0 && (
|
||||
<div className="mb-8 rounded-3xl border border-[#eceef2] bg-white/90 p-4">
|
||||
<div className="mb-3 text-center">
|
||||
<h3 className="text-[16px] font-semibold text-[#1f2937]">试试这些 Skills</h3>
|
||||
<h3 className="text-[16px] font-semibold text-[#1f2937]">{canvasSkillTagsTitle}</h3>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
{canvasSkillTags.map((tag) => {
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
export const CANVAS_SKILL_TAGS_SETTING_KEY = "canvas_skill_tags";
|
||||
export const DEFAULT_CANVAS_SKILL_TAGS_TITLE = "试试这些 Skills";
|
||||
|
||||
export type CanvasSkillTagSettings = {
|
||||
enabled: boolean;
|
||||
title: string;
|
||||
tags: CanvasSkillTag[];
|
||||
};
|
||||
|
||||
@ -120,20 +122,24 @@ export function normalizeCanvasSkillTagSettings(
|
||||
if (Array.isArray(value)) {
|
||||
return {
|
||||
enabled: true,
|
||||
title: DEFAULT_CANVAS_SKILL_TAGS_TITLE,
|
||||
tags: normalizeCanvasSkillTags(value),
|
||||
};
|
||||
}
|
||||
|
||||
if (value && typeof value === "object") {
|
||||
const row = value as Record<string, unknown>;
|
||||
const title = normalizeString(row.title) || DEFAULT_CANVAS_SKILL_TAGS_TITLE;
|
||||
return {
|
||||
enabled: row.enabled !== false,
|
||||
title,
|
||||
tags: normalizeCanvasSkillTags(row.tags),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: true,
|
||||
title: DEFAULT_CANVAS_SKILL_TAGS_TITLE,
|
||||
tags: normalizeCanvasSkillTags(null),
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user