mirror of
https://gitee.com/JavaLionLi/plus-ui.git
synced 2026-09-13 15:53:42 +08:00
117 lines
2.9 KiB
Vue
117 lines
2.9 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, ref } from 'vue';
|
|
import { fetchAgentConversations, fetchMyAgents, registerCurrentSnailUser } from '@/api/ai/agent';
|
|
import type { AgentItem, ConversationSummaryItem } from '@/api/ai/agent/types';
|
|
import ChatMain from './modules/chat-main.vue';
|
|
import ChatSidebar from './modules/chat-sidebar.vue';
|
|
|
|
defineOptions({ name: 'AiChatPage' });
|
|
|
|
const agents = ref<AgentItem[]>([]);
|
|
const conversations = ref<ConversationSummaryItem[]>([]);
|
|
const currentAgent = ref<AgentItem | null>(null);
|
|
const currentConversationId = ref('');
|
|
const currentNickname = ref('');
|
|
|
|
async function loadAgents() {
|
|
const { data: user } = await registerCurrentSnailUser();
|
|
currentNickname.value = user?.nickname || '';
|
|
const { data } = await fetchMyAgents();
|
|
agents.value = Array.isArray(data) ? data : [];
|
|
currentAgent.value = agents.value[0] || null;
|
|
}
|
|
|
|
async function loadConversations(agentId: number) {
|
|
try {
|
|
const { data } = await fetchAgentConversations(agentId, { page: 1, size: 50 });
|
|
const list = Array.isArray(data?.data) ? data.data : [];
|
|
conversations.value = list;
|
|
} catch {
|
|
conversations.value = [];
|
|
}
|
|
}
|
|
|
|
async function onSelectAgent(agent: AgentItem) {
|
|
currentAgent.value = agent;
|
|
currentConversationId.value = '';
|
|
await loadConversations(agent.id);
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadAgents().then(async () => {
|
|
if (currentAgent.value) {
|
|
await loadConversations(currentAgent.value.id);
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="ai-chat-page">
|
|
<header class="chat-header">
|
|
<div class="brand">
|
|
<div class="brand-dot" />
|
|
<span>Snail AI</span>
|
|
</div>
|
|
</header>
|
|
<div class="chat-body">
|
|
<ChatSidebar
|
|
:agents="agents"
|
|
:conversations="conversations"
|
|
:current-agent="currentAgent"
|
|
:current-conversation-id="currentConversationId"
|
|
:current-nickname="currentNickname"
|
|
@select-agent="onSelectAgent"
|
|
@select-conversation="currentConversationId = $event"
|
|
@new-chat="currentConversationId = ''"
|
|
/>
|
|
<ChatMain
|
|
:agent="currentAgent"
|
|
:conversation-id="currentConversationId"
|
|
@conversation-created="(id) => { currentConversationId = id; if (currentAgent) loadConversations(currentAgent.id); }"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.ai-chat-page {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
min-height: calc(100vh - 84px);
|
|
background: #f5f6f8;
|
|
}
|
|
|
|
.chat-header {
|
|
height: 46px;
|
|
padding: 0 14px;
|
|
border-bottom: 1px solid #e6e8ee;
|
|
background: #fff;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.brand {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
color: #8b90a0;
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.brand-dot {
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 50%;
|
|
background: #6f76ff;
|
|
}
|
|
|
|
.chat-body {
|
|
flex: 1;
|
|
display: flex;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|