<template> <view id='app'> <view class="placeholder"></view> <view class="pageView"> <view class="sidebar-left"></view> <view class="body"> <view class="head"> <text>睿宝AI</text> </view> <view class="list-wrap"> <scroll-view id="content-box" scroll-y="true" class="scrollview" :scroll-top="msgList.scrollTop"> <!-- 聊天主体 --> <view id="content-overflow"> <view class="scrollview-item" v-for="(item,index) in msgList.chatList" :key='index'> <!-- user方-聊天内容 --> <view class="item self" v-if="item.userContent != ''"> <image class="avtar" src="../../static/user-avatar.png" mode="aspectFit"></image> <view class="content right" disabled>{{ item.userContent }}</view> </view> <!-- ai方-聊天内容 --> <view class="item other"> <view class=""> <view class="loadingPoint" v-if='msgList.isloading[index]'> <loadingPointsVue></loadingPointsVue> </view> <view class="content left" v-if='!msgList.isloading[index]'> {{ msgList.otherChatList[index] }}</view> </view> <image class="avtar" src="../../static/Ai-avatar.png" mode="aspectFit"></image> </view> </view> </view> </scroll-view> </view> <view class="chat-bottom"> <view class="send-msg"> <view class="uni-textarea"> <textarea id="input-textarea" type="text" v-model="msgList.chatMsg" placeholder="快来聊天吧" confirm-type="send" @confirm="handleSend" maxlength="300" /> </view> <view class="uni-button"> <button class="send-btn" @click="handleSend" type="primary">发送</button> </view> </view> </view> </view> <view class="sidebar-right"> <image src="../../static/logo.png" mode="aspectFit"></image> </view> </view> </view> </template> <script setup> import { nextTick, reactive, watch } from 'vue'; import { getDataList } from '../../api/ChatApp.js' import axios from 'axios'; import loadingPointsVue from '../../components/loadingPoints.vue'; const msgList = reactive({ // 输入框 chatMsg: '', // 聊天数据列表 chatList: [], // 滚动距离 scrollTop: 0, // timer: null, textCount: 0, otherContent: '', otherChatList: [], len: 0, isloading: [], isClick:false }) // 发送消息 const handleSend = async () => { msgList.isClick = !msgList.isClick const data = { AppId: '0c8ff06b-91d9-43f7-b61e-ca5da1db15d4', AId: 'TK1234', content: '' } if (msgList.chatMsg != '') { msgList.isloading[msgList.len] = true msgList.len++ let obj = { otherContent: '', userContent: '', image: "" } data.content = msgList.chatMsg obj.userContent = msgList.chatMsg msgList.chatList.push(obj) obj.otherContent = await GetNewsList(data) await sleep(16000); getChatContent(obj.otherContent, msgList.len) } msgList.otherContent = '' } // 滚动条回到最底部 const scrollToBottom = (() => { nextTick(() => { const query = uni.createSelectorQuery(); query.select("#content-box").boundingClientRect() query.select("#content-overflow").boundingClientRect() query.exec(res => { const scrollViewHeight = res[0].height const scrollContentHeight = res[1].height if (scrollViewHeight < scrollContentHeight) { const scrollTop = scrollContentHeight - scrollViewHeight msgList.scrollTop = scrollTop } }) }) }) //滚动至聊天底部 watch([msgList.otherChatList,msgList.chatList], (newVal) => { scrollToBottom() }) // 调用数据接口 const GetNewsList = async (data) => { msgList.chatMsg = '' var res = await getDataList(data) console.log(res) return res } // ------- 聊天逐字输出 ----------- // 延时函数 const sleep = ((delaytime = 10000) => { return new Promise(resolve => setTimeout(resolve, delaytime)); }) // 逐字显示内容 const getChatContent = ((text, index) => { console.log(index) msgList.timer = setInterval(() => { msgList.textCount++; if (msgList.textCount == text.length + 1) { msgList.otherChatList[index - 1] = text; clearInterval(msgList.timer); } else { // 取字符串子串 let nowStr = text.substring(0, msgList.textCount); msgList.otherChatList[index - 1] = nowStr; } }, 200); console.log(msgList.timer) msgList.textCount = 0 msgList.isloading[index - 1] = false msgList.isClick = !msgList.isClick }) </script> <style> @import url("../../theme/chat32.css"); </style>