赞
踩
const requestTask = wx.request({ url: `xxx`, // 需要请求的接口地址 enableChunked: true, // enableChunked必须为true method: "GET", timeout: '120000', success(res) { console.log(res.data) }, fail: function (error) { // 请求失败的操作 console.error(error); }, complete: function () { // 请求完成的操作,无论成功或失败都会执行 console.log('请求完成', str); } }) // 监听服务端返回的数据 requestTask.onChunkReceived(res => { console.log( res, res.data); })
// 监听服务端返回的数据 requestTask.onChunkReceived(res => { console.log( res, res.data); // Uint8Array转为text格式 let arrayBuffer = res.data; let decoder = new TextDecoder('utf-8'); let text = decoder.decode(arrayBuffer); //正则匹配上所有event:data后面的文字 const eventRegex = /event:data\ndata:"data:(.*?)"/g; const eventRegexErr = /event:600\ndata:"(.*?)"/g; let matches = []; let match; if (text.indexOf('600') != -1) {//如果获取响应失败 while ((match = eventRegexErr.exec(text)) !== null) { wx.showToast({ title: match[1], }) matches.push(match[1]); } str = str + matches.join('') } else {//如果获取响应成功 while ((match = eventRegex.exec(text)) !== null) { matches.push(match[1]); } //处理成字符串 str = str + matches.join('') console.log(text, str); } })
handleRequestResolve(result) { this.setData({ currentContent: '' }) const contentCharArr = result.trim().split("") this.showText(0, contentCharArr); }, showText(key = 0, value) { /* 所有内容展示完成 */ if (key >= value.length) { // wx.vibrateShort() //判断字是否展示完 this.setData({ isShowFinish: true }) return; } /* 渲染回话内容 */ this.setData({ currentContent: this.data.currentContent + value[key], }) setTimeout(() => { /* 递归渲染内容 */ this.showText(key + 1, value); }, 50); },
handleScollTop() { return new Promise((resolve) => { const query = wx.createSelectorQuery() query.select('.page-content').boundingClientRect() query.select('.scroll-view-content').boundingClientRect() query.exec((res) => { const scrollViewHeight = res[0].height const scrollContentHeight = res[1].height if (scrollContentHeight > (scrollViewHeight - 200)) { const scrollTop = scrollContentHeight - scrollViewHeight + 200 this.setData({ scrollTop }, () => { resolve() }) } else { resolve() } }) }) }, showText(key = 0, value) { /* 所有内容展示完成 */ if (key >= value.length) { // wx.vibrateShort() this.setData({ isShowFinish: true }) return; } /* 渲染回话内容 */ this.setData({ currentContent: this.data.currentContent + value[key], }, () => { this.handleScollTop().then(() => { setTimeout(() => { this.showText(key + 1, value); }, 20); }) }) },
<scroll-view scroll-y scroll-top="{{scrollTop}}" wx:else class="page-content {{isFirst ? '' : 'page-content-bg'}}"> <view class="scroll-view-content"> <view wx:for="{{talkArr}}" wx:key="index" class="talk-box1"> <view class="talk-box-question" wx:if="{{item.isAnswer=='0'}}"> <view class="left"> <text class="left-content">{{item.content}}</text> </view> <image class="right" src="../images/user-icon.png" mode="aspectFill" /> </view> <view class="talk-box-reply" wx:else> <image class="left" src="../images/ai-icon.png" mode="aspectFill" /> <view class="right"> <view class="right-content"> <view wx:if="{{(index!=talkArr.length-1)}}">{{item.content}}</view> <view wx:else> <view wx:if="{{loading}}"> <image class="loading" src="../images/loading-1.png" mode="aspectFill" /> </view> <view wx:else> {{currentContent}} </view> </view> </view> </view> </view> </view> </view> </scroll-view>
.page-content { width: 100%; margin-top: 48rpx; padding-top: 150rpx; } .page-content-bg { background: #F5F6F7; height: 75%; padding-bottom: 280rpx; overflow: scroll; padding-top: 0; } .scroll-view-content { padding-top: 50rpx; } .talk-box { display: flex; } .talk-box1 { width: 90%; margin: 0 auto; } .talk-box .left { width: 80rpx; height: 80rpx; } .talk-box .right { margin-left: 30rpx; flex: 1; } .talk-item { height: 92rpx; background: #F6FFF9; border-radius: 0rpx 20rpx 20rpx 20rpx; font-family: PingFang SC, PingFang SC; font-weight: 500; font-size: 28rpx; color: rgba(51, 51, 51, 0.9); text-align: left; display: flex; align-items: center; padding: 0 38rpx; } .talk-box-question, .talk-box-reply { width: 100%; display: flex; margin-bottom: 32rpx; } .talk-box-question .left { flex: 1; display: flex; align-items: center; justify-content: flex-end; } .left-content { background: linear-gradient(273deg, #44BE35 0%, #6ECB63 100%); box-shadow: 0rpx 2rpx 8rpx 0rpx rgba(0, 0, 0, 0.05); border-radius: 24rpx 0rpx 24rpx 24rpx; padding: 24rpx; font-family: PingFang SC, PingFang SC; font-weight: 400; font-size: 28rpx; color: #FFFFFF; line-height: 44rpx; text-align: left; } .talk-box-question .right { margin-left: 30rpx; width: 80rpx; height: 80rpx; } .talk-box-reply .left { width: 80rpx; height: 80rpx; } .talk-box-reply .right { margin-left: 30rpx; flex: 1; display: flex; align-items: center; justify-content: flex-start; } .right-content { background: #FFFFFF; box-shadow: 0rpx 2rpx 8rpx 0rpx rgba(0, 0, 0, 0.05); border-radius: 0rpx 24rpx 24rpx 24rpx; border: 2rpx solid #6ECB63; padding: 24rpx; font-family: PingFang SC, PingFang SC; font-weight: 400; font-size: 28rpx; color: rgba(0, 0, 0, 0.9); line-height: 46rpx; text-align: left; }
data: { isShowFinish: false, scrollTop: '', currentContent: '', loading: false, talkArr: [] }, getDataStream(data) { let str = '' let that = this this.setData({ loading: true, }) // 基础库为2.33.0 const requestTask = wx.request({ enableChunked: true, // 开启分片模式 url: `xxx`, // 需要请求的接口地址 enableChunked: true, // enableChunked必须为true method: "GET", responseType: "arraybuffer", timeout: '120000', success(res) {}, fail: function (error) { // 请求失败的操作 console.error(error); }, complete: function () { // 请求完成的操作,无论成功或失败都会执行 that.handleRequestResolve(str) let index = that.data.talkArr.length - 1 let answerContent = `talkArr[${index}].content` that.setData({ [answerContent]: str, loading: false }) } }) // 监听服务端返回的数据 requestTask.onChunkReceived(res => { // Uint8Array转为text格式 let arrayBuffer = res.data; let decoder = new TextDecoder('utf-8'); let text = decoder.decode(arrayBuffer); //正则匹配上所有event:data后面的文字 const eventRegex = /event:data\ndata:"data:(.*?)"/g; const eventRegexErr = /event:600\ndata:"(.*?)"/g; let matches = []; let match; if (text.indexOf('600') != -1) { //如果获取响应失败 while ((match = eventRegexErr.exec(text)) !== null) { wx.showToast({ title: match[1], icon: 'none' }) matches.push(match[1]); } str = str + matches.join('') } else { //如果获取响应成功 while ((match = eventRegex.exec(text)) !== null) { matches.push(match[1]); } //处理成字符串 str = str + matches.join('') } }) requestTask.offChunkReceived(res => {}) }, handleScollTop() { return new Promise((resolve) => { const query = wx.createSelectorQuery() query.select('.page-content').boundingClientRect() query.select('.scroll-view-content').boundingClientRect() query.exec((res) => { const scrollViewHeight = res[0].height const scrollContentHeight = res[1].height if (scrollContentHeight > (scrollViewHeight - 200)) { const scrollTop = scrollContentHeight - scrollViewHeight + 200 this.setData({ scrollTop }, () => { resolve() }) } else { resolve() } }) }) }, handleRequestResolve(result) { this.setData({ currentContent: '' }) const contentCharArr = result.trim().split("") this.setData({ isShowFinish: false }) this.showText(0, contentCharArr); }, showText(key = 0, value) { /* 所有内容展示完成 */ if (key >= value.length) { // wx.vibrateShort() this.setData({ isShowFinish: true }) return; } /* 渲染回话内容 */ this.setData({ currentContent: this.data.currentContent + value[key], }, () => { this.handleScollTop().then(() => { setTimeout(() => { this.showText(key + 1, value); }, 20); }) }) },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。