feat: 前后端统一接口类型
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
interface Props {
|
||||
reversal?: boolean
|
||||
error?: boolean
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
@@ -8,7 +9,7 @@ defineProps<Props>()
|
||||
|
||||
<template>
|
||||
<div class="p-2 mt-2 rounded-md" :class="[reversal ? 'bg-[#d2f9d1]' : 'bg-[#f4f6f8]']">
|
||||
<span class="leading-relaxed whitespace-pre-wrap">
|
||||
<span class="leading-relaxed whitespace-pre-wrap" :class="[{ 'text-red-400': error }]">
|
||||
<slot />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ interface Props {
|
||||
message?: string
|
||||
dateTime?: string
|
||||
reversal?: boolean
|
||||
error?: boolean
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
@@ -23,7 +24,7 @@ defineProps<Props>()
|
||||
<span class="text-xs text-[#b4bbc4]">
|
||||
{{ dateTime }}
|
||||
</span>
|
||||
<Text :reversal="reversal">
|
||||
<Text :reversal="reversal" :error="error">
|
||||
{{ message }}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
import { nextTick, onMounted, ref } from 'vue'
|
||||
import { NButton, NInput, useMessage } from 'naive-ui'
|
||||
import { Message } from './components'
|
||||
import { clearChatContext, fetchChatAPI } from './request'
|
||||
import { Layout } from './layout'
|
||||
import { clearConversations, fetchChatAPI } from '@/api'
|
||||
import { HoverButton, SvgIcon } from '@/components/common'
|
||||
|
||||
interface ListProps {
|
||||
dateTime: string
|
||||
message: string
|
||||
reversal?: boolean
|
||||
error?: boolean
|
||||
}
|
||||
|
||||
const scrollRef = ref<HTMLDivElement>()
|
||||
@@ -30,13 +31,13 @@ function initChat() {
|
||||
|
||||
async function handleClear() {
|
||||
try {
|
||||
const { message } = await clearChatContext()
|
||||
ms.success(message)
|
||||
list.value = []
|
||||
setTimeout(initChat, 100)
|
||||
const { message } = await clearConversations()
|
||||
ms.success(message ?? 'Success')
|
||||
}
|
||||
catch (error) {
|
||||
ms.error('Clear failed, please try again later.')
|
||||
list.value = []
|
||||
setTimeout(initChat, 100)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +47,9 @@ function handleEnter(event: KeyboardEvent) {
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
if (loading.value)
|
||||
return
|
||||
|
||||
const message = prompt.value.trim()
|
||||
|
||||
if (!message || !message.length) {
|
||||
@@ -58,19 +62,19 @@ async function handleSubmit() {
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
const { text } = await fetchChatAPI(message)
|
||||
addMessage(text, false)
|
||||
const { data } = await fetchChatAPI(message)
|
||||
addMessage(data?.text ?? '', false)
|
||||
}
|
||||
catch (error: any) {
|
||||
addMessage(error.message ?? 'Request failed, please try again later.', false)
|
||||
addMessage(`Error: ${error.message ?? 'Request failed, please try again later.'}`, false, true)
|
||||
}
|
||||
finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function addMessage(message: string, reversal = false) {
|
||||
list.value.push({ dateTime: new Date().toLocaleString(), message, reversal })
|
||||
function addMessage(message: string, reversal = false, error = false) {
|
||||
list.value.push({ dateTime: new Date().toLocaleString(), message, reversal, error })
|
||||
nextTick(() => scrollRef.value && (scrollRef.value.scrollTop = scrollRef.value.scrollHeight))
|
||||
}
|
||||
</script>
|
||||
@@ -82,8 +86,12 @@ function addMessage(message: string, reversal = false) {
|
||||
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
|
||||
<div>
|
||||
<Message
|
||||
v-for="(item, index) of list" :key="index" :date-time="item.dateTime" :message="item.message"
|
||||
v-for="(item, index) of list"
|
||||
:key="index"
|
||||
:date-time="item.dateTime"
|
||||
:message="item.message"
|
||||
:reversal="item.reversal"
|
||||
:error="item.error"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang='ts'>
|
||||
import { ref, watch } from 'vue'
|
||||
import { NButton, NLayoutSider } from 'naive-ui'
|
||||
import { NButton, NLayoutSider, useMessage } from 'naive-ui'
|
||||
import List from './List.vue'
|
||||
import Footer from './Footer.vue'
|
||||
|
||||
@@ -18,6 +18,8 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const ms = useMessage()
|
||||
|
||||
const collapsed = ref(props.collapsed)
|
||||
|
||||
watch(
|
||||
@@ -28,6 +30,10 @@ watch(
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
function handleAdd() {
|
||||
ms.info('Coming soon...')
|
||||
}
|
||||
|
||||
function handleCollapsed() {
|
||||
collapsed.value = !collapsed.value
|
||||
emit('update:collapsed', collapsed.value)
|
||||
@@ -47,8 +53,8 @@ function handleCollapsed() {
|
||||
<div class="flex flex-col h-full">
|
||||
<main class="flex-1 min-h-0 overflow-hidden">
|
||||
<div class="p-4">
|
||||
<NButton dashed block>
|
||||
Add chat
|
||||
<NButton dashed block @click="handleAdd">
|
||||
New chat
|
||||
</NButton>
|
||||
</div>
|
||||
<List />
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const BASE_URL = import.meta.env.VITE_GLOB_API_URL
|
||||
|
||||
async function fetchChatAPI(message: string) {
|
||||
if (!message || message.trim() === '')
|
||||
return
|
||||
|
||||
try {
|
||||
const { status, data } = await axios.post(`${BASE_URL}/chat`, { message })
|
||||
|
||||
if (status === 200) {
|
||||
if (data.text)
|
||||
return Promise.resolve(data)
|
||||
|
||||
if (data.statusText)
|
||||
return Promise.reject(new Error(data.statusText))
|
||||
}
|
||||
|
||||
return Promise.reject(new Error('Request failed'))
|
||||
}
|
||||
catch (error) {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
}
|
||||
|
||||
async function clearChatContext() {
|
||||
try {
|
||||
const { status, data } = await axios.post(`${BASE_URL}/clear`)
|
||||
|
||||
if (status === 200)
|
||||
return Promise.resolve(data)
|
||||
|
||||
return Promise.reject(new Error('Request failed'))
|
||||
}
|
||||
catch (error) {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
}
|
||||
|
||||
export { fetchChatAPI, clearChatContext }
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang='ts'>
|
||||
|
||||
import { GithubSite } from '@/components/custom'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -8,11 +8,11 @@
|
||||
<img class="object-cover" src="@/assets/avatar.jpg" alt="avatar">
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<h2 class="text-sm font-bold">
|
||||
Redon
|
||||
<h2 class="font-bold text-md">
|
||||
ChenZhaoYu
|
||||
</h2>
|
||||
<p class="text-xs text-gray-500">
|
||||
#0827
|
||||
<GithubSite />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<template>
|
||||
<div class="fixed bottom-0 left-0 right-0 p-4 text-sm text-center text-neutral-500">
|
||||
<span class="text-center">
|
||||
❤️ Made By ChenZhaoYu -
|
||||
<a href="https://github.com/Chanzhaoyu/chatgpt-bot" target="_blank" class="text-blue-500">
|
||||
Github
|
||||
</a>
|
||||
</span>
|
||||
<div class="text-center text-neutral-500">
|
||||
<span>❤️ Star on</span>
|
||||
<a href="https://github.com/Chanzhaoyu/chatgpt-bot" target="_blank" class="text-blue-500">
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user