From 8627188ee7f4eab6e26edba550043bece0960938 Mon Sep 17 00:00:00 2001 From: john Date: Fri, 26 Jun 2026 19:44:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20DesignSkillPanel=20=E2=80=94=20awesome-?= =?UTF-8?q?design-md=20=E5=89=8D=E5=8F=B0=20UI=20=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 DesignSkillPanel 组件:54 品牌风格选择网格 + 任务描述输入 - ChatPanel 工具栏增加 design 按钮,点击弹出面板 - 生成结果回填到输入框,用户可编辑后发送 - 新增 API:listDesignStyles / invokeDesignSkill(走 /admin-api/skills/) - .env.local: H5_DEV_ADMIN=http://127.0.0.1:8085(对接本地 memindadm) Co-Authored-By: Claude Sonnet 4.6 --- src/api/client.ts | 17 +++ src/components/ChatPanel.tsx | 32 +++++ src/components/DesignSkillPanel.tsx | 171 ++++++++++++++++++++++++++ src/index.css | 183 ++++++++++++++++++++++++++++ 4 files changed, 403 insertions(+) create mode 100644 src/components/DesignSkillPanel.tsx diff --git a/src/api/client.ts b/src/api/client.ts index 9c0f672..70ad5ec 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -2147,3 +2147,20 @@ export function subscribeSessionEvents( } }; } + +// ── Design Skill API ───────────────────────────────────────────────────────── + +export async function listDesignStyles(): Promise { + const result = await portalFetch<{ designs: string[] }>('/admin-api/skills/designs'); + return result.designs ?? []; +} + +export async function invokeDesignSkill( + design: string, + task: string, +): Promise<{ invocation_id: number; output: string }> { + return portalFetch('/admin-api/skills/awesome-design-md/invoke', { + method: 'POST', + body: JSON.stringify({ design, task }), + }); +} diff --git a/src/components/ChatPanel.tsx b/src/components/ChatPanel.tsx index b77fbd8..25fa6c6 100644 --- a/src/components/ChatPanel.tsx +++ b/src/components/ChatPanel.tsx @@ -4,6 +4,7 @@ import { openAvatarPicker } from '../utils/userAvatar'; import { CHAT_SKILL_OPTIONS, filterChatSkills } from '../utils/chatSkills'; import { AvatarPicker } from './AvatarPicker'; import { ChatSkillPicker } from './ChatSkillPicker'; +import { DesignSkillPanel } from './DesignSkillPanel'; import { MessageList } from './MessageList'; import { PageSaveDialog } from './PageSaveDialog'; import { VoiceInputButton } from './VoiceInputButton'; @@ -67,6 +68,7 @@ export function ChatPanel({ }) { const online = useNetworkStatus(); const [input, setInput] = useState(''); + const [designPanelOpen, setDesignPanelOpen] = useState(false); const [voiceRecording, setVoiceRecording] = useState(false); const [pageSource, setPageSource] = useState(null); const [voiceNotice, setVoiceNotice] = useState(null); @@ -455,6 +457,25 @@ export function ChatPanel({ onPrefill={setInput} /> )} + + {designPanelOpen && ( + setDesignPanelOpen(false)} + onResult={(md) => { + setInput(md); + setDesignPanelOpen(false); + }} + /> + )} {chatState === 'streaming' ? ( + + +
+

选择设计风格

+ {fetching ? ( +
加载中…
+ ) : ( +
+ {designs.map((d) => ( + + ))} +
+ )} + + {selected && ( + <> +

+ 描述 UI 任务 + — {formatBrandLabel(selected)} 风格 +

+