This commit is contained in:
shengchanzhe 2023-10-15 13:42:20 +08:00
parent 95a6257c53
commit 92d1685688
4 changed files with 151 additions and 52 deletions

View File

@ -210,5 +210,4 @@ function RecordXunfei() {
// 结束录音 // 结束录音
recorder.stop() recorder.stop()
} }
return window.winText
} }

View File

@ -1,14 +1,28 @@
<template> <template>
<div /> <div style="position: relative;">
<div class="div" />
<p class="text">
正在唤起录音
</p>
</div>
</template> </template>
<style scoped> <style scoped>
div { .text{
display: block;
width: 100%;
font-size: 1.5em;
text-align: center;
position: absolute;
left: 0;
bottom: -2em;
}
.div {
width: 20em; width: 20em;
height: 20em; height: 20em;
border: 3em solid transparent; border: 3em solid transparent;
border-top-color: #3cefff; border-top-color: #7fe7c4;
border-bottom-color: #3cefff; border-bottom-color: #7fe7c4;
border-radius: 50%; border-radius: 50%;
animation: spin-stretch 1.5s ease infinite; animation: spin-stretch 1.5s ease infinite;
} }

View File

@ -297,12 +297,15 @@ const pauseAudio = () => {
const noPauseAudio = () => { const noPauseAudio = () => {
playStatus.value = 'playing' playStatus.value = 'playing'
emit('changeNowStatus', 'playing') emit('changeNowStatus', 'playing')
audioElements[pauseIndex].play() audioElements[pauseIndex]?.play()
pauseIndex = -1 pauseIndex = -1
} }
defineExpose({ defineExpose({
stopPlay, stopPlay,
pauseAudio,
noPauseAudio,
radioPlay,
}) })
</script> </script>

View File

@ -4,11 +4,10 @@ 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 {
NAutoComplete,
NButton, NButton,
NInput,
useDialog, useDialog,
useMessage, useMessage,
} from 'naive-ui' } from 'naive-ui'
import html2canvas from 'html2canvas' import html2canvas from 'html2canvas'
import { Message } from './components' import { Message } from './components'
@ -16,7 +15,7 @@ import { useScroll } from './hooks/useScroll'
import { useChat } from './hooks/useChat' import { useChat } from './hooks/useChat'
import { useUsingContext } from './hooks/useUsingContext' import { useUsingContext } from './hooks/useUsingContext'
import HeaderComponent from './components/Header/index.vue' import HeaderComponent from './components/Header/index.vue'
import { HoverButton, SvgIcon } from '@/components/common' import { SvgIcon } from '@/components/common'
import { useBasicLayout } from '@/hooks/useBasicLayout' import { useBasicLayout } from '@/hooks/useBasicLayout'
import { useChatStore, usePromptStore } from '@/store' import { useChatStore, usePromptStore } from '@/store'
import { fetchChatAPIProcess } from '@/api' import { fetchChatAPIProcess } from '@/api'
@ -25,6 +24,7 @@ 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 lodingSpin from '@/components/animation/lodingSpin.vue' import lodingSpin from '@/components/animation/lodingSpin.vue'
import lodingCir from '@/components/animation/lodingCir.vue'
import playing from '@/components/animation/playing.vue' import playing from '@/components/animation/playing.vue'
// import IatRecorder from '@/utils/larRcorder.js' // import IatRecorder from '@/utils/larRcorder.js'
@ -33,7 +33,7 @@ import playing from '@/components/animation/playing.vue'
// let socket = new WebSocket("wss://chat.lihaink.cn/chat"); // let socket = new WebSocket("wss://chat.lihaink.cn/chat");
const maxWeight = ref(1200) const maxWeight = ref(2500)
const messageRef = ref(null) const messageRef = ref(null)
@ -58,32 +58,112 @@ const recordFalg = ref(0)
* stop 停止播放 * stop 停止播放
* re-play 重新播放 * re-play 重新播放
*/ */
const runOrder = (e)=>{ const runOrder = (e) => {
switch(e){ switch (e) {
case 'start': startOrder();break; case 'start': startOrder(); break
case 'end':endOrder();break; case 'end':endOrder(); break
case 're':reOrder(); break
case 'clear':cleatOrder(); break
case 'pause':pauseOrder(); break
case 'play':playOrder(); break
case 'stop':stopOrder(); break
case 're-play':rePlayOrder(); break
default: console.log('无效指令')
} }
} }
const startOrder = ()=>{ const startOrder = () => {
if (recordFalg.value == 0) { if (recordFalg.value == 0) {
RecordXunfei() RecordXunfei()
nowStatus.value = 'run'
if (messageRef.value?.length > 0)
messageRef.value[messageRef.value.length - 1].stopPlay()
setTimeout(() => {
recordFalg.value = 1 recordFalg.value = 1
nowStatus.value = 'record' nowStatus.value = 'record'
}else { }, 1000)
console.log('无效指令'); }
else {
console.log('无效指令')
} }
} }
const endOrder = ()=>{ const endOrder = () => {
if(recordFalg.value==1){ if (recordFalg.value == 1) {
RecordXunfei() RecordXunfei()
recordFalg.value = 0 recordFalg.value = 0
nowStatus.value = 'loding' nowStatus.value = 'loding'
handleSubmit() handleSubmit()
}else {
console.log('无效指令');
} }
else {
console.log('无效指令')
}
}
const reOrder = () => {
if (recordFalg.value == 1) {
RecordXunfei() //
recordFalg.value = 0
nowStatus.value = 'run'
prompt.value = ''
if (messageRef.value?.length > 0)
messageRef.value[messageRef.value.length - 1].stopPlay()
setTimeout(() => {
prompt.value = ''
RecordXunfei() //
setTimeout(() => {
prompt.value = ''
recordFalg.value = 1
nowStatus.value = 'record'
}, 500)
}, 2500)
}
else {
console.log('无效指令')
}
}
const cleatOrder = () => {
if (recordFalg.value == 1) {
RecordXunfei()
recordFalg.value = 0
}
if (messageRef.value?.length > 0)
messageRef.value[messageRef.value.length - 1].stopPlay()
if (socket?.readyState < 2)
socket.close()
chatStore.getChatByUuid(+uuid).length = 0
nowStatus.value = 'input'
}
const pauseOrder = () => {
if (messageRef.value?.length > 0)
messageRef.value[messageRef.value.length - 1].pauseAudio()
else
console.log('无效指令')
}
const playOrder = () => {
if (messageRef.value?.length > 0)
messageRef.value[messageRef.value.length - 1].noPauseAudio()
else
console.log('无效指令')
}
const stopOrder = () => {
if (messageRef.value?.length > 0) {
nowStatus.value = 'input'
messageRef.value[messageRef.value.length - 1].stopPlay()
}
else { console.log('无效指令') }
}
const rePlayOrder = () => {
if (messageRef.value?.length > 0) {
messageRef.value[messageRef.value.length - 1].stopPlay()
messageRef.value[messageRef.value.length - 1].radioPlay()
}
else { console.log('无效指令') }
} }
// uid1 // uid1
@ -140,7 +220,7 @@ const conversationList = computed(() =>
const prompt = ref<string>('') const prompt = ref<string>('')
const loading = ref<boolean>(false) const loading = ref<boolean>(false)
const inputRef = ref<Ref | null>(null) const inputRef = ref<Ref | null>(null)
const nowStatus = ref('input') // , input, loding, record,playing const nowStatus = ref('input') // , input, loding, record,playing, run
const nowStart = ref(true) // , const nowStart = ref(true) // ,
// PromptStore // PromptStore
@ -155,7 +235,13 @@ dataSources.value.forEach((item, index) => {
updateChatSome(+uuid, index, { loading: false }) updateChatSome(+uuid, index, { loading: false })
}) })
function handleSubmit() { const messageUI = useMessage()
async function handleSubmit() {
if (prompt.value.trim() == '') {
nowStatus.value = 'input'
return messageUI.error('不可发送空内容')
}
if (recordFalg.value == 1) { if (recordFalg.value == 1) {
RecordXunfei() RecordXunfei()
recordFalg.value = 0 recordFalg.value = 0
@ -228,6 +314,15 @@ async function onConversation() {
if (lastContext && usingContext.value) if (lastContext && usingContext.value)
options = { ...lastContext } options = { ...lastContext }
let infoList = JSON.parse(JSON.stringify(dataSources.value))
infoList = infoList.slice(-20)
infoList = infoList.map((item: any, index: any) => {
return {
role: index % 2 == 0 ? 'user' : 'assistant',
content: item.text,
}
})
addChat(+uuid, { addChat(+uuid, {
dateTime: new Date().toLocaleString(), dateTime: new Date().toLocaleString(),
text: '思考中', text: '思考中',
@ -240,16 +335,7 @@ async function onConversation() {
}) })
scrollToBottom() scrollToBottom()
let infoList = JSON.parse(JSON.stringify(dataSources.value)) // console.log(dataSources.value)
infoList = infoList.slice(-20)
infoList = infoList.map((item: any, index: any) => {
return {
role: index % 2 == 0 ? 'user' : 'assistant',
content: item.text,
}
})
console.log(dataSources.value)
try { try {
let lastText = '' let lastText = ''
@ -261,10 +347,6 @@ async function onConversation() {
tts: 1, tts: 1,
data: [ data: [
...infoList, ...infoList,
{
role: 'user',
content: message,
},
], ],
})) }))
@ -303,6 +385,7 @@ async function onConversation() {
} }
} }
catch (error) { catch (error) {
console.log(error)
nowStatus.value = 'input' nowStatus.value = 'input'
socket.close() socket.close()
} }
@ -695,7 +778,7 @@ setTimeout(() => {
<!-- <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 v-else-if="nowStatus == 'loding'" key="loding" />
<playing v-else-if="nowStatus == 'playing'" key="playing" /> <playing v-else-if="nowStatus == 'playing'" key="playing" />
<!-- <lodingCir v-else-if="nowStatus=='loding'" key="loding"></lodingCir> --> <lodingCir v-else-if="nowStatus == 'run'" key="run" />
</transition> </transition>
</indexBG> </indexBG>
<transition name="slide-right-to-left"> <transition name="slide-right-to-left">
@ -765,7 +848,7 @@ setTimeout(() => {
</div> </div>
</div> </div>
</main> </main>
<footer :class="footerClass"> <!-- <footer :class="footerClass">
<div <div
class="w-full max-w-screen-xl m-auto" class="w-full max-w-screen-xl m-auto"
:style="{ 'max-width': `${maxWeight}px` }" :style="{ 'max-width': `${maxWeight}px` }"
@ -786,12 +869,12 @@ setTimeout(() => {
<SvgIcon icon="ri:delete-bin-line" /> <SvgIcon icon="ri:delete-bin-line" />
</span> </span>
</HoverButton> </HoverButton>
<!-- <HoverButton v-if="!isMobile" @click="handleExport"> <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="{
@ -801,7 +884,7 @@ setTimeout(() => {
> >
<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"
@ -833,7 +916,7 @@ setTimeout(() => {
</NButton> </NButton>
</div> </div>
</div> </div>
</footer> </footer> -->
</div> </div>
</transition> </transition>
</div> </div>