Files
DLE/frontend/src/components/chat/MessageInput.vue

215 lines
5.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="message-input">
<textarea
v-model="message"
placeholder="Введите сообщение..."
@keydown.enter.prevent="handleEnter"
ref="textareaRef"
:disabled="sending"
></textarea>
<button @click="sendMessage" class="send-button" :disabled="!message.trim() || sending">
<span v-if="sending">Отправка...</span>
<span v-else>Отправить</span>
</button>
</div>
</template>
<script setup>
import { ref, defineEmits, nextTick } from 'vue';
import axios from 'axios';
const props = defineProps({
conversationId: {
type: [Number, String],
required: true,
},
});
const emit = defineEmits(['message-sent']);
const message = ref('');
const sending = ref(false);
const textareaRef = ref(null);
// Обработка нажатия Enter
const handleEnter = (event) => {
// Если нажат Shift+Enter, добавляем перенос строки
if (event.shiftKey) {
return;
}
// Иначе отправляем сообщение
sendMessage();
};
// Отправка сообщения
const sendMessage = async () => {
const messageText = message.value.trim();
if (!messageText) return;
const userMessage = {
id: Date.now(),
content: messageText,
role: auth.isAuthenticated ? 'user' : 'guest',
timestamp: new Date().toISOString()
};
messages.value.push(userMessage);
try {
// Логируем параметры запроса
console.log('Sending message to Ollama:', {
message: messageText,
language: userLanguage.value
});
const response = await axios.post('/api/chat/message', {
message: messageText,
language: userLanguage.value
});
// Логируем ответ от Ollama
console.log('Response from Ollama:', response.data);
// Обработка ответа
messages.value.push({
id: Date.now() + 1,
content: response.data.message,
role: 'assistant',
timestamp: new Date().toISOString()
});
// Очищаем поле ввода
message.value = '';
// Фокусируемся на поле ввода
nextTick(() => {
textareaRef.value.focus();
});
// Уведомляем родительский компонент о новых сообщениях
emit('message-sent', [response.data.userMessage, response.data.aiMessage]);
} catch (error) {
console.error('Ошибка при отправке сообщения:', error);
} finally {
sending.value = false;
}
};
// Сброс поля ввода
const resetInput = () => {
message.value = '';
};
// Экспорт методов для использования в родительском компоненте
defineExpose({
resetInput,
focus: () => textareaRef.value?.focus(),
});
const sendGuestMessage = async (messageText) => {
if (!messageText.trim()) return;
const userMessage = {
id: Date.now(),
content: messageText,
role: 'user',
timestamp: new Date().toISOString(),
isGuest: true
};
// Добавляем сообщение пользователя в локальную историю
messages.value.push(userMessage);
// Сохраняем сообщение в массиве гостевых сообщений
guestMessages.value.push(userMessage);
// Сохраняем гостевые сообщения в localStorage
localStorage.setItem('guestMessages', JSON.stringify(guestMessages.value));
// Очищаем поле ввода
newMessage.value = '';
// Прокрутка вниз
await nextTick();
if (messagesContainer.value) {
messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
}
// Устанавливаем состояние загрузки
isLoading.value = true;
// Вместо отправки запроса к Ollama, отправляем сообщение с кнопками для аутентификации
const authMessage = {
id: Date.now() + 1,
content: 'Чтобы продолжить, пожалуйста, аутентифицируйтесь.',
role: 'assistant',
timestamp: new Date().toISOString(),
isGuest: true,
showAuthOptions: true // Указываем, что нужно показать кнопки аутентификации
};
messages.value.push(authMessage);
guestMessages.value.push(authMessage);
localStorage.setItem('guestMessages', JSON.stringify(guestMessages.value));
// Прокрутка вниз
await nextTick();
if (messagesContainer.value) {
messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
}
isLoading.value = false;
};
</script>
<style scoped>
.message-input {
display: flex;
padding: 1rem;
border-top: 1px solid #e0e0e0;
background-color: #fff;
}
textarea {
flex: 1;
min-height: 40px;
max-height: 120px;
padding: 0.75rem;
border: 1px solid #e0e0e0;
border-radius: 4px;
resize: none;
font-family: inherit;
font-size: 0.9rem;
line-height: 1.4;
}
textarea:focus {
outline: none;
border-color: #4caf50;
box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2);
}
.send-button {
margin-left: 0.5rem;
padding: 0 1rem;
height: 40px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
transition: background-color 0.2s;
}
.send-button:hover:not(:disabled) {
background-color: #43a047;
}
.send-button:disabled {
background-color: #9e9e9e;
cursor: not-allowed;
}
</style>