From 15b001bab562c4cd505d0178fd1a3d6cb0e802e7 Mon Sep 17 00:00:00 2001 From: "feifei.xu" <307327147@qq.com> Date: Sun, 15 Mar 2026 11:54:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=9F=E8=83=BD1=20-=20=E6=96=B0?= =?UTF-8?q?=E5=BB=BA=E6=9C=BA=E5=99=A8=E4=BA=BA=20(v0.9.6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 CreateBotModal.vue 新建机器人模态框 - 实现12个预设头像选择 - 实现名称/显示名称/描述表单 - HomeView 添加「新建机器人」按钮 - Store 添加 createBot 方法 - Store 添加 fetchAgents 方法 - 表单验证和错误提示 --- .../src/components/chat/CreateBotModal.vue | 316 ++++++++++++++++++ frontend/src/stores/chat.ts | 74 +++- frontend/src/views/HomeView.vue | 48 ++- 3 files changed, 433 insertions(+), 5 deletions(-) create mode 100644 frontend/src/components/chat/CreateBotModal.vue diff --git a/frontend/src/components/chat/CreateBotModal.vue b/frontend/src/components/chat/CreateBotModal.vue new file mode 100644 index 0000000..aff3cb8 --- /dev/null +++ b/frontend/src/components/chat/CreateBotModal.vue @@ -0,0 +1,316 @@ + + + + + + + 新建机器人 + × + + + + + + 选择头像 + + + {{ avatar }} + + + + + + + 名称 * + + + + + + 显示名称 + + + + + + 描述 + + + + + + {{ error }} + + + + + + 取消 + + + {{ loading ? '创建中...' : '创建' }} + + + + + + + + diff --git a/frontend/src/stores/chat.ts b/frontend/src/stores/chat.ts index 312ef6e..48975d5 100644 --- a/frontend/src/stores/chat.ts +++ b/frontend/src/stores/chat.ts @@ -10,6 +10,19 @@ export interface Bot { avatar?: string description?: string status: string + agent_id?: string + is_system?: boolean + capabilities?: string[] + config?: Record +} + +export interface Agent { + id: string + name: string + display_name?: string + status: string + model?: string + capabilities?: string[] } export interface Message { @@ -190,6 +203,61 @@ export const useChatStore = defineStore('chat', () => { } } + // Agent actions + async function fetchAgents() { + try { + const response = await fetch('/api/agents/available') + return await response.json() + } catch (error) { + console.error('Fetch agents failed:', error) + throw error + } + } + + // Bot actions + async function createBot(data: { + name: string + display_name?: string + avatar?: string + description?: string + }) { + try { + const response = await botApi.create(data) + const newBot = response.data.bot + bots.value.push(newBot) + return { bot: newBot, token: response.data.token } + } catch (error) { + console.error('Create bot failed:', error) + throw error + } + } + + async function bindBotAgent(botId: string, agentId: string) { + try { + const response = await botApi.bind(botId, agentId) + const updatedBot = response.data.bot + // Update bot in list + const index = bots.value.findIndex(b => b.id === botId) + if (index !== -1) { + bots.value[index] = { ...bots.value[index], ...updatedBot } + } + return updatedBot + } catch (error) { + console.error('Bind bot agent failed:', error) + throw error + } + } + + async function deleteBot(botId: string) { + try { + await botApi.delete(botId) + bots.value = bots.value.filter(b => b.id !== botId) + } catch (error) { + console.error('Delete bot failed:', error) + throw error + } + } + return { socket, connected, @@ -202,11 +270,15 @@ export const useChatStore = defineStore('chat', () => { setupSocket, disconnectSocket, fetchBots, + fetchAgents, fetchSessions, + createBot, createSession, joinSession, leaveSession, sendMessage, - sendTyping + sendTyping, + bindBotAgent, + deleteBot } }) diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue index adc3e4c..1cbe993 100644 --- a/frontend/src/views/HomeView.vue +++ b/frontend/src/views/HomeView.vue @@ -1,13 +1,16 @@ @@ -31,9 +38,14 @@ function resumeChat(sessionId: string) { 🐕 智队中枢 - - {{ authStore.user?.nickname || authStore.user?.username }} - 退出 + + + + 新建机器人 + + + {{ authStore.user?.nickname || authStore.user?.username }} + 退出 + @@ -92,6 +104,12 @@ function resumeChat(sessionId: string) { + + @@ -120,6 +138,28 @@ function resumeChat(sessionId: string) { color: var(--primary-color); } +.user-actions { + display: flex; + align-items: center; + gap: var(--spacing-md); +} + +.new-bot-btn { + padding: var(--spacing-xs) var(--spacing-md); + background: var(--primary-color); + color: white; + border: none; + border-radius: var(--border-radius); + font-size: var(--font-size-sm); + font-weight: 500; + cursor: pointer; + transition: background 0.2s; +} + +.new-bot-btn:hover { + background: var(--primary-dark); +} + .user-info { display: flex; align-items: center;