Fix like/dislike errors and implement native chat system

This commit is contained in:
2025-09-13 07:51:02 +09:00
parent 8893b4ad22
commit 321547bf27
14 changed files with 1236 additions and 39 deletions

View File

@@ -95,7 +95,18 @@ export class ProfileService {
}
return this.mapEntityToProfile(result.rows[0]);
} // Получение UUID пользователя по Telegram ID
}
// Получение Telegram ID по UUID пользователя
async getTelegramIdByUserId(userId: string): Promise<string | null> {
const result = await query(`
SELECT telegram_id FROM users WHERE id = $1
`, [userId]);
return result.rows.length > 0 ? result.rows[0].telegram_id.toString() : null;
}
// Получение UUID пользователя по Telegram ID
async getUserIdByTelegramId(telegramId: string): Promise<string | null> {
const result = await query(`
SELECT id FROM users WHERE telegram_id = $1
@@ -162,7 +173,8 @@ export class ProfileService {
case 'photos':
case 'interests':
updateFields.push(`${this.camelToSnake(key)} = $${paramIndex++}`);
updateValues.push(JSON.stringify(value));
// Для PostgreSQL массивы передаем как есть, не как JSON строки
updateValues.push(value);
break;
case 'location':
if (value && typeof value === 'object' && 'latitude' in value) {
@@ -336,7 +348,7 @@ export class ProfileService {
return {
totalLikes: parseInt(likesResult.rows[0].count),
totalMatches: parseInt(matchesResult.rows[0].count),
profileViews: 0, // TODO: implement profile views tracking
profileViews: await this.getProfileViewsCount(userId),
likesReceived: parseInt(likesReceivedResult.rows[0].count)
};
}
@@ -499,4 +511,61 @@ export class ProfileService {
profile.isVisible = newVisibility;
return profile;
}
// Записать просмотр профиля
async recordProfileView(viewerId: string, viewedProfileId: string, viewType: string = 'browse'): Promise<void> {
try {
await query(`
INSERT INTO profile_views (viewer_id, viewed_profile_id, view_type)
VALUES (
(SELECT id FROM users WHERE telegram_id = $1),
(SELECT id FROM profiles WHERE user_id = (SELECT id FROM users WHERE telegram_id = $2)),
$3
)
ON CONFLICT (viewer_id, viewed_profile_id) DO UPDATE
SET viewed_at = CURRENT_TIMESTAMP, view_type = EXCLUDED.view_type
`, [viewerId, viewedProfileId, viewType]);
} catch (error) {
console.error('Error recording profile view:', error);
}
}
// Получить количество просмотров профиля
async getProfileViewsCount(userId: string): Promise<number> {
try {
const result = await query(`
SELECT COUNT(*) as count
FROM profile_views pv
JOIN profiles p ON pv.viewed_profile_id = p.id
WHERE p.user_id = $1
`, [userId]);
return parseInt(result.rows[0].count) || 0;
} catch (error) {
console.error('Error getting profile views count:', error);
return 0;
}
}
// Получить список кто просматривал профиль
async getProfileViewers(userId: string, limit: number = 10): Promise<Profile[]> {
try {
const result = await query(`
SELECT DISTINCT p.*, u.telegram_id, u.username, u.first_name, u.last_name
FROM profile_views pv
JOIN profiles target_p ON pv.viewed_profile_id = target_p.id
JOIN users viewer_u ON pv.viewer_id = viewer_u.id
JOIN profiles p ON viewer_u.id = p.user_id
JOIN users u ON p.user_id = u.id
WHERE target_p.user_id = $1
ORDER BY pv.viewed_at DESC
LIMIT $2
`, [userId, limit]);
return result.rows.map((row: any) => this.mapEntityToProfile(row));
} catch (error) {
console.error('Error getting profile viewers:', error);
return [];
}
}
}