feat:增加历史消息模块
This commit is contained in:
159
src/components/Agent.vue
Normal file
159
src/components/Agent.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="agent-container">
|
||||
<!-- 聊天区域 -->
|
||||
<main class="chat-container">
|
||||
<div v-for="(item, index) in agentStore.chatMessages" :key="index" class="message" :class="item.role">
|
||||
<!-- 用户 -->
|
||||
<div v-if="item.role === 'user'" class="bubble">
|
||||
{{ item.content }}
|
||||
</div>
|
||||
|
||||
<!-- AI -->
|
||||
<MdPreview v-else :modelValue="item.content" class="md"/>
|
||||
</div>
|
||||
|
||||
<div v-if="agentStore.loading" class="loading">
|
||||
<el-icon class="is-loading"><Loading /></el-icon>
|
||||
思考中…
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- 输入区 -->
|
||||
<footer class="input-container">
|
||||
<el-input v-model="agentStore.input" placeholder="请输入你的食材" @keyup.enter="sendMessage" clearable/>
|
||||
<el-button type="primary" :loading="agentStore.loading" @click="sendMessage">发送</el-button>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from "vue";
|
||||
import { Loading } from "@element-plus/icons-vue";
|
||||
import { MdPreview } from 'md-editor-v3';
|
||||
import 'md-editor-v3/lib/preview.css';
|
||||
import { useAgentStore } from "../stores/agent.ts";
|
||||
|
||||
const agentStore = useAgentStore();
|
||||
|
||||
onMounted(() => {
|
||||
getSessionMessage()
|
||||
})
|
||||
|
||||
const getSessionMessage = async () => {
|
||||
const response = await fetch(
|
||||
"/chief-agent-api/chat/messages/session?username=Cxx0822",
|
||||
{
|
||||
method: "GET",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
agentStore.sessionMessages = await response.json();
|
||||
agentStore.threadId = crypto.randomUUID()
|
||||
}
|
||||
|
||||
const sendMessage = async () => {
|
||||
if (!agentStore.input.trim()) return;
|
||||
|
||||
const userMsg = agentStore.input;
|
||||
agentStore.input = "";
|
||||
|
||||
agentStore.chatMessages.push({ role: "user", content: userMsg });
|
||||
agentStore.loading = true;
|
||||
|
||||
try {
|
||||
agentStore.agentMessage = {
|
||||
username: 'Cxx0822',
|
||||
message: userMsg,
|
||||
thread_id: agentStore.threadId,
|
||||
}
|
||||
const response = await fetch(
|
||||
"/chief-agent-api/chat/stream",
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(agentStore.agentMessage)
|
||||
}
|
||||
);
|
||||
|
||||
agentStore.chatMessages.push({ role: "ai", content: "" });
|
||||
const reader = response.body!.getReader();
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
let aiText = "";
|
||||
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
aiText += decoder.decode(value, { stream: true });
|
||||
agentStore.chatMessages[agentStore.chatMessages.length - 1].content = aiText;
|
||||
}
|
||||
} finally {
|
||||
agentStore.loading = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.agent-container {
|
||||
height: 100%;
|
||||
background-color: whitesmoke;
|
||||
border-radius: 10px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 5px;
|
||||
|
||||
.chat-container {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
|
||||
.message {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.user {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ai {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border-radius: 14px;
|
||||
max-width: 85%;
|
||||
word-break: break-word;
|
||||
line-height: 1.6;
|
||||
background: #409eff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.md {
|
||||
background: #f0f2f5;
|
||||
border-radius: 14px;
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-container {
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user