实现流程:
1.用户点击按钮从右侧展开抽屉(drawer),打开模拟对话框
2.用户输入问题,点击提问按钮,创建一个SSE实例请求后端数据,由于SSE是单向流,所以每提一个问题都需要先把之前的实例关掉,然后重新new个SSE实例
3.在SSE的onmessage里监听返回的数据流,并拼接到前端对话框中(后端返回的是markdown语法的流,这里全局引入了marked.js插件用来解析markdown),我这里接的是deepseek,所以返回的数据流里会有推理信息,不过后端可以控制不返回推理信息,只返回结果
4.可以加一些细节处理,提升用户体验,比如:保存最近十条的聊天记录(这里存到了localStorage里),允许用户主动停止正在生成的内容,每次读取流时页面需要滚动到底部等
完整代码如下:
<template>
<div>
<!-- AI对话框 -->
<a-drawer
class="ai-drawer"
v-model:visible="status.showAI"
placement="right"
width="40%"
>
<!-- 聊天面板 -->
<div ref="chatPanelRef" class="chat-panel">
<div v-for="(item, index) in status.chatRecords" :key="index" class="chat-item">
<template v-if="item.user==='AI'">
<div class="avatar">
<img src="@/assets/img/home/AI.svg" alt="智能问答" />
</div>
<div class="cont">
<div class="answer-cont">
<template v-if="item.content.length <= 0">
<loading-outlined />
</template>
<template v-else>
<div v-html="item.content" class="answer-box"></div>
</template>
</div>
</div>
</template>
<template v-else>
<div class="cont user">
<div class="answer-cont">
<div v-html="item.content" class=""></div>
</div>
</div>
<div class="avatar user">
<img src="@/assets/default-user.png" alt="用户" />
</div>
</template>
</div>
</div>
<!-- 输入面板 -->
<div class="inp-panel">
<div class="flex">
<a-textarea
v-model:value="status.question"
:auto-size="{ minRows: 4, maxRows: 4 }"
placeholder="说点什么吧...(shift + enter换行)"
/>
<a-button type="primary" size="large" :title="status.isAsking ? '停止回答' : '提问'" class="search-btn" @click="onQuestion">
<template #icon>
<send-outlined v-if="!status.isAsking" />
<pause-circle-outlined v-else/>
</template>
</a-button>
</div>
</div>
</a-dra

最低0.47元/天 解锁文章
1822

被折叠的 条评论
为什么被折叠?



