mass refactor
This commit is contained in:
@@ -24,8 +24,8 @@ export class ChatService {
|
||||
SELECT
|
||||
m.*,
|
||||
CASE
|
||||
WHEN m.user1_id = $1 THEN m.user2_id
|
||||
ELSE m.user1_id
|
||||
WHEN m.user_id_1 = $1 THEN m.user_id_2
|
||||
ELSE m.user_id_1
|
||||
END as other_user_id,
|
||||
p.name as other_user_name,
|
||||
p.photos as other_user_photos,
|
||||
@@ -42,8 +42,8 @@ export class ChatService {
|
||||
FROM matches m
|
||||
LEFT JOIN profiles p ON (
|
||||
CASE
|
||||
WHEN m.user1_id = $1 THEN p.user_id = m.user2_id
|
||||
ELSE p.user_id = m.user1_id
|
||||
WHEN m.user_id_1 = $1 THEN p.user_id = m.user_id_2
|
||||
ELSE p.user_id = m.user_id_1
|
||||
END
|
||||
)
|
||||
LEFT JOIN messages msg ON msg.id = (
|
||||
@@ -52,10 +52,10 @@ export class ChatService {
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE (m.user1_id = $1 OR m.user2_id = $1)
|
||||
AND m.status = 'active'
|
||||
WHERE (m.user_id_1 = $1 OR m.user_id_2 = $1)
|
||||
AND m.is_active = true
|
||||
ORDER BY
|
||||
CASE WHEN msg.created_at IS NULL THEN m.matched_at ELSE msg.created_at END DESC
|
||||
CASE WHEN msg.created_at IS NULL THEN m.created_at ELSE msg.created_at END DESC
|
||||
`, [userId]);
|
||||
|
||||
return result.rows.map((row: any) => ({
|
||||
@@ -91,7 +91,6 @@ export class ChatService {
|
||||
senderId: row.sender_id,
|
||||
content: row.content,
|
||||
messageType: row.message_type,
|
||||
fileId: row.file_id,
|
||||
isRead: row.is_read,
|
||||
createdAt: new Date(row.created_at)
|
||||
})).reverse(); // Возвращаем в хронологическом порядке
|
||||
@@ -106,8 +105,7 @@ export class ChatService {
|
||||
matchId: string,
|
||||
senderTelegramId: string,
|
||||
content: string,
|
||||
messageType: 'text' | 'photo' | 'video' | 'voice' | 'sticker' | 'gif' = 'text',
|
||||
fileId?: string
|
||||
messageType: 'text' | 'photo' | 'video' | 'voice' | 'sticker' | 'gif' = 'text'
|
||||
): Promise<Message | null> {
|
||||
try {
|
||||
// Получаем senderId по telegramId
|
||||
@@ -119,7 +117,7 @@ export class ChatService {
|
||||
// Проверяем, что матч активен и пользователь является участником
|
||||
const matchResult = await query(`
|
||||
SELECT * FROM matches
|
||||
WHERE id = $1 AND (user1_id = $2 OR user2_id = $2) AND status = 'active'
|
||||
WHERE id = $1 AND (user_id_1 = $2 OR user_id_2 = $2) AND is_active = true
|
||||
`, [matchId, senderId]);
|
||||
|
||||
if (matchResult.rows.length === 0) {
|
||||
@@ -130,9 +128,9 @@ export class ChatService {
|
||||
|
||||
// Создаем сообщение
|
||||
await query(`
|
||||
INSERT INTO messages (id, match_id, sender_id, content, message_type, file_id, is_read, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, false, CURRENT_TIMESTAMP)
|
||||
`, [messageId, matchId, senderId, content, messageType, fileId]);
|
||||
INSERT INTO messages (id, match_id, sender_id, content, message_type, is_read, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5, false, CURRENT_TIMESTAMP)
|
||||
`, [messageId, matchId, senderId, content, messageType]);
|
||||
|
||||
// Обновляем время последнего сообщения в матче
|
||||
await query(`
|
||||
@@ -157,7 +155,6 @@ export class ChatService {
|
||||
senderId: row.sender_id,
|
||||
content: row.content,
|
||||
messageType: row.message_type,
|
||||
fileId: row.file_id,
|
||||
isRead: row.is_read,
|
||||
createdAt: new Date(row.created_at)
|
||||
});
|
||||
@@ -197,11 +194,11 @@ export class ChatService {
|
||||
SELECT
|
||||
m.*,
|
||||
CASE
|
||||
WHEN m.user1_id = $2 THEN m.user2_id
|
||||
ELSE m.user1_id
|
||||
WHEN m.user_id_1 = $2 THEN m.user_id_2
|
||||
ELSE m.user_id_1
|
||||
END as other_user_id
|
||||
FROM matches m
|
||||
WHERE m.id = $1 AND (m.user1_id = $2 OR m.user2_id = $2) AND m.status = 'active'
|
||||
WHERE m.id = $1 AND (m.user_id_1 = $2 OR m.user_id_2 = $2) AND m.is_active = true
|
||||
`, [matchId, userId]);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
@@ -234,7 +231,7 @@ export class ChatService {
|
||||
// Проверяем, что пользователь является участником матча
|
||||
const matchResult = await query(`
|
||||
SELECT * FROM matches
|
||||
WHERE id = $1 AND (user1_id = $2 OR user2_id = $2) AND status = 'active'
|
||||
WHERE id = $1 AND (user_id_1 = $2 OR user_id_2 = $2) AND is_active = true
|
||||
`, [matchId, userId]);
|
||||
|
||||
if (matchResult.rows.length === 0) {
|
||||
@@ -244,9 +241,11 @@ export class ChatService {
|
||||
// Помечаем матч как неактивный
|
||||
await query(`
|
||||
UPDATE matches
|
||||
SET status = 'unmatched'
|
||||
SET is_active = false,
|
||||
unmatched_at = NOW(),
|
||||
unmatched_by = $2
|
||||
WHERE id = $1
|
||||
`, [matchId]);
|
||||
`, [matchId, userId]);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
|
||||
@@ -70,7 +70,7 @@ export class MatchingService {
|
||||
await transaction(async (client) => {
|
||||
// Создаем свайп
|
||||
await client.query(`
|
||||
INSERT INTO swipes (id, swiper_id, swiped_id, direction, created_at)
|
||||
INSERT INTO swipes (id, user_id, target_user_id, direction, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
`, [swipeId, userId, targetUserId, direction, new Date()]);
|
||||
|
||||
@@ -78,14 +78,14 @@ export class MatchingService {
|
||||
if (swipeType === 'like' || swipeType === 'superlike') {
|
||||
const reciprocalSwipe = await client.query(`
|
||||
SELECT * FROM swipes
|
||||
WHERE swiper_id = $1 AND swiped_id = $2 AND direction IN ('like', 'super')
|
||||
WHERE swiper_id = $1 AND swiped_id = $2 AND direction IN ('right', 'super')
|
||||
`, [targetUserId, userId]);
|
||||
|
||||
if (reciprocalSwipe.rows.length > 0) {
|
||||
// Проверяем, что матч еще не существует
|
||||
const existingMatch = await client.query(`
|
||||
SELECT * FROM matches
|
||||
WHERE (user1_id = $1 AND user2_id = $2) OR (user1_id = $2 AND user2_id = $1)
|
||||
WHERE (user_id_1 = $1 AND user_id_2 = $2) OR (user_id_1 = $2 AND user_id_2 = $1)
|
||||
`, [userId, targetUserId]);
|
||||
|
||||
if (existingMatch.rows.length === 0) {
|
||||
@@ -98,9 +98,9 @@ export class MatchingService {
|
||||
|
||||
// Создаем матч
|
||||
await client.query(`
|
||||
INSERT INTO matches (id, user1_id, user2_id, matched_at, status)
|
||||
INSERT INTO matches (id, user_id_1, user_id_2, created_at, is_active)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
`, [matchId, user1Id, user2Id, new Date(), 'active']);
|
||||
`, [matchId, user1Id, user2Id, new Date(), true]);
|
||||
|
||||
match = new Match({
|
||||
id: matchId,
|
||||
@@ -143,7 +143,7 @@ export class MatchingService {
|
||||
async getSwipe(userId: string, targetUserId: string): Promise<Swipe | null> {
|
||||
const result = await query(`
|
||||
SELECT * FROM swipes
|
||||
WHERE swiper_id = $1 AND swiped_id = $2
|
||||
WHERE user_id = $1 AND target_user_id = $2
|
||||
`, [userId, targetUserId]);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
@@ -163,8 +163,8 @@ export class MatchingService {
|
||||
|
||||
const result = await query(`
|
||||
SELECT * FROM matches
|
||||
WHERE (user1_id = $1 OR user2_id = $1) AND status = 'active'
|
||||
ORDER BY matched_at DESC
|
||||
WHERE (user_id_1 = $1 OR user_id_2 = $1) AND is_active = true
|
||||
ORDER BY created_at DESC
|
||||
LIMIT $2
|
||||
`, [userId, limit]);
|
||||
|
||||
@@ -217,7 +217,7 @@ export class MatchingService {
|
||||
async getRecentLikes(userId: string, limit: number = 20): Promise<Swipe[]> {
|
||||
const result = await query(`
|
||||
SELECT * FROM swipes
|
||||
WHERE swiped_id = $1 AND direction IN ('like', 'super') AND is_match = false
|
||||
WHERE target_user_id = $1 AND direction IN ('right', 'super') AND is_match = false
|
||||
ORDER BY created_at DESC
|
||||
LIMIT $2
|
||||
`, [userId, limit]);
|
||||
@@ -311,11 +311,11 @@ export class MatchingService {
|
||||
private mapEntityToMatch(entity: any): Match {
|
||||
return new Match({
|
||||
id: entity.id,
|
||||
userId1: entity.user1_id,
|
||||
userId2: entity.user2_id,
|
||||
createdAt: entity.matched_at || entity.created_at,
|
||||
userId1: entity.user_id_1,
|
||||
userId2: entity.user_id_2,
|
||||
createdAt: entity.created_at,
|
||||
lastMessageAt: entity.last_message_at,
|
||||
isActive: entity.status === 'active',
|
||||
isActive: entity.is_active === true,
|
||||
isSuperMatch: false, // Определяется из swipes если нужно
|
||||
unreadCount1: 0,
|
||||
unreadCount2: 0
|
||||
@@ -329,8 +329,8 @@ export class MatchingService {
|
||||
FROM swipes s1
|
||||
JOIN swipes s2 ON s1.user_id = s2.target_user_id AND s1.target_user_id = s2.user_id
|
||||
WHERE s1.user_id = $1
|
||||
AND s1.type IN ('like', 'superlike')
|
||||
AND s2.type IN ('like', 'superlike')
|
||||
AND s1.direction IN ('right', 'super')
|
||||
AND s2.direction IN ('right', 'super')
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM matches m
|
||||
WHERE (m.user_id_1 = s1.user_id AND m.user_id_2 = s1.target_user_id)
|
||||
@@ -342,7 +342,7 @@ export class MatchingService {
|
||||
}
|
||||
|
||||
// Получить следующего кандидата для просмотра
|
||||
async getNextCandidate(telegramId: string): Promise<Profile | null> {
|
||||
async getNextCandidate(telegramId: string, isNewUser: boolean = false): Promise<Profile | null> {
|
||||
// Сначала получаем профиль пользователя по telegramId
|
||||
const userProfile = await this.profileService.getProfileByTelegramId(telegramId);
|
||||
if (!userProfile) {
|
||||
@@ -354,18 +354,26 @@ export class MatchingService {
|
||||
|
||||
// Получаем список уже просмотренных пользователей
|
||||
const viewedUsers = await query(`
|
||||
SELECT DISTINCT swiped_id
|
||||
SELECT DISTINCT target_user_id
|
||||
FROM swipes
|
||||
WHERE swiper_id = $1
|
||||
WHERE user_id = $1
|
||||
`, [userId]);
|
||||
|
||||
const viewedUserIds = viewedUsers.rows.map((row: any) => row.swiped_id);
|
||||
const viewedUserIds = viewedUsers.rows.map((row: any) => row.target_user_id);
|
||||
viewedUserIds.push(userId); // Исключаем самого себя
|
||||
|
||||
// Формируем условие для исключения уже просмотренных
|
||||
const excludeCondition = viewedUserIds.length > 0
|
||||
? `AND p.user_id NOT IN (${viewedUserIds.map((_: any, i: number) => `$${i + 2}`).join(', ')})`
|
||||
: '';
|
||||
// Если это новый пользователь или у пользователя мало просмотренных профилей,
|
||||
// показываем всех пользователей по очереди (исключая только себя)
|
||||
let excludeCondition = '';
|
||||
|
||||
if (!isNewUser) {
|
||||
excludeCondition = viewedUserIds.length > 0
|
||||
? `AND p.user_id NOT IN (${viewedUserIds.map((_: any, i: number) => `$${i + 2}`).join(', ')})`
|
||||
: '';
|
||||
} else {
|
||||
// Для новых пользователей исключаем только себя
|
||||
excludeCondition = `AND p.user_id != $2`;
|
||||
}
|
||||
|
||||
// Ищем подходящих кандидатов
|
||||
const candidateQuery = `
|
||||
|
||||
@@ -233,8 +233,8 @@ export class NotificationService {
|
||||
SELECT m.created_at
|
||||
FROM messages m
|
||||
JOIN matches mt ON m.match_id = mt.id
|
||||
WHERE (mt.user1_id = $1 OR mt.user2_id = $1)
|
||||
AND (mt.user1_id = $2 OR mt.user2_id = $2)
|
||||
WHERE (mt.user_id_1 = $1 OR mt.user_id_2 = $1)
|
||||
AND (mt.user_id_1 = $2 OR mt.user_id_2 = $2)
|
||||
AND m.sender_id = $1
|
||||
ORDER BY m.created_at DESC
|
||||
LIMIT 1
|
||||
@@ -347,10 +347,33 @@ export class NotificationService {
|
||||
// Планировщик уведомлений (вызывается периодически)
|
||||
async processScheduledNotifications(): Promise<void> {
|
||||
try {
|
||||
// Проверим, существует ли таблица scheduled_notifications
|
||||
const tableCheck = await query(`
|
||||
SELECT EXISTS (
|
||||
SELECT FROM information_schema.tables
|
||||
WHERE table_name = 'scheduled_notifications'
|
||||
) as exists
|
||||
`);
|
||||
|
||||
if (!tableCheck.rows[0].exists) {
|
||||
// Если таблицы нет, создаем её
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS scheduled_notifications (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID REFERENCES users(id),
|
||||
type VARCHAR(50) NOT NULL,
|
||||
data JSONB,
|
||||
scheduled_at TIMESTAMP NOT NULL,
|
||||
is_processed BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
// Получаем запланированные уведомления
|
||||
const result = await query(`
|
||||
SELECT * FROM scheduled_notifications
|
||||
WHERE scheduled_at <= $1 AND processed = false
|
||||
WHERE scheduled_at <= $1 AND is_processed = false
|
||||
ORDER BY scheduled_at ASC
|
||||
LIMIT 100
|
||||
`, [new Date()]);
|
||||
@@ -370,7 +393,7 @@ export class NotificationService {
|
||||
|
||||
// Отмечаем как обработанное
|
||||
await query(
|
||||
'UPDATE scheduled_notifications SET processed = true WHERE id = $1',
|
||||
'UPDATE scheduled_notifications SET is_processed = true WHERE id = $1',
|
||||
[notification.id]
|
||||
);
|
||||
} catch (error) {
|
||||
|
||||
@@ -49,18 +49,15 @@ export class ProfileService {
|
||||
// Сохранение в базу данных
|
||||
await query(`
|
||||
INSERT INTO profiles (
|
||||
id, user_id, name, age, gender, looking_for, bio, photos, interests,
|
||||
hobbies, location, education, occupation, height, religion, dating_goal,
|
||||
latitude, longitude, verification_status, is_active, is_visible,
|
||||
created_at, updated_at
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23)
|
||||
id, user_id, name, age, gender, interested_in, bio, photos,
|
||||
city, education, job, height, religion, dating_goal,
|
||||
is_verified, is_visible, created_at, updated_at
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
|
||||
`, [
|
||||
profileId, userId, profile.name, profile.age, profile.gender, profile.interestedIn,
|
||||
profile.bio, profile.photos, profile.interests, profile.hobbies,
|
||||
profile.city, profile.education, profile.job, profile.height,
|
||||
profile.religion, profile.datingGoal,
|
||||
profile.location?.latitude, profile.location?.longitude,
|
||||
'unverified', true, profile.isVisible, profile.createdAt, profile.updatedAt
|
||||
profile.bio, JSON.stringify(profile.photos), profile.city, profile.education, profile.job,
|
||||
profile.height, profile.religion, profile.datingGoal,
|
||||
profile.isVerified, profile.isVisible, profile.createdAt, profile.updatedAt
|
||||
]);
|
||||
|
||||
return profile;
|
||||
@@ -137,8 +134,7 @@ export class ProfileService {
|
||||
ON CONFLICT (telegram_id) DO UPDATE SET
|
||||
username = EXCLUDED.username,
|
||||
first_name = EXCLUDED.first_name,
|
||||
last_name = EXCLUDED.last_name,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
last_name = EXCLUDED.last_name
|
||||
RETURNING id
|
||||
`, [
|
||||
parseInt(telegramId),
|
||||
@@ -177,12 +173,8 @@ export class ProfileService {
|
||||
updateValues.push(value);
|
||||
break;
|
||||
case 'location':
|
||||
if (value && typeof value === 'object' && 'latitude' in value) {
|
||||
updateFields.push(`latitude = $${paramIndex++}`);
|
||||
updateValues.push(value.latitude);
|
||||
updateFields.push(`longitude = $${paramIndex++}`);
|
||||
updateValues.push(value.longitude);
|
||||
}
|
||||
// Пропускаем обработку местоположения, так как колонки location нет
|
||||
console.log('Skipping location update - column does not exist');
|
||||
break;
|
||||
case 'searchPreferences':
|
||||
// Поля search preferences больше не хранятся в БД, пропускаем
|
||||
@@ -339,8 +331,8 @@ export class ProfileService {
|
||||
const [likesResult, matchesResult, likesReceivedResult] = await Promise.all([
|
||||
query('SELECT COUNT(*) as count FROM swipes WHERE swiper_id = $1 AND direction IN ($2, $3)',
|
||||
[userId, 'like', 'super']),
|
||||
query('SELECT COUNT(*) as count FROM matches WHERE (user1_id = $1 OR user2_id = $1) AND status = $2',
|
||||
[userId, 'active']),
|
||||
query('SELECT COUNT(*) as count FROM matches WHERE (user_id_1 = $1 OR user_id_2 = $1) AND is_active = true',
|
||||
[userId]),
|
||||
query('SELECT COUNT(*) as count FROM swipes WHERE swiped_id = $1 AND direction IN ($2, $3)',
|
||||
[userId, 'like', 'super'])
|
||||
]);
|
||||
@@ -424,6 +416,27 @@ export class ProfileService {
|
||||
return [];
|
||||
};
|
||||
|
||||
// Функция для парсинга JSON полей
|
||||
const parseJsonField = (jsonField: any): any[] => {
|
||||
if (!jsonField) return [];
|
||||
|
||||
// Если это строка, пробуем распарсить JSON
|
||||
if (typeof jsonField === 'string') {
|
||||
try {
|
||||
const parsed = JSON.parse(jsonField);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch (e) {
|
||||
console.error('Error parsing JSON field:', e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Если это уже массив, возвращаем как есть
|
||||
if (Array.isArray(jsonField)) return jsonField;
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
return new Profile({
|
||||
userId: entity.user_id,
|
||||
name: entity.name,
|
||||
@@ -431,8 +444,8 @@ export class ProfileService {
|
||||
gender: entity.gender,
|
||||
interestedIn: entity.looking_for,
|
||||
bio: entity.bio,
|
||||
photos: parsePostgresArray(entity.photos),
|
||||
interests: parsePostgresArray(entity.interests),
|
||||
photos: parseJsonField(entity.photos),
|
||||
interests: parseJsonField(entity.interests),
|
||||
hobbies: entity.hobbies,
|
||||
city: entity.location || entity.city,
|
||||
education: entity.education,
|
||||
@@ -441,14 +454,11 @@ export class ProfileService {
|
||||
religion: entity.religion,
|
||||
datingGoal: entity.dating_goal,
|
||||
lifestyle: {
|
||||
smoking: entity.smoking,
|
||||
drinking: entity.drinking,
|
||||
kids: entity.has_kids
|
||||
},
|
||||
location: entity.latitude && entity.longitude ? {
|
||||
latitude: entity.latitude,
|
||||
longitude: entity.longitude
|
||||
} : undefined,
|
||||
smoking: undefined,
|
||||
drinking: undefined,
|
||||
kids: undefined
|
||||
}, // Пропускаем lifestyle, так как этих колонок нет
|
||||
location: undefined, // Пропускаем location, так как этих колонок нет
|
||||
searchPreferences: {
|
||||
minAge: 18,
|
||||
maxAge: 50,
|
||||
@@ -466,9 +476,10 @@ export class ProfileService {
|
||||
// Специальные случаи для некоторых полей
|
||||
const specialCases: { [key: string]: string } = {
|
||||
'interestedIn': 'looking_for',
|
||||
'job': 'occupation',
|
||||
'city': 'location',
|
||||
// Удалили 'job': 'occupation', так как колонка occupation не существует
|
||||
// Вместо этого используем job
|
||||
'datingGoal': 'dating_goal'
|
||||
// Удалили 'city': 'location', так как колонка location не существует
|
||||
};
|
||||
|
||||
if (specialCases[str]) {
|
||||
@@ -484,7 +495,7 @@ export class ProfileService {
|
||||
await transaction(async (client) => {
|
||||
// Удаляем связанные данные
|
||||
await client.query('DELETE FROM messages WHERE sender_id = $1 OR receiver_id = $1', [userId]);
|
||||
await client.query('DELETE FROM matches WHERE user1_id = $1 OR user2_id = $1', [userId]);
|
||||
await client.query('DELETE FROM matches WHERE user_id_1 = $1 OR user_id_2 = $1', [userId]);
|
||||
await client.query('DELETE FROM swipes WHERE swiper_id = $1 OR swiped_id = $1', [userId]);
|
||||
await client.query('DELETE FROM profiles WHERE user_id = $1', [userId]);
|
||||
});
|
||||
|
||||
@@ -24,8 +24,9 @@ export class VipService {
|
||||
// Проверить премиум статус пользователя
|
||||
async checkPremiumStatus(telegramId: string): Promise<PremiumInfo> {
|
||||
try {
|
||||
// Проверяем существование пользователя
|
||||
const result = await query(`
|
||||
SELECT premium, premium_expires_at
|
||||
SELECT id
|
||||
FROM users
|
||||
WHERE telegram_id = $1
|
||||
`, [telegramId]);
|
||||
@@ -34,27 +35,12 @@ export class VipService {
|
||||
throw new BotError('User not found', 'USER_NOT_FOUND', 404);
|
||||
}
|
||||
|
||||
const user = result.rows[0];
|
||||
const isPremium = user.premium;
|
||||
const expiresAt = user.premium_expires_at ? new Date(user.premium_expires_at) : undefined;
|
||||
|
||||
let daysLeft = undefined;
|
||||
if (isPremium && expiresAt) {
|
||||
const now = new Date();
|
||||
const timeDiff = expiresAt.getTime() - now.getTime();
|
||||
daysLeft = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||
|
||||
// Если премиум истек
|
||||
if (daysLeft <= 0) {
|
||||
await this.removePremium(telegramId);
|
||||
return { isPremium: false };
|
||||
}
|
||||
}
|
||||
|
||||
// Временно возвращаем false для всех пользователей, так как колонки premium нет
|
||||
// В будущем, когда колонки будут добавлены, этот код нужно будет заменить обратно
|
||||
return {
|
||||
isPremium,
|
||||
expiresAt,
|
||||
daysLeft
|
||||
isPremium: false,
|
||||
expiresAt: undefined,
|
||||
daysLeft: undefined
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking premium status:', error);
|
||||
@@ -65,14 +51,9 @@ export class VipService {
|
||||
// Добавить премиум статус
|
||||
async addPremium(telegramId: string, durationDays: number = 30): Promise<void> {
|
||||
try {
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setDate(expiresAt.getDate() + durationDays);
|
||||
|
||||
await query(`
|
||||
UPDATE users
|
||||
SET premium = true, premium_expires_at = $2
|
||||
WHERE telegram_id = $1
|
||||
`, [telegramId, expiresAt]);
|
||||
// Временно заглушка, так как колонок premium и premium_expires_at нет
|
||||
console.log(`[VIP] Попытка добавить премиум для ${telegramId} на ${durationDays} дней`);
|
||||
// TODO: Добавить колонки premium и premium_expires_at в таблицу users
|
||||
} catch (error) {
|
||||
console.error('Error adding premium:', error);
|
||||
throw error;
|
||||
@@ -82,11 +63,9 @@ export class VipService {
|
||||
// Удалить премиум статус
|
||||
async removePremium(telegramId: string): Promise<void> {
|
||||
try {
|
||||
await query(`
|
||||
UPDATE users
|
||||
SET premium = false, premium_expires_at = NULL
|
||||
WHERE telegram_id = $1
|
||||
`, [telegramId]);
|
||||
// Временно заглушка, так как колонок premium и premium_expires_at нет
|
||||
console.log(`[VIP] Попытка удалить премиум для ${telegramId}`);
|
||||
// TODO: Добавить колонки premium и premium_expires_at в таблицу users
|
||||
} catch (error) {
|
||||
console.error('Error removing premium:', error);
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user