This commit is contained in:
shengchanzhe 2023-10-13 16:26:35 +08:00
parent a358efeebc
commit faee446b5a
1 changed files with 170 additions and 172 deletions

View File

@ -1,6 +1,6 @@
<script setup lang='ts'> <script setup lang='ts'>
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue' import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { import {
@ -21,15 +21,11 @@ import { useBasicLayout } from '@/hooks/useBasicLayout'
import { useChatStore, usePromptStore } from '@/store' import { useChatStore, usePromptStore } from '@/store'
import { fetchChatAPIProcess } from '@/api' import { fetchChatAPIProcess } from '@/api'
import { t } from '@/locales' import { t } from '@/locales'
import indexBG from "@/components/animation/indexBG.vue" import indexBG from '@/components/animation/indexBG.vue'
import recording from "@/components/animation/recording.vue" import recording from '@/components/animation/recording.vue'
import inputing from "@/components/animation/inputing.vue" import inputing from '@/components/animation/inputing.vue'
import loding from "@/components/animation/loding.vue" import lodingSpin from '@/components/animation/lodingSpin.vue'
import lodingCir from "@/components/animation/lodingCir.vue"
import lodingSpin from "@/components/animation/lodingSpin.vue"
import IatRecorder from '@/utils/test.js'
import { start } from 'repl'
// import IatRecorder from '@/utils/larRcorder.js' // import IatRecorder from '@/utils/larRcorder.js'
// import socket from "@/websocket/socket"; // import socket from "@/websocket/socket";
@ -60,26 +56,26 @@ user_channel.on('message', (data: any) => {
if (recordFalg.value == 0) { if (recordFalg.value == 0) {
RecordXunfei() RecordXunfei()
recordFalg.value = 1 recordFalg.value = 1
nowStatus.value = 'record' nowStatus.value = 'record'
} }
else { else {
RecordXunfei() RecordXunfei()
recordFalg.value = 0 recordFalg.value = 0
nowStatus.value = 'loding' nowStatus.value = 'loding'
handleSubmit() handleSubmit()
} }
}) })
const changeRecord = ()=>{ const changeRecord = () => {
if (recordFalg.value == 0) { if (recordFalg.value == 0) {
RecordXunfei() RecordXunfei()
recordFalg.value = 1 recordFalg.value = 1
nowStatus.value = 'record' nowStatus.value = 'record'
} }
else { else {
RecordXunfei() RecordXunfei()
recordFalg.value = 0 recordFalg.value = 0
nowStatus.value = 'input' nowStatus.value = 'input'
} }
} }
@ -100,6 +96,7 @@ const { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll()
const { usingContext, toggleUsingContext } = useUsingContext() const { usingContext, toggleUsingContext } = useUsingContext()
const { uuid } = route.params as { uuid: string } const { uuid } = route.params as { uuid: string }
chatStore.getChatByUuid(+uuid).length = 0
const dataSources = computed(() => chatStore.getChatByUuid(+uuid)) const dataSources = computed(() => chatStore.getChatByUuid(+uuid))
const conversationList = computed(() => const conversationList = computed(() =>
@ -151,11 +148,11 @@ async function onConversation() {
// WebSocket // WebSocket
socket.onclose = (event: any) => { socket.onclose = (event: any) => {
console.log('连接已关闭: ', event) console.log('连接已关闭: ', event)
nowStatus.value = 'input' nowStatus.value = 'input'
} }
socket.onerror = (event: any) => { socket.onerror = (event: any) => {
console.log('连接出错: ', event) console.log('连接出错: ', event)
nowStatus.value = 'input' nowStatus.value = 'input'
} }
if (loading.value) if (loading.value)
@ -212,39 +209,40 @@ async function onConversation() {
}, },
], ],
})) }))
nowStatus.value = 'loding' nowStatus.value = 'loding'
// WebSocket // WebSocket
socket.onmessage = (event: any) => { socket.onmessage = (event: any) => {
try { try {
const msg = JSON.parse(event.data) const msg = JSON.parse(event.data)
// console.log(`: `, msg.payload.choices.text[0].content); // console.log(`: `, msg.payload.choices.text[0].content);
// console.log(`: `, dataSources.value[dataSources.value.length - 1].text); // console.log(`: `, dataSources.value[dataSources.value.length - 1].text);
lastText += msg.payload.choices.text[0].content lastText += msg.payload.choices.text[0].content
const loading = true const loading = true
nowStart.value = false nowStart.value = false
updateChat( updateChat(
+uuid, +uuid,
dataSources.value.length - 1, dataSources.value.length - 1,
{ {
dateTime: new Date().toLocaleString(), dateTime: new Date().toLocaleString(),
text: lastText, text: lastText,
inversion: false, inversion: false,
error: false, error: false,
loading, loading,
conversationOptions: { conversationId: msg.header.sid, parentMessageId: msg.header.sid }, conversationOptions: { conversationId: msg.header.sid, parentMessageId: msg.header.sid },
requestOptions: { prompt: message, options: { ...options } }, requestOptions: { prompt: message, options: { ...options } },
}, },
) )
// //
if(msg.header.code!=0||(event.data&&msg.header.status==2)){ if (msg.header.code != 0 || (event.data && msg.header.status == 2)) {
nowStatus.value = 'input' nowStatus.value = 'input'
socket.close() socket.close()
} }
} catch (error) { }
nowStatus.value = 'input' catch (error) {
socket.close() nowStatus.value = 'input'
} socket.close()
}
} }
// await fetchChatAPIProcess<Chat.ConversationResponse>({ // await fetchChatAPIProcess<Chat.ConversationResponse>({
@ -601,7 +599,6 @@ onUnmounted(() => {
controller.abort() controller.abort()
}) })
window.winText = '' window.winText = ''
window.addEventListener('test', (e) => { window.addEventListener('test', (e) => {
@ -612,42 +609,41 @@ window.addEventListener('test', (e) => {
// setTimeout(()=>{ // setTimeout(()=>{
// nowStart.value = false; // nowStart.value = false;
// }, 800) // }, 800)
</script> </script>
<template> <template>
<div class="flex w-full h-full my-layout"> <div class="flex w-full h-full my-layout">
<indexBG v-if="!isMobile"> <indexBG v-if="!isMobile">
<transition mode="out-in" name="fade"> <transition mode="out-in" name="fade">
<inputing v-if="nowStatus=='input'" key="input"></inputing> <inputing v-if="nowStatus == 'input'" key="input" />
<recording v-else-if="nowStatus=='record'" key="record"></recording> <recording v-else-if="nowStatus == 'record'" key="record" />
<!-- <loding v-else-if="nowStatus=='loding'" key="loding"></loding> --> <!-- <loding v-else-if="nowStatus=='loding'" key="loding"></loding> -->
<lodingSpin v-else-if="nowStatus=='loding'" key="loding"></lodingSpin> <lodingSpin v-else-if="nowStatus == 'loding'" key="loding" />
<!-- <lodingCir v-else-if="nowStatus=='loding'" key="loding"></lodingCir> --> <!-- <lodingCir v-else-if="nowStatus=='loding'" key="loding"></lodingCir> -->
</transition> </transition>
</indexBG> </indexBG>
<transition name="slide-right-to-left"> <transition name="slide-right-to-left">
<div v-if="!nowStart" class="flex flex-col w-full h-full" :style="{'max-width': maxWeight + 'px'}"> <div v-if="!nowStart" class="flex flex-col w-full h-full" :style="{ 'max-width': `${maxWeight}px` }">
<HeaderComponent <HeaderComponent
v-if="isMobile" v-if="isMobile"
:using-context="usingContext" :using-context="usingContext"
@export="handleExport" @export="handleExport"
@handle-clear="handleClear" @handle-clear="handleClear"
/> />
<main class="flex-1 overflow-hidden"> <main class="flex-1 overflow-hidden">
<div <div
id="scrollRef" id="scrollRef"
ref="scrollRef" ref="scrollRef"
class="h-full overflow-hidden overflow-y-auto" class="h-full overflow-hidden overflow-y-auto"
> >
<div <div
id="image-wrapper" id="image-wrapper"
class="w-full max-w-screen-xl m-auto dark:bg-[#101014]" class="w-full max-w-screen-xl m-auto dark:bg-[#101014]"
:class="[isMobile ? 'p-2' : 'p-4']" :class="[isMobile ? 'p-2' : 'p-4']"
:style="{'max-width': maxWeight + 'px'}" :style="{ 'max-width': `${maxWeight}px` }"
> >
<!-- <div @click="click">录音开始</div> --> <!-- <div @click="click">录音开始</div> -->
<!-- <div> <!-- <div>
浏览器录音听写<button id="btn_control" @click="click"> 浏览器录音听写<button id="btn_control" @click="click">
开始录音 开始录音
</button> </button>
@ -655,65 +651,67 @@ window.addEventListener('test', (e) => {
<br> <br>
<div id="result" ref="resultRef" /> --> <div id="result" ref="resultRef" /> -->
<template v-if="!dataSources.length"> <template v-if="!dataSources.length">
<div <div
class="flex items-center justify-center mt-4 text-center text-neutral-300" class="flex items-center justify-center mt-4 text-center text-neutral-300"
> >
<SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" /> <SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" />
<span>欢迎来到里海AI~</span> <span>欢迎来到里海AI~</span>
</div> </div>
</template> </template>
<template v-else> <template v-else>
<div> <div>
<Message <Message
v-for="(item, index) of dataSources" v-for="(item, index) of dataSources"
:key="index" :key="index"
:date-time="item.dateTime" :date-time="item.dateTime"
:text="item.text" :text="item.text"
:inversion="item.inversion" :inversion="item.inversion"
:error="item.error" :error="item.error"
:loading="item.loading" :loading="item.loading"
@regenerate="onRegenerate(index)" @regenerate="onRegenerate(index)"
@delete="handleDelete(index)" @delete="handleDelete(index)"
/> />
<div class="sticky bottom-0 left-0 flex justify-center"> <div class="sticky bottom-0 left-0 flex justify-center">
<NButton v-if="loading" type="warning" @click="handleStop"> <NButton v-if="loading" type="warning" @click="handleStop">
<template #icon> <template #icon>
<SvgIcon icon="ri:stop-circle-line" /> <SvgIcon icon="ri:stop-circle-line" />
</template> </template>
{{ t("common.stopResponding") }} {{ t("common.stopResponding") }}
</NButton> </NButton>
</div> </div>
</div> </div>
</template> </template>
</div> </div>
</div> </div>
</main> </main>
<footer :class="footerClass"> <footer :class="footerClass">
<div class="w-full max-w-screen-xl m-auto" <div
:style="{'max-width': maxWeight + 'px'}"> class="w-full max-w-screen-xl m-auto"
<div class="flex items-center justify-between space-x-2"> :style="{ 'max-width': `${maxWeight}px` }"
<HoverButton v-if="recordFalg==0" @click="changeRecord"> >
<span class="text-xl text-[#4f555e] dark:text-white"> <div class="flex items-center justify-between space-x-2">
录音 <HoverButton v-if="recordFalg == 0" @click="changeRecord">
</span> <span class="text-xl text-[#4f555e] dark:text-white">
</HoverButton> 录音
<HoverButton v-else-if="recordFalg==1" @click="changeRecord"> </span>
<span class="text-xl text-[#4f555e] dark:text-white"> </HoverButton>
完成 <HoverButton v-else-if="recordFalg == 1" @click="changeRecord">
</span> <span class="text-xl text-[#4f555e] dark:text-white">
</HoverButton> 完成
<HoverButton v-if="!isMobile" @click="handleClear"> </span>
<span class="text-xl text-[#4f555e] dark:text-white"> </HoverButton>
<SvgIcon icon="ri:delete-bin-line" /> <HoverButton v-if="!isMobile" @click="handleClear">
</span> <span class="text-xl text-[#4f555e] dark:text-white">
</HoverButton> <SvgIcon icon="ri:delete-bin-line" />
<!-- <HoverButton v-if="!isMobile" @click="handleExport"> </span>
</HoverButton>
<!-- <HoverButton v-if="!isMobile" @click="handleExport">
<span class="text-xl text-[#4f555e] dark:text-white"> <span class="text-xl text-[#4f555e] dark:text-white">
<SvgIcon icon="ri:download-2-line" /> <SvgIcon icon="ri:download-2-line" />
</span> </span>
</HoverButton> --> </HoverButton> -->
<!-- <HoverButton @click="toggleUsingContext"> <!-- <HoverButton @click="toggleUsingContext">
<span <span
class="text-xl" class="text-xl"
:class="{ :class="{
@ -724,41 +722,41 @@ window.addEventListener('test', (e) => {
<SvgIcon icon="ri:chat-history-line" /> <SvgIcon icon="ri:chat-history-line" />
</span> </span>
</HoverButton> --> </HoverButton> -->
<NAutoComplete <NAutoComplete
v-model:value="prompt" v-model:value="prompt"
:options="searchOptions" :options="searchOptions"
:render-label="renderOption" :render-label="renderOption"
> >
<template #default="{ handleInput, handleBlur, handleFocus }"> <template #default="{ handleInput, handleBlur, handleFocus }">
<NInput <NInput
v-model:value="prompt" v-model:value="prompt"
type="textarea" type="textarea"
:placeholder="placeholder" :placeholder="placeholder"
:autosize="{ minRows: 1, maxRows: isMobile ? 4 : 8 }" :autosize="{ minRows: 1, maxRows: isMobile ? 4 : 8 }"
@input="handleInput" @input="handleInput"
@focus="handleFocus" @focus="handleFocus"
@blur="handleBlur" @blur="handleBlur"
@keypress="handleEnter" @keypress="handleEnter"
/> />
</template> </template>
</NAutoComplete> </NAutoComplete>
<NButton <NButton
type="primary" type="primary"
:disabled="buttonDisabled" :disabled="buttonDisabled"
@click="handleSubmit" @click="handleSubmit"
> >
<template #icon> <template #icon>
<span class="dark:text-black"> <span class="dark:text-black">
<SvgIcon icon="ri:send-plane-fill" /> <SvgIcon icon="ri:send-plane-fill" />
</span> </span>
</template> </template>
</NButton> </NButton>
</div> </div>
</div> </div>
</footer> </footer>
</div> </div>
</transition> </transition>
</div> </div>
</template> </template>
<style scoped> <style scoped>