|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
<script setup lang="ts"> |
|
|
|
|
import { computed, onMounted, ref } from 'vue' |
|
|
|
|
import { Button } from 'ant-design-vue' |
|
|
|
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue' |
|
|
|
|
import { onBeforeRouteLeave } from 'vue-router' |
|
|
|
|
import { Button, message } from 'ant-design-vue' |
|
|
|
|
import { AppContainerBox } from '@/components/AppContainerBox' |
|
|
|
|
import { AppSubMenuTitle } from '@/components/AppSubMenuTitle' |
|
|
|
|
import { AppSubMenuList } from '@/components/AppSubMenuList' |
|
|
|
@ -11,7 +12,7 @@ import { AppMessage } from '@/components/AppMessage'
|
|
|
|
|
import type { MessageItem } from '@/components/AppMessage/index.d' |
|
|
|
|
import { useMessageStore } from '@/store/moules/messageStore/index' |
|
|
|
|
import { MessageStatusEnum, MessageTypeEnum } from '@/enums/messageEnum' |
|
|
|
|
import { conversationList, historyMessage, sendMessage } from '@/api/base/message' |
|
|
|
|
import { conversationList, historyMessage } from '@/api/base/message' |
|
|
|
|
import { useMqtt } from '@/hooks/useMqtt' |
|
|
|
|
|
|
|
|
|
const messageStore = useMessageStore() |
|
|
|
@ -19,10 +20,12 @@ const messageStore = useMessageStore()
|
|
|
|
|
const sendBtnLoading = ref(false) |
|
|
|
|
const subMenuActive = ref(0) |
|
|
|
|
const subMenuList = ref<SubMenuItem[]>([]) |
|
|
|
|
const appMessage = ref() |
|
|
|
|
const messageList = computed(() => messageStore.getMessageList) |
|
|
|
|
const messageStatus = computed(() => messageStore.getMessageStatus) |
|
|
|
|
const conversationData = computed(() => messageStore.getConversationData) |
|
|
|
|
const historyMessageParams = ref({ |
|
|
|
|
conversationId: conversationData.value ? conversationData.value.id : '', |
|
|
|
|
conversationId: '', |
|
|
|
|
current: 1, |
|
|
|
|
size: 10, |
|
|
|
|
total: 0, |
|
|
|
@ -30,40 +33,33 @@ const historyMessageParams = ref({
|
|
|
|
|
|
|
|
|
|
const conversationDefaultShow = ref(true) |
|
|
|
|
|
|
|
|
|
watch( |
|
|
|
|
() => messageStatus.value, |
|
|
|
|
(val) => { |
|
|
|
|
if (val === MessageStatusEnum.END) { |
|
|
|
|
sendBtnLoading.value = false |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
function handleSubMenuChange(index: number) { |
|
|
|
|
if (messageStatus.value !== MessageStatusEnum.END) { |
|
|
|
|
message.warn('请先结束对话') |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
subMenuActive.value = index |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @description: 发送消息 |
|
|
|
|
*/ |
|
|
|
|
function handleSend(value: string) { |
|
|
|
|
console.log('handleSend', value) |
|
|
|
|
sendBtnLoading.value = true |
|
|
|
|
conversationDefaultShow.value = false |
|
|
|
|
messageStore.setMessageStatus(MessageStatusEnum.LOADING) |
|
|
|
|
messageStore.setMessageFirstItem({ |
|
|
|
|
messageType: MessageTypeEnum.USER, |
|
|
|
|
content: value, |
|
|
|
|
time: String(new Date().getTime()), |
|
|
|
|
avatar: '', |
|
|
|
|
}) |
|
|
|
|
messageStore.setMessageFirstItem({ |
|
|
|
|
messageType: MessageTypeEnum.AI, |
|
|
|
|
content: '正在思考中...', |
|
|
|
|
time: String(new Date().getTime()), |
|
|
|
|
avatar: '', |
|
|
|
|
messageStatus: MessageStatusEnum.LOADING, |
|
|
|
|
}) |
|
|
|
|
if (!messageStore.getConversationData) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
sendMessage({ |
|
|
|
|
roleId: messageStore.getConversationData.roleId, |
|
|
|
|
conversationId: messageStore.getConversationData.id, |
|
|
|
|
question: value, |
|
|
|
|
}).then(() => { |
|
|
|
|
|
|
|
|
|
}).catch(() => { |
|
|
|
|
messageStore.setMessageStatus(MessageStatusEnum.END) |
|
|
|
|
}) |
|
|
|
|
useMqtt().sendMessage(messageStore.getConversationData.roleId, messageStore.getConversationData.id, value) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -86,6 +82,10 @@ async function getConversationList() {
|
|
|
|
|
* @description: 获取历史对话记录 |
|
|
|
|
*/ |
|
|
|
|
async function getHistoryMessage() { |
|
|
|
|
if (!conversationData.value) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
historyMessageParams.value.conversationId = conversationData.value.id |
|
|
|
|
const res = await historyMessage(historyMessageParams.value) |
|
|
|
|
if (!res || !res.records || !res.records.length) { |
|
|
|
|
return |
|
|
|
@ -99,14 +99,59 @@ async function getHistoryMessage() {
|
|
|
|
|
messageStatus: MessageStatusEnum.END, |
|
|
|
|
} |
|
|
|
|
historyMessageParams.value.total = res.total |
|
|
|
|
messageStore.setMessagePushItem(itemData) |
|
|
|
|
messageStore.setMessageUnshiftItem(itemData) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
conversationDefaultShow.value = false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @description: 滚动监听 |
|
|
|
|
*/ |
|
|
|
|
async function onScrollTop(scrollTop: number) { |
|
|
|
|
if (scrollTop !== 0) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (historyMessageParams.value.current * historyMessageParams.value.size > historyMessageParams.value.total) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (historyMessageParams.value.current < historyMessageParams.value.total) { |
|
|
|
|
historyMessageParams.value.current++ |
|
|
|
|
await getHistoryMessage() |
|
|
|
|
|
|
|
|
|
// 无缝滚动 |
|
|
|
|
appMessage.value.seamlessScrollToTop() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @description: 重新回答 |
|
|
|
|
*/ |
|
|
|
|
function reloadMessage() { |
|
|
|
|
if (!messageStore.getConversationData) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
const question = messageList.value[messageList.value.length - 2]?.content |
|
|
|
|
useMqtt().sendMessage(messageStore.getConversationData.roleId, messageStore.getConversationData.id, question) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
|
getConversationList() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
onUnmounted(() => { |
|
|
|
|
useMqtt().end() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
// 路由离开时的操作 |
|
|
|
|
onBeforeRouteLeave(() => { |
|
|
|
|
if (messageStatus.value !== MessageStatusEnum.END) { |
|
|
|
|
message.warn('请先结束对话') |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
@ -139,7 +184,15 @@ onMounted(() => {
|
|
|
|
|
</AppConversationDefault> |
|
|
|
|
|
|
|
|
|
<!-- 消息列表 --> |
|
|
|
|
<AppMessage v-else :list="messageList"></AppMessage> |
|
|
|
|
<AppMessage |
|
|
|
|
v-else |
|
|
|
|
ref="appMessage" |
|
|
|
|
class="pl-27 pr-5" |
|
|
|
|
:list="messageList" |
|
|
|
|
@on-scroll-top="onScrollTop" |
|
|
|
|
@reload-message="reloadMessage" |
|
|
|
|
> |
|
|
|
|
</AppMessage> |
|
|
|
|
|
|
|
|
|
<!-- 发送框 --> |
|
|
|
|
<AppTextarea |
|
|
|
|