feat(AI): 优化消息组件和语音输入功能

- 修改消息组件,仅在非思考模式下显示消息文本
- 增加语音模式下的文本输入框- 优化语音录音和识别逻辑
- 更新思考模式的处理流程
- 调整界面样式,增加禁用状态的录音按钮
This commit is contained in:
陈昱达
2025-06-10 13:30:05 +08:00
parent fd43fae0f7
commit 84ea21ea1d
2 changed files with 35 additions and 7 deletions

View File

@@ -17,7 +17,7 @@
<!--开启思考-->
<p v-html="md.render(message.think)" v-if="message.think && message.showThink" class="thinkText" />
</span>
<div>
<div v-if='!message.isThink '>
<p v-html="md.render(message.text)" v-if="message.text "></p>
<span class="speakLoadingToast pv10" v-else-if='!message.text && !thinkOk'>
<van-loading type="spinner" color="#2e5ca9" size="20px" v-if="!message.text" />

View File

@@ -12,6 +12,11 @@
<van-icon name="upgrade" size="2em" @click="scrollToTop" />
</div>
</main>
<div v-if='isVoiceMode && newMessage' class='isVoiceModeText'>
<textarea class="textarea" placeholder="请输入内容" v-model='newMessage' ></textarea>
</div>
<section class="section">
<button @click="searchInternet" :class="{ active: isSearching }">
<svg-icon icon-class="earth" class-name="chat-icon"></svg-icon>
@@ -37,6 +42,7 @@
@keyup.enter="sendMessage"
/>
<div v-else class="voice-hint-container"
:class="{disabled:messageStatus === 'send' }"
@mousedown="startRecording"
@selectstart="() => false"
@mouseup="stopRecording"
@@ -186,6 +192,7 @@ export default {
this.scrollPosition = messageArea.scrollTop
},
async startRecording() {
if(this.messageStatus === 'send') return
if (this.isRecognizing) return
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
@@ -221,7 +228,7 @@ export default {
if (text) {
this.newMessage = text
this.messageStatus = 'stop'
this.sendMessage()
// this.sendMessage()
}
} catch (error) {
console.error('语音识别失败:', error)
@@ -322,8 +329,12 @@ export default {
}
},
updateConversationState(data) {
this.conversationId = data.conversation_id || this.conversationId
if (data.answer && data.answer.indexOf('withTo') !== -1) {
this.conversationId = data.conversation_id || conversationId.value
if (data.answer && data.answer.indexOf('<think>') !== -1) {
this.isThink = true
}
if (data.answer && data.answer.indexOf('</think>') !== -1) {
this.isThink = false
}
},
@@ -368,6 +379,7 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
background: #f7f8fa;
position: relative;
.button-container {
position: fixed;
bottom: 120px;
@@ -384,7 +396,19 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
}
}
}
.isVoiceModeText{
display: flex;
textarea{
flex:1;
max-height: 80px;
resize: none;
background: #fff;
outline: none;
overflow-y: auto;
padding: 10px;
border: none;
}
}
.section {
font-size: 13px;
display: flex;
@@ -447,6 +471,7 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
background-color: #eaeaea;
}
.waveform {
display: flex;
align-items: flex-end;
@@ -454,7 +479,10 @@ $primary-trans-color: rgba(135, 162, 208, 0.5);
//height: 30px;
//width: 60px;
gap: 2px;
&.disabled{
cursor: not-allowed;
background: red;
}
&.active .bar {
animation: wave-animation 1s infinite ease-in-out;
}