0


7. 综合演练聊天面板前端实现-SpringAI实战

前端实现

在学习了之前的SpringAI基础功能SSE流、内存历史消息基础上,整合前端界面和数据库版本的历史消息。
聊天面板

前端的聊天面板组件是以

  1. chat-view.vue

为核心,聊天面板的结构如下

  • 聊天面板 - 会话面板(左) - 标题(上)- 会话列表(中),进入页面的时候获取用户的会话列表使用session-item组件,该组件有删除按钮点击触发handleDeleteSession- 创建会话按钮(下), 触发点击事件调用handleCreateSession- 消息面板(右) - 会话详情(上),可编辑会话名称调用handleUpdateSession- 消息列表(中),for循环遍历activeSession当前会话中的消息使用message-row组件展示文本消息、图片消息、语音消息- 输入框使用(下),message-input组件

会话列表

会话列表

for循环遍历会话列表用会话组件显示,并监听点击事件和删除事件。点击时切换到被点击的会话,删除时从会话列表中提出被删除的会话。

  1. <!-- 左侧的会话列表 --><divclass="session-panel"><divclass="title">AI助手</div><divclass="session-list"v-if="activeSession"><!-- 遍历会话列表 --><session-itemv-for="session in sessionList":key="session.id":active="session.id === activeSession.id":session="session"class="session"@click="activeSession = session"@delete="handleDeleteSession"></session-item></div><divclass="button-wrapper"><el-buttonstyle="margin-right: 20px":icon="ChatRound"size="small"@click="handleSessionCreate">创建会话</el-button></div></div>

会话的创建、删除、加载逻辑。

  1. const activeSession =ref<AiSession>()const sessionList =ref<AiSession[]>([])consthandleCreateSession=async(session: AiSessionInput)=>{const res =await api.aiSessionController.save({ body: session })const sessionRes =await api.aiSessionController.findById({ id: res })
  2. sessionList.value.unshift(sessionRes)
  3. activeSession.value = sessionList.value[0]}// 从会话列表中删除会话consthandleDeleteSession=async(session: AiSession)=>{await api.aiSessionController.delete({ body:[session.id]})const index = sessionList.value.findIndex((value)=>{return value.id === session.id
  4. })
  5. sessionList.value.splice(index,1)if(index == sessionList.value.length){
  6. activeSession.value = sessionList.value[index -1]}else{
  7. activeSession.value = sessionList.value[index]}}onMounted(async()=>{// 查询自己的聊天会话
  8. api.aiSessionController.findByUser().then((res)=>{// 讲会话添加到列表中
  9. sessionList.value = res.map((row)=>{return{...row, checked:false}})// 默认选中的聊天会话是第一个if(sessionList.value.length >0){
  10. activeSession.value = sessionList.value[0]}else{handleSessionCreate()}
  11. loading.value =false})})

消息发送和展示

消息列表和消息发送

  1. <!-- 监听发送事件 --><message-input@send="handleSendMessage"v-if="activeSession"></message-input>

用户发送的逻辑,使用

  1. sse.js

发送消息,并监听sse消息。

  1. consthandleSendMessage=async(message:{ text:string; image:string})=>{if(!activeSession.value){
  2. ElMessage.warning('请创建会话')return}// 图片/语音const medias: AiMessage['medias']=[]if(message.image){
  3. medias.push({ type:'image', data: message.image })}// 用户的提问const chatMessage ={
  4. id:newDate().getTime().toString(),
  5. sessionId: activeSession.value.id,
  6. medias,
  7. textContent: message.text,
  8. type:'USER'} satisfies AiMessage
  9. // 新建一个ChatGPT回复对象,不能重复使用同一个对象。
  10. responseMessage.value ={
  11. id:newDate().getTime().toString(),
  12. type:'ASSISTANT',
  13. textContent:'',
  14. sessionId: activeSession.value.id
  15. }const evtSource =newSSE(import.meta.env.VITE_API_PREFIX+'/message/chat',{
  16. withCredentials:true,// 禁用自动启动,需要调用stream()方法才能发起请求
  17. start:false,
  18. headers:{'Content-Type':'application/json'},
  19. payload:JSON.stringify(chatMessage),
  20. method:'POST'})
  21. evtSource.addEventListener('message',async(event:any)=>{
  22. responseMessage.value.textContent = event.data
  23. // 非通义千问使用下面的消息拼接逻辑// responseMessage.value.textContent += event.data})// 调用stream,发起请求。
  24. evtSource.stream()// 将两条消息显示在页面中
  25. activeSession.value.messages.push(...[chatMessage, responseMessage.value])awaitnextTick(()=>{
  26. messageListRef.value?.scrollTo(0, messageListRef.value.scrollHeight)})}

遍历会话中的消息并展示

  1. <divref="messageListRef"class="message-list"><!-- 过渡效果 --><transition-groupname="list"v-if="activeSession"><message-rowv-for="message in activeSession.messages":key="message.id":message="message"></message-row></transition-group></div>
标签: 前端 ai spring

本文转载自: https://blog.csdn.net/Gachin/article/details/139793891
版权归原作者 起凡7 所有, 如有侵权,请联系我们删除。

“7. 综合演练聊天面板前端实现-SpringAI实战”的评论:

还没有评论