add message view

This commit is contained in:
jxxghp
2024-03-15 18:15:31 +08:00
parent 8236d80b42
commit 046c21edf6
4 changed files with 297 additions and 3 deletions

View File

@@ -0,0 +1,102 @@
<script lang="ts" setup>
import store from '@/store'
import MessageCard from '@/components/cards/MessageCard.vue'
import type { Message } from '@/api/types'
import api from '@/api'
// 消息列表
const messages = ref<Message[]>([])
// 是否完成加载
const isLoaded = ref(false)
// 输入消息
const content = ref('')
// 聊天容器
const chatContainer = ref<HTMLDivElement>()
// 滚动到底部
function scrollToEnd() {
if (chatContainer.value)
chatContainer.value.scrollTop = chatContainer.value.scrollHeight
}
// SSE持续获取消息
function startSSEMessager() {
const token = store.state.auth.token
if (token) {
const eventSource = new EventSource(
`${import.meta.env.VITE_API_BASE_URL}system/message?token=${token}&role=user`,
)
eventSource.addEventListener('message', (event) => {
const message = event.data
if (message) {
const object = JSON.parse(message)
messages.value.push(object)
scrollToEnd()
}
isLoaded.value = true
})
onBeforeUnmount(() => {
eventSource.close()
})
}
}
// 调用API加载存量消息
async function loadMessages() {
try {
messages.value = await api.get('message/web')
}
catch (error) {
console.error(error)
}
}
onMounted(() => {
// 加载存量消息
loadMessages()
// 监听新消息
startSSEMessager()
})
</script>
<template>
<div
v-if="!isLoaded"
class="mt-5 w-full text-center flex flex-col items-center"
>
<VProgressCircular
size="48"
indeterminate
color="primary"
/>
<span class="mt-3">正在刷新 ...</span>
</div>
<div
v-if="messages.length === 0"
class="w-full text-center flex flex-col items-center"
>
<span class="mb-3">当前没有消息</span>
</div>
<VContainer ref="chatContainer" fluid style="padding: 0;">
<VRow
v-for="(msg, index) in messages"
:key="index"
>
<VCol
sm="8"
lg="6"
xl="4"
style="position: relative;"
>
<MessageCard
:message="msg"
/>
</VCol>
</VRow>
</VContainer>
</template>