feat:增加历史消息模块

This commit is contained in:
2026-05-31 21:14:32 +08:00
parent 41ef49a04f
commit d47383cd95
9 changed files with 426 additions and 139 deletions

159
src/components/Agent.vue Normal file
View 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>