Browse Source

输入框提示语修改;修改输入非法内容后的逻辑;修改了音频存储文件,主页加入音频控制。

hongxilin/hotfix-20250625101643-手机输入法弹出输入框上浮
宋杰 1 week ago
parent
commit
c16e8870fa
  1. 55
      src/store/audio.js
  2. 41
      src/views/AiEmotion.vue
  3. 30
      src/views/homePage.vue

55
src/store/audio.js

@ -9,7 +9,10 @@ export const useAudioStore = defineStore('audio', {
lastVoiceState: null,
ttsUrl:'',
isNewInstance: false, // 新增是否是新实例的标志
nowSound:''
nowSound:'',
currentAudioUrl: '', // 当前音频URL
isPaused: false, // 是否处于暂停状态
duration: 0 // 音频总时长
}),
actions: {
// 设置音频实例
@ -19,19 +22,67 @@ export const useAudioStore = defineStore('audio', {
// 播放控制
play() {
if (this.soundInstance) {
if (this.isPaused && this.playbackPosition > 0) {
// 从暂停位置继续播放
this.soundInstance.seek(this.playbackPosition)
}
this.soundInstance.play()
this.isPlaying = true
this.isPaused = false
}
},
// 暂停控制
pause() {
if (this.soundInstance) {
if (this.soundInstance && this.isPlaying) {
// 保存当前播放位置
this.playbackPosition = this.soundInstance.seek() || 0
this.soundInstance.pause()
this.isPlaying = false
this.isPaused = true
}
},
// 停止播放
stop() {
if (this.soundInstance) {
this.soundInstance.stop()
this.isPlaying = false
this.isPaused = false
this.playbackPosition = 0
}
},
// 切换播放/暂停
togglePlayPause() {
if (this.isPlaying) {
this.pause()
} else {
this.play()
}
},
// 设置当前音频URL
setCurrentAudioUrl(url) {
if (this.currentAudioUrl !== url) {
// 如果是新的音频,重置播放状态
this.stop()
this.currentAudioUrl = url
this.playbackPosition = 0
this.isPaused = false
}
},
// 语音开关控制
toggleVoice() {
this.isVoiceEnabled = !this.isVoiceEnabled
if (!this.isVoiceEnabled) {
// 关闭语音时停止当前播放
this.stop()
}
},
// 重置音频状态
resetAudioState() {
this.stop()
this.currentAudioUrl = ''
this.ttsUrl = ''
this.soundInstance = null
this.nowSound = ''
}
}
})

41
src/views/AiEmotion.vue

@ -693,8 +693,11 @@ function playAudio(url) {
console.log('开始创建音频实例...');
try {
// URL
audioStore.setCurrentAudioUrl(url);
//
if (audioStore.nowSound) {
if (audioStore.nowSound && audioStore.nowSound.playing()) {
audioStore.nowSound.stop();
}
@ -705,19 +708,35 @@ function playAudio(url) {
format: ['mp3', 'wav'],
onplay: () => {
isAudioPlaying.value = true;
audioStore.isPlaying = true;
console.log('开始播放场景应用语音');
},
onend: () => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
audioStore.isPaused = false;
audioStore.playbackPosition = 0;
console.log('场景应用语音播放结束');
},
onstop: () => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
console.log('场景应用语音播放停止');
},
onpause: () => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
console.log('场景应用语音播放暂停');
},
onerror: (error) => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
console.error('音频播放错误:', error);
},
onload: () => {
//
audioStore.duration = newSound.duration();
console.log('音频加载完成,时长:', audioStore.duration);
}
});
@ -764,11 +783,6 @@ async function handleSendMessage(input) {
if (input.trim()) {
const userMessage = reactive({ sender: 'user', text: input });
messages.value.push(userMessage);
//
isLoading.value = true;
isPageLoaded.value = false;
//
isRotating.value = true;
try {
//
@ -797,6 +811,12 @@ async function handleSendMessage(input) {
if (parsedData && parsedData.market && parsedData.code) {
console.log("工作流接口返回股票信息:", parsedData);
//
isLoading.value = true;
isPageLoaded.value = false;
//
isRotating.value = true;
//
const conclusionParams = {
content: input.trim(),
@ -826,16 +846,19 @@ async function handleSendMessage(input) {
emotionStore.updateActiveStockConclusion(conclusionResponse.data);
}
} else {
// refuse
ElMessage.error(processRefuseMessage(parsedData.refuse));
return; //
}
} catch (error) {
ElMessage.error('请求工作流接口失败,请检查网络连接');
return; //
} finally {
//
//
if (isRotating.value) {
isRotating.value = false;
}
} else {
ElMessage.error(processRefuseMessage(parsedData.refuse));
}
}
}

30
src/views/homePage.vue

@ -46,7 +46,19 @@ const chatStore = useChatStore();
const audioStore = useAudioStore();
const isVoice = computed(() => audioStore.isVoiceEnabled);
const toggleVoice = () => {
if (!audioStore.isVoiceEnabled) {
//
audioStore.toggleVoice();
} else {
// /
if (audioStore.currentAudioUrl || audioStore.ttsUrl) {
// /
audioStore.togglePlayPause();
} else {
//
audioStore.toggleVoice();
}
}
};
// sessionStorage 使 'aifindCow'tab
const activeTab = ref(sessionStorage.getItem("activeTabAI") || "AIchat");
@ -570,7 +582,8 @@ onMounted(async () => {
<!-- AI情绪大模型按钮 -->
<img :src="activeTab === 'AiEmotion' ? emotionButton01 : emotionButton02
" @click="setActiveTab('AiEmotion', 1)" class="action-btn model-btn" alt="AI情绪大模型" />
<img v-if="isVoice" :src="voice" @click="toggleVoice" class="action-btn" />
<img v-if="audioStore.isVoiceEnabled && !audioStore.isPlaying" :src="voice" @click="toggleVoice" class="action-btn" />
<img v-else-if="audioStore.isVoiceEnabled && audioStore.isPlaying" :src="voice" @click="toggleVoice" class="action-btn" style="opacity: 0.7; animation: pulse 1.5s infinite;" />
<img v-else :src="voiceNoActive" @click="toggleVoice" class="action-btn" />
</div>
<img v-if="!chatStore.isLoading" :src="sendBtn" @click="sendMessage" class="action-btn send-btn" />
@ -585,7 +598,7 @@ onMounted(async () => {
<div class="footer-second-line">
<img :src="msgBtn" class="msg-icon" />
<el-input type="textarea" v-model="message" @focus="onFocus" @blur="onBlur"
:autosize="{ minRows: 1, maxRows: 4 }" placeholder="给AI小财神发消息..." class="msg-input"
:autosize="{ minRows: 1, maxRows: 4 }" placeholder="请输入股票名称或股票代码..." class="msg-input"
@keydown.enter.exact.prevent="isLoading ? null : sendMessage()" resize="none">
</el-input>
</div>
@ -949,6 +962,19 @@ body {
margin-right: 5px;
}
/* 音频播放动画 */
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.footer-second-line {
position: relative;
display: flex;

Loading…
Cancel
Save