|
|
@ -1,51 +1,27 @@
|
|
|
|
<script setup lang='ts'>
|
|
|
|
<script setup lang='ts'>
|
|
|
|
import { nextTick, onMounted, ref } from 'vue'
|
|
|
|
import { computed, nextTick, onMounted, ref } from 'vue'
|
|
|
|
import { NButton, NInput, useMessage } from 'naive-ui'
|
|
|
|
import { NButton, NInput, useMessage } from 'naive-ui'
|
|
|
|
|
|
|
|
import type { ChatOptions, ChatProps } from './types'
|
|
|
|
import { Message } from './components'
|
|
|
|
import { Message } from './components'
|
|
|
|
import { Layout } from './layout'
|
|
|
|
import { Layout } from './layout'
|
|
|
|
import { clearConversations, fetchChatAPI } from '@/api'
|
|
|
|
import { fetchChatAPI } from '@/api'
|
|
|
|
import { HoverButton, SvgIcon } from '@/components/common'
|
|
|
|
import { HoverButton, SvgIcon } from '@/components/common'
|
|
|
|
|
|
|
|
|
|
|
|
interface ListProps {
|
|
|
|
|
|
|
|
dateTime: string
|
|
|
|
|
|
|
|
message: string
|
|
|
|
|
|
|
|
reversal?: boolean
|
|
|
|
|
|
|
|
error?: boolean
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const scrollRef = ref<HTMLDivElement>()
|
|
|
|
const scrollRef = ref<HTMLDivElement>()
|
|
|
|
|
|
|
|
|
|
|
|
const ms = useMessage()
|
|
|
|
const ms = useMessage()
|
|
|
|
|
|
|
|
|
|
|
|
const prompt = ref('')
|
|
|
|
const prompt = ref('')
|
|
|
|
|
|
|
|
|
|
|
|
const loading = ref(false)
|
|
|
|
const loading = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
const list = ref<ListProps[]>([])
|
|
|
|
const list = ref<ChatProps[]>([])
|
|
|
|
|
|
|
|
const chatList = computed(() => list.value.filter(item => (!item.reversal && !item.error)))
|
|
|
|
onMounted(initChat)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function initChat() {
|
|
|
|
function initChat() {
|
|
|
|
addMessage('Hi, I am ChatGPT, a chatbot based on GPT-3.', false)
|
|
|
|
addMessage('Hi, I am ChatGPT, a chatbot based on GPT-3.')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function handleClear() {
|
|
|
|
onMounted(initChat)
|
|
|
|
try {
|
|
|
|
|
|
|
|
await clearConversations()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (error) {
|
|
|
|
|
|
|
|
ms.error('Clear failed, please try again later.')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
finally {
|
|
|
|
|
|
|
|
list.value = []
|
|
|
|
|
|
|
|
setTimeout(initChat, 100)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function handleEnter(event: KeyboardEvent) {
|
|
|
|
|
|
|
|
if (event.key === 'Enter')
|
|
|
|
|
|
|
|
handleSubmit()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function handleSubmit() {
|
|
|
|
async function handleSubmit() {
|
|
|
|
if (loading.value)
|
|
|
|
if (loading.value)
|
|
|
@ -58,26 +34,51 @@ async function handleSubmit() {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addMessage(message, true)
|
|
|
|
addMessage(message, { reversal: true })
|
|
|
|
prompt.value = ''
|
|
|
|
prompt.value = ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let options: ChatOptions = {}
|
|
|
|
|
|
|
|
const lastContext = chatList.value[chatList.value.length - 1]?.options
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (lastContext)
|
|
|
|
|
|
|
|
options = { ...lastContext }
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
loading.value = true
|
|
|
|
loading.value = true
|
|
|
|
const { data } = await fetchChatAPI(message)
|
|
|
|
const { data } = await fetchChatAPI(message, options)
|
|
|
|
addMessage(data?.text ?? '', false)
|
|
|
|
addMessage(data?.text ?? '', { options: { conversationId: data.conversationId, parentMessageId: data.id } })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (error: any) {
|
|
|
|
catch (error: any) {
|
|
|
|
addMessage(`Error: ${error.message ?? 'Request failed, please try again later.'}`, false, true)
|
|
|
|
addMessage(`Error: ${error.message ?? 'Request failed, please try again later.'}`, { error: true })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally {
|
|
|
|
finally {
|
|
|
|
loading.value = false
|
|
|
|
loading.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function addMessage(message: string, reversal = false, error = false) {
|
|
|
|
function handleEnter(event: KeyboardEvent) {
|
|
|
|
list.value.push({ dateTime: new Date().toLocaleString(), message, reversal, error })
|
|
|
|
if (event.key === 'Enter')
|
|
|
|
|
|
|
|
handleSubmit()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function addMessage(
|
|
|
|
|
|
|
|
message: string,
|
|
|
|
|
|
|
|
args?: { reversal?: boolean; error?: boolean; options?: ChatOptions },
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
list.value.push({
|
|
|
|
|
|
|
|
dateTime: new Date().toLocaleString(),
|
|
|
|
|
|
|
|
message,
|
|
|
|
|
|
|
|
reversal: args?.reversal ?? false,
|
|
|
|
|
|
|
|
error: args?.error ?? false,
|
|
|
|
|
|
|
|
options: args?.options ?? undefined,
|
|
|
|
|
|
|
|
})
|
|
|
|
nextTick(() => scrollRef.value && (scrollRef.value.scrollTop = scrollRef.value.scrollHeight))
|
|
|
|
nextTick(() => scrollRef.value && (scrollRef.value.scrollTop = scrollRef.value.scrollHeight))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function handleClear() {
|
|
|
|
|
|
|
|
list.value = []
|
|
|
|
|
|
|
|
setTimeout(initChat, 100)
|
|
|
|
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
@ -87,12 +88,8 @@ function addMessage(message: string, reversal = false, error = false) {
|
|
|
|
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
|
|
|
|
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
|
|
|
|
<div>
|
|
|
|
<div>
|
|
|
|
<Message
|
|
|
|
<Message
|
|
|
|
v-for="(item, index) of list"
|
|
|
|
v-for="(item, index) of list" :key="index" :date-time="item.dateTime" :message="item.message"
|
|
|
|
:key="index"
|
|
|
|
:reversal="item.reversal" :error="item.error"
|
|
|
|
:date-time="item.dateTime"
|
|
|
|
|
|
|
|
:message="item.message"
|
|
|
|
|
|
|
|
:reversal="item.reversal"
|
|
|
|
|
|
|
|
:error="item.error"
|
|
|
|
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|