feat(ui): 优化智能体界面交互和样式
- 添加单例模式支持,区分独立页面和普通视图 - 重构智能体选择器为按钮样式并优化交互 - 更新侧边栏组件以支持不同模式下的显示 - 统一智能体名称显示为"智能体助手" - 调整按钮圆角样式提升视觉一致性
This commit is contained in:
parent
7f1b4f4a59
commit
68e7bd8300
@ -18,7 +18,7 @@ from src.agents.chatbot.configuration import ChatbotConfiguration
|
|||||||
from src.agents.tools_factory import get_runnable_tools
|
from src.agents.tools_factory import get_runnable_tools
|
||||||
|
|
||||||
class ChatbotAgent(BaseAgent):
|
class ChatbotAgent(BaseAgent):
|
||||||
name = "问答助手"
|
name = "智能体助手"
|
||||||
description = "基础的对话机器人,可以回答问题,默认不使用任何工具,可在配置中启用需要的工具。"
|
description = "基础的对话机器人,可以回答问题,默认不使用任何工具,可在配置中启用需要的工具。"
|
||||||
config_schema = ChatbotConfiguration
|
config_schema = ChatbotConfiguration
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chat-container" ref="chatContainerRef">
|
<div class="chat-container" ref="chatContainerRef">
|
||||||
<ChatSidebarComponent
|
<ChatSidebarComponent
|
||||||
:current-agent-id="props.agentId"
|
|
||||||
:current-chat-id="currentChatId"
|
:current-chat-id="currentChatId"
|
||||||
:chats-list="chatsList"
|
:chats-list="chatsList"
|
||||||
:is-sidebar-open="state.isSidebarOpen"
|
:is-sidebar-open="state.isSidebarOpen"
|
||||||
:is-initial-render="state.isInitialRender"
|
:is-initial-render="state.isInitialRender"
|
||||||
|
:single-mode="props.singleMode"
|
||||||
|
:agents="agents"
|
||||||
|
:selected-agent-id="props.agentId"
|
||||||
@create-chat="createNewChat"
|
@create-chat="createNewChat"
|
||||||
@select-chat="selectChat"
|
@select-chat="selectChat"
|
||||||
@delete-chat="deleteChat"
|
@delete-chat="deleteChat"
|
||||||
@rename-chat="renameChat"
|
@rename-chat="renameChat"
|
||||||
@toggle-sidebar="toggleSidebar"
|
@toggle-sidebar="toggleSidebar"
|
||||||
|
@open-agent-modal="openAgentModal"
|
||||||
:class="{
|
:class="{
|
||||||
'floating-sidebar': isSmallContainer,
|
'floating-sidebar': isSmallContainer,
|
||||||
'sidebar-open': state.isSidebarOpen,
|
'sidebar-open': state.isSidebarOpen,
|
||||||
@ -71,9 +74,6 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="chat-box" ref="messagesContainer">
|
<div class="chat-box" ref="messagesContainer">
|
||||||
<div class="conv-box" v-for="(conv, index) in convs" :key="index">
|
<div class="conv-box" v-for="(conv, index) in convs" :key="index">
|
||||||
<AgentMessageComponent
|
<AgentMessageComponent
|
||||||
@ -163,9 +163,15 @@ const props = defineProps({
|
|||||||
state: {
|
state: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
|
},
|
||||||
|
singleMode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['open-config', 'open-agent-modal']);
|
||||||
|
|
||||||
// ==================== 状态管理 ====================
|
// ==================== 状态管理 ====================
|
||||||
|
|
||||||
// UI状态
|
// UI状态
|
||||||
@ -417,9 +423,9 @@ const handleRenameChat = () => {
|
|||||||
message.warning('请先选择对话');
|
message.warning('请先选择对话');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newTitle = currentChat.value.title;
|
let newTitle = currentChat.value.title;
|
||||||
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '重命名对话',
|
title: '重命名对话',
|
||||||
content: h('div', { style: { marginTop: '12px' } }, [
|
content: h('div', { style: { marginTop: '12px' } }, [
|
||||||
@ -1286,6 +1292,11 @@ const toggleSidebar = () => {
|
|||||||
console.log("toggleSidebar", state.isSidebarOpen);
|
console.log("toggleSidebar", state.isSidebarOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const openAgentModal = () => {
|
||||||
|
// 发送事件给父组件,让父组件处理打开智能体选择弹窗的逻辑
|
||||||
|
emit('open-agent-modal');
|
||||||
|
}
|
||||||
|
|
||||||
// 处理键盘事件
|
// 处理键盘事件
|
||||||
const handleKeyDown = (e) => {
|
const handleKeyDown = (e) => {
|
||||||
if (e.key === 'Enter' && !e.shiftKey) {
|
if (e.key === 'Enter' && !e.shiftKey) {
|
||||||
@ -1444,14 +1455,14 @@ const mergeMessageChunk = (chunks) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
.center-title {
|
.center-title {
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rename-button {
|
.rename-button {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -1462,11 +1473,11 @@ const mergeMessageChunk = (chunks) => {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--gray-100);
|
background-color: var(--gray-100);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chat-sidebar" :class="{'sidebar-open': isSidebarOpen, 'no-transition': isInitialRender}">
|
<div class="chat-sidebar" :class="{'sidebar-open': isSidebarOpen, 'no-transition': isInitialRender}">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<div class="header-title">{{ currentAgentId }}</div>
|
<div class="header-title" v-if="singleMode">{{ selectedAgentName }}</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="agent-selector"
|
||||||
|
@click="openAgentModal"
|
||||||
|
> {{ selectedAgentName || '选择智能体' }}</div>
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<div class="toggle-sidebar nav-btn" v-if="isSidebarOpen" @click="toggleCollapse">
|
<div class="toggle-sidebar nav-btn" v-if="isSidebarOpen" @click="toggleCollapse">
|
||||||
<PanelLeftClose size="20" color="var(--gray-800)"/>
|
<PanelLeftClose size="20" color="var(--gray-800)"/>
|
||||||
@ -90,13 +95,32 @@ const props = defineProps({
|
|||||||
isInitialRender: {
|
isInitialRender: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
singleMode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
agents: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
selectedAgentId: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['create-chat', 'select-chat', 'delete-chat', 'rename-chat', 'toggle-sidebar']);
|
const emit = defineEmits(['create-chat', 'select-chat', 'delete-chat', 'rename-chat', 'toggle-sidebar', 'open-agent-modal']);
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const selectedAgentName = computed(() => {
|
||||||
|
if (props.selectedAgentId && props.agents && props.agents[props.selectedAgentId]) {
|
||||||
|
return props.agents[props.selectedAgentId].name;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
const groupedChats = computed(() => {
|
const groupedChats = computed(() => {
|
||||||
const groups = {
|
const groups = {
|
||||||
'今天': [],
|
'今天': [],
|
||||||
@ -187,6 +211,10 @@ const renameChat = async (chatId) => {
|
|||||||
const toggleCollapse = () => {
|
const toggleCollapse = () => {
|
||||||
emit('toggle-sidebar');
|
emit('toggle-sidebar');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openAgentModal = () => {
|
||||||
|
emit('open-agent-modal');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@ -394,4 +422,16 @@ const toggleCollapse = () => {
|
|||||||
background-color: var(--gray-100);
|
background-color: var(--gray-100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 智能体选择器样式
|
||||||
|
.agent-selector {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--gray-900);
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--main-500);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="agent-single-view">
|
<div class="agent-single-view">
|
||||||
<!-- 智能体聊天界面 -->
|
<!-- 智能体聊天界面 -->
|
||||||
<AgentChatComponent :agent-id="agentId">
|
<AgentChatComponent :agent-id="agentId" :single-mode="true">
|
||||||
<template #header-right>
|
<template #header-right>
|
||||||
<UserInfoComponent />
|
<UserInfoComponent />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -3,15 +3,9 @@
|
|||||||
<div class="agent-view-header">
|
<div class="agent-view-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<div class="header-item">
|
<div class="header-item">
|
||||||
<div
|
<a-button class="header-button" @click="openAgentModal">
|
||||||
class="agent-selector"
|
选择:{{ selectedAgent.name || '选择智能体' }}
|
||||||
@click="openAgentModal"
|
</a-button>
|
||||||
style="width: 220px; cursor: pointer;"
|
|
||||||
>
|
|
||||||
<div class="selected-agent-display">
|
|
||||||
<span class="agent-name">{{ selectedAgent.name || '选择智能体' }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-center">
|
<div class="header-center">
|
||||||
@ -27,9 +21,10 @@
|
|||||||
v-if="selectedAgentId"
|
v-if="selectedAgentId"
|
||||||
>
|
>
|
||||||
<template #icon><LinkOutlined /></template>
|
<template #icon><LinkOutlined /></template>
|
||||||
打开独立页面
|
独立页面
|
||||||
</a-button>
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="header-item">
|
||||||
<a-tooltip :title="isDefaultAgent ? '当前为默认智能体' : '设为默认智能体'" placement="left">
|
<a-tooltip :title="isDefaultAgent ? '当前为默认智能体' : '设为默认智能体'" placement="left">
|
||||||
<a-button
|
<a-button
|
||||||
class="header-button primary-action"
|
class="header-button primary-action"
|
||||||
@ -291,7 +286,9 @@
|
|||||||
:agent-id="selectedAgentId"
|
:agent-id="selectedAgentId"
|
||||||
:config="agentConfig"
|
:config="agentConfig"
|
||||||
:state="state"
|
:state="state"
|
||||||
|
:single-mode="false"
|
||||||
@open-config="toggleConf"
|
@open-config="toggleConf"
|
||||||
|
@open-agent-modal="openAgentModal"
|
||||||
>
|
>
|
||||||
</AgentChatComponent>
|
</AgentChatComponent>
|
||||||
</div>
|
</div>
|
||||||
@ -743,6 +740,10 @@ const toggleConf = () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user