0


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

前端实现

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

前端的聊天面板组件是以

chat-view.vue

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

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

会话列表

会话列表

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

<!-- 左侧的会话列表 --><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>

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

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 })
  sessionList.value.unshift(sessionRes)
  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
  })
  sessionList.value.splice(index,1)if(index == sessionList.value.length){
    activeSession.value = sessionList.value[index -1]}else{
    activeSession.value = sessionList.value[index]}}onMounted(async()=>{// 查询自己的聊天会话
  api.aiSessionController.findByUser().then((res)=>{// 讲会话添加到列表中
    sessionList.value = res.map((row)=>{return{...row, checked:false}})// 默认选中的聊天会话是第一个if(sessionList.value.length >0){
      activeSession.value = sessionList.value[0]}else{handleSessionCreate()}
    loading.value =false})})

消息发送和展示

消息列表和消息发送

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

用户发送的逻辑,使用

sse.js

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

consthandleSendMessage=async(message:{ text:string; image:string})=>{if(!activeSession.value){
    ElMessage.warning('请创建会话')return}// 图片/语音const medias: AiMessage['medias']=[]if(message.image){
    medias.push({ type:'image', data: message.image })}// 用户的提问const chatMessage ={
    id:newDate().getTime().toString(),
    sessionId: activeSession.value.id,
    medias,
    textContent: message.text,
    type:'USER'} satisfies AiMessage

  // 新建一个ChatGPT回复对象,不能重复使用同一个对象。
  responseMessage.value ={
    id:newDate().getTime().toString(),
    type:'ASSISTANT',
    textContent:'',
    sessionId: activeSession.value.id
  }const evtSource =newSSE(import.meta.env.VITE_API_PREFIX+'/message/chat',{
    withCredentials:true,// 禁用自动启动,需要调用stream()方法才能发起请求
    start:false,
    headers:{'Content-Type':'application/json'},
    payload:JSON.stringify(chatMessage),
    method:'POST'})
  evtSource.addEventListener('message',async(event:any)=>{
    responseMessage.value.textContent = event.data
    // 非通义千问使用下面的消息拼接逻辑// responseMessage.value.textContent += event.data})// 调用stream,发起请求。
  evtSource.stream()// 将两条消息显示在页面中
  activeSession.value.messages.push(...[chatMessage, responseMessage.value])awaitnextTick(()=>{
    messageListRef.value?.scrollTo(0, messageListRef.value.scrollHeight)})}

遍历会话中的消息并展示

<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实战”的评论:

还没有评论