Reflex/backend/controllers/actionController.js
2025-05-21 22:13:09 +07:00

165 lines
8.6 KiB
JavaScript
Raw Permalink 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.

const User = require('../models/User'); // Нам нужна модель User
const Conversation = require('../models/Conversation'); // Добавляем модель Conversation
// @desc Лайкнуть пользователя
// @route POST /api/actions/like/:userId
// @access Private
const likeUser = async (req, res, next) => {
const likedUserId = req.params.userId; // ID пользователя, которого лайкают
const currentUserId = req.user._id; // ID текущего пользователя (из protect middleware)
console.log(`[ACTION_CTRL] Пользователь ${currentUserId} лайкает пользователя ${likedUserId}`);
try {
// 0. Проверка, не лайкает ли пользователь сам себя
if (currentUserId.equals(likedUserId)) {
const error = new Error('Вы не можете лайкнуть самого себя.');
error.statusCode = 400;
throw error;
}
// 1. Найти обоих пользователей
const currentUser = await User.findById(currentUserId);
const likedUser = await User.findById(likedUserId);
if (!currentUser || !likedUser) {
const error = new Error('Один из пользователей не найден.');
error.statusCode = 404;
throw error;
}
// 2. Проверить, не был ли этот пользователь уже лайкнут или пропущен текущим пользователем
if (currentUser.liked.includes(likedUserId)) {
console.log(`[ACTION_CTRL] Пользователь ${likedUserId} уже был лайкнут пользователем ${currentUserId}`);
// Можно вернуть информацию о существующем лайке или просто успешный ответ
return res.status(200).json({ message: 'Пользователь уже был лайкнут ранее.', isMatch: currentUser.matches.includes(likedUserId) });
}
if (currentUser.passed.includes(likedUserId)) {
// Если пользователь был ранее пропущен, убираем его из passed и продолжаем как обычный лайк
currentUser.passed.pull(likedUserId);
console.log(`[ACTION_CTRL] Пользователь ${likedUserId} был ранее пропущен, теперь лайкнут пользователем ${currentUserId}`);
}
// 3. Добавить likedUserId в массив 'liked' текущего пользователя
currentUser.liked.addToSet(likedUserId); // addToSet добавляет, только если элемента еще нет
// 4. Проверить на взаимный лайк (мэтч)
let isMatch = false;
let conversationId = null; // Инициализируем conversationId
// Проверяем, лайкал ли 'likedUser' текущего пользователя ('currentUser')
if (likedUser.liked.includes(currentUserId)) {
isMatch = true;
// Если мэтч, добавляем друг друга в массивы 'matches'
currentUser.matches.addToSet(likedUserId);
likedUser.matches.addToSet(currentUserId);
await likedUser.save(); // Сохраняем изменения для likedUser
console.log(`[ACTION_CTRL] !!! МЭТЧ !!! между ${currentUserId} и ${likedUserId}`);
// Автоматическое создание или получение диалога при мэтче
try {
let conversation = await Conversation.findOne({
participants: { $all: [currentUserId, likedUserId] }
});
if (!conversation) {
console.log(`[ACTION_CTRL] Создание нового диалога для мэтча между ${currentUserId} и ${likedUserId}`);
conversation = new Conversation({
participants: [currentUserId, likedUserId]
});
await conversation.save();
console.log(`[ACTION_CTRL] Новый диалог создан с ID: ${conversation._id}`);
} else {
console.log(`[ACTION_CTRL] Диалог для мэтча между ${currentUserId} и ${likedUserId} уже существует: ${conversation._id}`);
}
conversationId = conversation._id; // Сохраняем ID диалога
} catch (convError) {
console.error(`[ACTION_CTRL] Ошибка при создании/получении диалога для мэтча:`, convError.message);
// Не прерываем основной ответ из-за ошибки создания чата,
// но логируем. В реальном приложении здесь могла бы быть
// более сложная обработка или уведомление администратора.
}
// TODO: Здесь можно будет добавить логику для отправки уведомления о мэтче
}
await currentUser.save(); // Сохраняем изменения для currentUser
const responseJson = {
message: isMatch ? 'Это мэтч! Вы понравились друг другу!' : 'Лайк успешно поставлен.',
isMatch: isMatch,
};
if (isMatch && conversationId) {
responseJson.conversationId = conversationId;
}
res.status(200).json(responseJson);
} catch (error) {
console.error(`[ACTION_CTRL] Ошибка при лайке пользователя ${likedUserId} пользователем ${currentUserId}:`, error.message);
// Если statusCode не установлен ошибкой, errorHandler поставит 500
// Для ошибок типа "не найден" мы уже ставим 404
next(error);
}
};
// @desc Пропустить/дизлайкнуть пользователя
// @route POST /api/actions/pass/:userId
// @access Private
const passUser = async (req, res, next) => {
const passedUserId = req.params.userId; // ID пользователя, которого пропускают
const currentUserId = req.user._id; // ID текущего пользователя
console.log(`[ACTION_CTRL] Пользователь ${currentUserId} пропускает пользователя ${passedUserId}`);
try {
// 0. Проверка, не пропускает ли пользователь сам себя
if (currentUserId.equals(passedUserId)) {
const error = new Error('Вы не можете пропустить самого себя.');
error.statusCode = 400;
throw error;
}
const currentUser = await User.findById(currentUserId);
const userToPass = await User.findById(passedUserId); // Проверяем, что такой пользователь существует
if (!currentUser || !userToPass) {
const error = new Error('Один из пользователей не найден.');
error.statusCode = 404;
throw error;
}
// 1. Добавить passedUserId в массив 'passed' текущего пользователя
currentUser.passed.addToSet(passedUserId);
// 2. Если этот пользователь был ранее лайкнут, убрать его из лайков
// (на случай, если пользователь передумал, хотя UI обычно не дает так сделать без "анлайка")
if (currentUser.liked.includes(passedUserId)) {
currentUser.liked.pull(passedUserId);
// Также нужно проверить, не был ли это мэтч, и если да, то убрать из мэтчей у обоих
if (currentUser.matches.includes(passedUserId)) {
currentUser.matches.pull(passedUserId);
userToPass.matches.pull(currentUserId);
await userToPass.save(); // Сохраняем изменения для другого пользователя
console.log(`[ACTION_CTRL] Мэтч между ${currentUserId} и ${passedUserId} был разорван из-за пропуска.`);
}
}
await currentUser.save();
res.status(200).json({
message: 'Пользователь успешно пропущен.',
// passed: currentUser.passed
});
} catch (error) {
console.error(`[ACTION_CTRL] Ошибка при пропуске пользователя ${passedUserId} пользователем ${currentUserId}:`, error.message);
next(error);
}
};
module.exports = {
likeUser,
passUser,
};