|
|
@@ -136,23 +136,27 @@
|
|
|
</view>
|
|
|
</scroll-view>
|
|
|
|
|
|
- <!-- 输入区 -->
|
|
|
- <view class="chat-input-area">
|
|
|
- <view class="chat-input-wrap">
|
|
|
- <input class="chat-input" v-model="inputText" placeholder="问我关于家庭和孩子的问题..."
|
|
|
- :disabled="sending" @confirm="sendMessage" confirm-type="send" />
|
|
|
- </view>
|
|
|
- <view class="chat-send-btn" :class="{ 'chat-send-active': inputText.trim() }"
|
|
|
- @click="sendMessage">
|
|
|
- <text class="send-icon">➤</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="chat-disclaimer">本服务为生成内容,结果仅供参考</view>
|
|
|
+<!-- 输入区 -->
|
|
|
+ <view class="chat-input-area">
|
|
|
+ <view class="chat-input-wrap">
|
|
|
+ <input class="chat-input" v-model="inputText" placeholder="问我关于家庭和孩子的问题..."
|
|
|
+ :disabled="sending" @confirm="sendMessage" confirm-type="send" />
|
|
|
+ </view>
|
|
|
+ <view class="chat-voice-btn" :class="{ 'voice-recording': isRecording }" @touchstart="startVoiceRecord" @touchend="stopVoiceRecord">
|
|
|
+ <text class="voice-icon">{{ isRecording ? '🔴' : '🎤' }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="chat-send-btn" :class="{ 'chat-send-active': inputText.trim() }"
|
|
|
+ @click="sendMessage">
|
|
|
+ <text class="send-icon">➤</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="chat-disclaimer">本服务为生成内容,结果仅供参考</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { aiSendMessage, aiGetConversations, aiGetMessages, aiDeleteConversation, aiSendNutritionMessage, aiSendHealthCoachMessage, aiSendHealthButlerMessage, getMyMembership } from '../../utils/api.js'
|
|
|
+import { sttTranscribe } from '../../utils/api.js'
|
|
|
import BaseEmpty from '../../components/BaseEmpty.vue'
|
|
|
import TaskCard from '../../components/AITaskCard.vue'
|
|
|
import config from '@/config.js'
|
|
|
@@ -176,7 +180,9 @@ export default {
|
|
|
recommendations: [],
|
|
|
mascotCode: '',
|
|
|
mascotName: '',
|
|
|
- mascotIcon: ''
|
|
|
+ mascotIcon: '',
|
|
|
+ isRecording: false,
|
|
|
+ recorderManager: null
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
@@ -273,7 +279,36 @@ export default {
|
|
|
goBack() {
|
|
|
uni.navigateBack()
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
+ startVoiceRecord() {
|
|
|
+ if (this.isRecording) return
|
|
|
+ this.recorderManager = uni.getRecorderManager()
|
|
|
+ var self = this
|
|
|
+ this.recorderManager.onStop(function(res) {
|
|
|
+ self.isRecording = false
|
|
|
+ uni.showLoading({ title: '语音识别中...', mask: true })
|
|
|
+ sttTranscribe(res.tempFilePath).then(function(text) {
|
|
|
+ uni.hideLoading()
|
|
|
+ self.inputText = text
|
|
|
+ }).catch(function(err) {
|
|
|
+ uni.hideLoading()
|
|
|
+ uni.showToast({ title: '语音识别失败', icon: 'none' })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.recorderManager.onError(function() {
|
|
|
+ self.isRecording = false
|
|
|
+ uni.showToast({ title: '录音失败', icon: 'none' })
|
|
|
+ })
|
|
|
+ this.recorderManager.start({ duration: 60000, format: 'mp3' })
|
|
|
+ this.isRecording = true
|
|
|
+ },
|
|
|
+
|
|
|
+ stopVoiceRecord() {
|
|
|
+ if (this.recorderManager) {
|
|
|
+ this.recorderManager.stop()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
onTaskAccepted() {
|
|
|
this.loadConversations()
|
|
|
},
|
|
|
@@ -716,7 +751,27 @@ export default {
|
|
|
background: var(--bg, #FFF7ED);
|
|
|
border-radius: 40rpx;
|
|
|
padding: 0 24rpx;
|
|
|
- margin-right: 16rpx;
|
|
|
+ margin-right: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-voice-btn {
|
|
|
+ width: 60rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: var(--border-light, #E2E8F0);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+ margin-right: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-voice-btn.voice-recording {
|
|
|
+ background: #FF6B6B;
|
|
|
+}
|
|
|
+
|
|
|
+.voice-icon {
|
|
|
+ font-size: 28rpx;
|
|
|
}
|
|
|
|
|
|
.chat-input {
|