<template>
<text class="message-content-text" style="color: #fff;font-size: 28rpx;line-height: 1.5;">
{{contents}}
</text>
<text style="color: #fff;" :style="{ opacity }" v-if="isSend">|</text>
</template>
<script setup>
const props = defineProps({
inputMessage: {
type: String,
default: ''
}
})
import { HTTP_REQUEST_URL } from '@/config';
let eventSource : UniEventSource | null = null
let once = true
const contents = ref('')
const getContents = computed(() => contents.value)
const isSend = ref(true)
const opacity = ref(1)
let timer : number | null = null
const setOpacity = () => {
if (timer !== null) clearInterval(timer as number)
timer = setInterval(() => {
opacity.value = opacity.value > 0 ? 0 : 1
}, 500)
}
const emit = defineEmits(['stop', 'updateScrollTop'])
setOpacity()
onUnmounted(() => {
eventSource?.close()
if (timer !== null) clearInterval(timer as number)
})
const handleAPICall = () => {
let displayMessage = '';
eventSource = uni.connectEventSource({ url: HTTP_REQUEST_URL + '/api/chat/stream' });
eventSource?.onMessage(({ data }) => {
try {
const jsonData = JSON.parseObject(data as string);
const output = jsonData?.get("output") as UTSJSONObject | null;
const rawText = output?.get("text");
const newText = typeof rawText === 'string' ? rawText : '';
displayMessage += newText
nextTick(() => {
if ((displayMessage != '' && displayMessage != null) || (newText != '' && newText != null) && (displayMessage != newText)) {
contents.value = displayMessage
if (isSend.value) {
isSend.value = false;
if (timer !== null) clearInterval(timer as number)
}
nextTick(() => {
emit('updateScrollTop')
})
}
})
// throttledSetContent(displayMessage)
// 检查是否是最后一次数据
if (output?.get("finish_reason") == 'stop') {
emit('updateScrollTop')
emit('stop')
eventSource?.close(); // 关闭 SSE
console.log('displayMessage:', displayMessage);
}
} catch (e) {
console.log(e, '<<>><><><<');
uni.showToast({
title: '连接错误,已中断连接',
icon: 'none'
});
emit('stop')
emit('updateScrollTop')
eventSource?.close();
}
});
eventSource?.onError((error : any) => {
emit('stop')
eventSource?.close();
isSend.value = false;
});
};
watch(() : string => props.inputMessage, (t : string) => {
if (t == '' && once) {
setTimeout(() => {
handleAPICall()
once = false
}, 100)
}
})
</script>
<style>
</style>
1 个回复
DCloud_heavensoft
不用自己研究啦,看这个插件:https://ext.dcloud.net.cn/plugin?id=23902