diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx index 6665f882b..947226b7a 100644 --- a/app/(admin)/settings/admin-settings-client.tsx +++ b/app/(admin)/settings/admin-settings-client.tsx @@ -104,6 +104,7 @@ function createEmptyCanvasSkillTag(): CanvasSkillTag { id: `tag-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, name: "", prompt: "", + iconUrl: "", }; } @@ -998,6 +999,7 @@ export function AdminSettingsClient() { const [canvasSkillTags, setCanvasSkillTags] = useState( DEFAULT_CANVAS_SKILL_TAGS ); + const [canvasSkillTagUploadingId, setCanvasSkillTagUploadingId] = useState(null); const { data: canvasSkillTagsData, mutate: mutateCanvasSkillTags } = useSWR<{ tags?: CanvasSkillTag[]; }>("/api/canvas-skill-tags", fetcher); @@ -1079,7 +1081,7 @@ export function AdminSettingsClient() { const handleCanvasSkillTagChange = ( index: number, - field: "name" | "prompt", + field: "name" | "prompt" | "iconUrl", value: string ) => { setCanvasSkillTags((prev) => @@ -1089,6 +1091,43 @@ export function AdminSettingsClient() { ); }; + const handleCanvasSkillTagIconUpload = async (index: number, file: File) => { + if (!file.type.startsWith("image/")) { + toast.error("请上传图片文件"); + return; + } + + const targetTag = canvasSkillTags[index]; + if (!targetTag) return; + + try { + setCanvasSkillTagUploadingId(targetTag.id); + const formData = new FormData(); + formData.append("file", file); + + const response = await fetch("/api/files/upload", { + method: "POST", + body: formData, + }); + const result = await response.json(); + + if (!response.ok || !result?.url) { + throw new Error(result?.error || "上传失败"); + } + + setCanvasSkillTags((prev) => + prev.map((tag, tagIndex) => + tagIndex === index ? { ...tag, iconUrl: result.url } : tag + ) + ); + toast.success("标签图标上传成功"); + } catch (error: any) { + toast.error(error?.message || "标签图标上传失败"); + } finally { + setCanvasSkillTagUploadingId(null); + } + }; + const handleAddCanvasSkillTag = () => { setCanvasSkillTags((prev) => [...prev, createEmptyCanvasSkillTag()]); }; @@ -5698,7 +5737,7 @@ export function AdminSettingsClient() { 画布对话快捷标签 - 每个标签包含「标签名 + 预设提示词」。用户点击标签后,发送消息时会自动附带对应提示词。 + 每个标签支持「图标 + 标签名 + 预设提示词」。用户点击标签后,发送消息时会自动附带对应提示词。 @@ -5721,6 +5760,53 @@ export function AdminSettingsClient() { +
+
+ {tag.iconUrl ? ( + {tag.name + ) : ( + + )} +
+
+ + handleCanvasSkillTagChange(index, "iconUrl", event.target.value) + } + placeholder="图标 URL(可选)" + /> + + { + const file = event.target.files?.[0]; + if (file) { + void handleCanvasSkillTagIconUpload(index, file); + } + event.currentTarget.value = ""; + }} + /> +
+