ваше сообщение коммита

This commit is contained in:
2025-04-10 18:27:06 +03:00
parent 70c0a50c44
commit 4d8ec5c914
11 changed files with 979 additions and 482 deletions

View File

@@ -1,68 +1,135 @@
<template>
<div class="telegram-connect">
<p>Подключите свой аккаунт Telegram для быстрой авторизации.</p>
<button @click="connectTelegram" class="connect-button">
<span class="telegram-icon">📱</span> Подключить Telegram
</button>
<div v-if="loading" class="loading">Загрузка...</div>
<div v-if="!showQR" class="intro">
<p>Подключите свой аккаунт Telegram для быстрой авторизации</p>
<button @click="startConnection" class="connect-button" :disabled="loading">
<span class="telegram-icon">📱</span>
{{ loading ? 'Загрузка...' : 'Подключить Telegram' }}
</button>
</div>
<div v-else class="qr-section">
<p>Отсканируйте QR-код в приложении Telegram</p>
<div class="qr-container" v-html="qrCode"></div>
<p class="or-divider">или</p>
<a :href="botLink" target="_blank" class="bot-link">
Открыть бота в Telegram
</a>
<button @click="resetConnection" class="reset-button">
Отмена
</button>
</div>
<div v-if="error" class="error">{{ error }}</div>
<div v-if="success" class="success">{{ success }}</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
import { ref, onMounted, onUnmounted } from 'vue';
import axios from '@/api/axios';
import { useAuth } from '@/composables/useAuth';
import QRCode from 'qrcode';
const emit = defineEmits(['close']);
const { linkIdentity } = useAuth();
const loading = ref(false);
const error = ref('');
const success = ref('');
const isConnecting = ref(false);
const showQR = ref(false);
const qrCode = ref('');
const botLink = ref('');
const pollInterval = ref(null);
const connectionToken = ref('');
async function connectTelegram() {
const startConnection = async () => {
try {
loading.value = true;
error.value = '';
success.value = '';
// Запрос на получение ссылки для авторизации через Telegram
const response = await axios.get('/api/auth/telegram', {
withCredentials: true
});
const response = await axios.post('/api/auth/telegram/start-connection');
if (response.data.error) {
error.value = `Ошибка при подключении Telegram: ${response.data.error}`;
return;
}
if (response.data.authUrl) {
success.value = 'Перейдите по ссылке для авторизации через Telegram';
window.open(response.data.authUrl, '_blank');
if (response.data.success) {
connectionToken.value = response.data.token;
botLink.value = `https://t.me/${response.data.botUsername}?start=${connectionToken.value}`;
// Генерируем QR-код
const qr = await QRCode.toDataURL(botLink.value);
qrCode.value = `<img src="${qr}" alt="Telegram QR Code" />`;
showQR.value = true;
startPolling();
} else {
error.value = 'Не удалось получить ссылку для авторизации';
error.value = response.data.error || 'Не удалось начать процесс подключения';
}
} catch (err) {
console.error('Error connecting Telegram:', err);
error.value = 'Ошибка при подключении Telegram';
error.value = err.response?.data?.error || 'Ошибка при подключении Telegram';
} finally {
loading.value = false;
}
}
};
const checkConnection = async () => {
try {
const response = await axios.post('/api/auth/telegram/check-connection', {
token: connectionToken.value
});
if (response.data.success && response.data.telegramId) {
// Связываем Telegram с текущим пользователем
await linkIdentity('telegram', response.data.telegramId);
stopPolling();
emit('close');
}
} catch (error) {
console.error('Error checking connection:', error);
}
};
const startPolling = () => {
pollInterval.value = setInterval(checkConnection, 2000);
};
const stopPolling = () => {
if (pollInterval.value) {
clearInterval(pollInterval.value);
pollInterval.value = null;
}
};
const resetConnection = () => {
stopPolling();
showQR.value = false;
error.value = '';
qrCode.value = '';
botLink.value = '';
connectionToken.value = '';
};
onUnmounted(() => {
stopPolling();
});
</script>
<style scoped>
.telegram-connect {
padding: 20px;
max-width: 400px;
}
.intro,
.qr-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
text-align: center;
}
.connect-button {
display: flex;
align-items: center;
justify-content: center;
padding: 10px 15px;
padding: 10px 20px;
background-color: #0088cc;
color: white;
border: none;
@@ -72,7 +139,7 @@ async function connectTelegram() {
transition: background-color 0.2s;
}
.connect-button:hover {
.connect-button:hover:not(:disabled) {
background-color: #0077b5;
}
@@ -81,23 +148,60 @@ async function connectTelegram() {
font-size: 18px;
}
.loading, .error, .success {
.qr-container {
background: white;
padding: 10px;
border-radius: 4px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.loading {
background-color: #f8f9fa;
.qr-container img {
max-width: 200px;
height: auto;
}
.or-divider {
color: #666;
margin: 10px 0;
}
.bot-link {
color: #0088cc;
text-decoration: none;
padding: 8px 16px;
border: 1px solid #0088cc;
border-radius: 4px;
transition: all 0.2s;
}
.bot-link:hover {
background-color: #0088cc;
color: white;
}
.reset-button {
padding: 8px 16px;
background-color: #e2e8f0;
color: #4a5568;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}
.reset-button:hover {
background-color: #cbd5e0;
}
.error {
background-color: #f8d7da;
color: #721c24;
color: #e53e3e;
margin-top: 10px;
text-align: center;
}
.success {
background-color: #d4edda;
color: #155724;
button:disabled {
opacity: 0.7;
cursor: not-allowed;
}
</style>