// static/js/chat.js new Vue({ el: '#chat-app', delimiters: ['[[', ']]'], data() { return { socket: null, messages: [], newMessage: '', status: '', // 用于显示“聆听中...”或“思考中...” isRecording: false, recognition: null }; }, created() { this.initSocket(); this.initSpeechRecognition(); this.startLive(); // 页面加载后自动启动 live 模式 }, methods: { initSocket() { // 初始化 SocketIO 连接 this.socket = io.connect('http://' + document.domain + ':' + location.port + '/'); this.socket.on('connect', () => { console.log('Connected to SocketIO server'); }); this.socket.on('receive_message', (data) => { this.addMessage(data.type, data.content, data.username, data.timetext); }); this.socket.on('load_messages', (data) => { data.forEach(message => { this.addMessage(message.type, message.content, message.username, message.timetext); }); }); this.socket.on('disconnect', () => { console.log('Disconnected from SocketIO server'); }); }, initSpeechRecognition() { if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) { const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; this.recognition = new SpeechRecognition(); this.recognition.lang = 'zh-CN'; this.recognition.interimResults = false; this.recognition.maxAlternatives = 1; this.recognition.onstart = () => { this.isRecording = true; this.status = '聆听中...'; this.$set(this, 'recordIconSrc', '/static/images/recording.png'); }; this.recognition.onresult = (event) => { const transcript = event.results[0][0].transcript; this.addMessage('user', transcript, '您'); this.socket.emit('send_message', { username: '您', message: transcript, type: 'user' }); this.status = '思考中...'; setTimeout(() => { this.status = ''; }, 2000); }; this.recognition.onerror = (event) => { console.error('语音识别错误:', event.error); this.status = '语音识别失败'; this.isRecording = false; this.$set(this, 'recordIconSrc', '/static/images/record.png'); }; this.recognition.onend = () => { this.isRecording = false; this.$set(this, 'recordIconSrc', '/static/images/record.png'); }; } else { alert('当前浏览器不支持语音识别功能'); } }, toggleChat() { const chatContainer = document.getElementById('chat-container'); const toggleButton = document.getElementById('toggle-chat'); if (chatContainer.classList.contains('hidden')) { chatContainer.classList.remove('hidden'); toggleButton.textContent = '关闭聊天'; } else { chatContainer.classList.add('hidden'); toggleButton.textContent = '打开聊天'; } }, toggleRecording() { if (this.recognition) { if (!this.isRecording) { this.recognition.start(); } else { this.recognition.stop(); } } }, sendMessage() { const message = this.newMessage.trim(); if (message === '') return; this.addMessage('user', message, '您'); this.socket.emit('send_message', { username: '您', message: message, type: 'user' }); this.newMessage = ''; this.status = '思考中...'; setTimeout(() => { this.status = ''; }, 2000); }, addMessage(type, content, username, timestamp) { const message = { type, content, username, timetext: timestamp }; this.messages.push(message); // 只保留最近三条消息 if (this.messages.length > 3) { this.messages.shift(); } // 滚动到最新消息 this.$nextTick(() => { const messagesDiv = document.getElementById('messages'); if (messagesDiv) { messagesDiv.scrollTop = messagesDiv.scrollHeight; } }); }, getCurrentTime() { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, startLive() { // 调用启动 live 模式的 API fetch('/api/start-live', { method: 'POST' }) .then(response => response.json()) .then(data => { if (data.result === 'successful') { this.$notify({ title: '成功', message: '已开启 live 模式!', type: 'success', }); } else { this.$notify({ title: '失败', message: data.message || '启动 live 模式失败', type: 'error', }); } }) .catch(error => { console.error('启动 live 模式时出错:', error); this.$notify({ title: '错误', message: '启动 live 模式时出错', type: 'error', }); }); }, stopLive() { // 调用停止 live 模式的 API fetch('/api/stop-live', { method: 'POST' }) .then(response => response.json()) .then(data => { if (data.result === 'successful') { this.$notify({ title: '成功', message: '已关闭 live 模式!', type: 'success', }); } else { this.$notify({ title: '失败', message: data.message || '停止 live 模式失败', type: 'error', }); } }) .catch(error => { console.error('停止 live 模式时出错:', error); this.$notify({ title: '错误', message: '停止 live 模式时出错', type: 'error', }); }); }}})