|
|
|
<script setup lang="ts">
|
|
|
|
import { computed, onMounted, ref } from 'vue'
|
|
|
|
import { Button } from 'ant-design-vue'
|
|
|
|
import { AppContainerBox } from '@/components/AppContainerBox'
|
|
|
|
import { AppSubMenuTitle } from '@/components/AppSubMenuTitle'
|
|
|
|
import { AppSubMenuList } from '@/components/AppSubMenuList'
|
|
|
|
import { AppConversationDefault } from '@/components/AppConversationDefault'
|
|
|
|
import type { SubMenuItem } from '@/components/AppSubMenuList/index.d'
|
|
|
|
import { AppTextarea } from '@/components/AppTextarea'
|
|
|
|
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 { useMqtt } from '@/hooks/useMqtt'
|
|
|
|
|
|
|
|
const messageStore = useMessageStore()
|
|
|
|
|
|
|
|
const sendBtnLoading = ref(false)
|
|
|
|
const subMenuActive = ref(0)
|
|
|
|
const subMenuList = ref<SubMenuItem[]>([])
|
|
|
|
const messageList = computed(() => messageStore.getMessageList)
|
|
|
|
const conversationData = computed(() => messageStore.getConversationData)
|
|
|
|
const historyMessageParams = ref({
|
|
|
|
conversationId: conversationData.value ? conversationData.value.id : '',
|
|
|
|
current: 1,
|
|
|
|
size: 10,
|
|
|
|
total: 0,
|
|
|
|
})
|
|
|
|
|
|
|
|
const conversationDefaultShow = ref(true)
|
|
|
|
|
|
|
|
function handleSubMenuChange(index: number) {
|
|
|
|
subMenuActive.value = index
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: 获取会话列表
|
|
|
|
*/
|
|
|
|
async function getConversationList() {
|
|
|
|
const res = await conversationList()
|
|
|
|
subMenuList.value = res
|
|
|
|
subMenuActive.value = 0
|
|
|
|
if (subMenuList.value.length) {
|
|
|
|
messageStore.setConversationData(subMenuList.value[subMenuActive.value])
|
|
|
|
historyMessageParams.value.current = 1
|
|
|
|
getHistoryMessage()
|
|
|
|
|
|
|
|
await useMqtt().connect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: 获取历史对话记录
|
|
|
|
*/
|
|
|
|
async function getHistoryMessage() {
|
|
|
|
const res = await historyMessage(historyMessageParams.value)
|
|
|
|
if (!res || !res.records || !res.records.length) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
res.records.forEach((item: any) => {
|
|
|
|
const itemData: MessageItem = {
|
|
|
|
messageType: item.roleType === MessageTypeEnum.USER ? MessageTypeEnum.USER : MessageTypeEnum.AI,
|
|
|
|
content: item.messageContent,
|
|
|
|
time: item.messageTime,
|
|
|
|
avatar: '',
|
|
|
|
messageStatus: MessageStatusEnum.END,
|
|
|
|
}
|
|
|
|
historyMessageParams.value.total = res.total
|
|
|
|
messageStore.setMessagePushItem(itemData)
|
|
|
|
})
|
|
|
|
conversationDefaultShow.value = false
|
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
getConversationList()
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<AppContainerBox>
|
|
|
|
<template #subMenu>
|
|
|
|
<!-- 标题 -->
|
|
|
|
<AppSubMenuTitle></AppSubMenuTitle>
|
|
|
|
|
|
|
|
<!-- 按钮 -->
|
|
|
|
<div class="px-5 mb-5">
|
|
|
|
<Button type="primary" class="w-full">
|
|
|
|
新建会话
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 会话列表 -->
|
|
|
|
<AppSubMenuList
|
|
|
|
:list="subMenuList"
|
|
|
|
:active-index="subMenuActive"
|
|
|
|
@change="handleSubMenuChange"
|
|
|
|
>
|
|
|
|
</AppSubMenuList>
|
|
|
|
</template>
|
|
|
|
<template #content>
|
|
|
|
<!-- 默认导语 -->
|
|
|
|
<AppConversationDefault
|
|
|
|
v-if="conversationDefaultShow"
|
|
|
|
height="calc(100% - 120px)"
|
|
|
|
>
|
|
|
|
</AppConversationDefault>
|
|
|
|
|
|
|
|
<!-- 消息列表 -->
|
|
|
|
<AppMessage v-else :list="messageList"></AppMessage>
|
|
|
|
|
|
|
|
<!-- 发送框 -->
|
|
|
|
<AppTextarea
|
|
|
|
class="pl-52 pr-32 mt-10"
|
|
|
|
:btn-loading="sendBtnLoading"
|
|
|
|
@send="handleSend"
|
|
|
|
></AppTextarea>
|
|
|
|
</template>
|
|
|
|
</AppContainerBox>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<style scoped></style>
|