nakama/backend/routes/users.js

193 lines
5.9 KiB
JavaScript
Raw Normal View History

2025-11-03 20:35:01 +00:00
const express = require('express');
const router = express.Router();
const { authenticate } = require('../middleware/auth');
const User = require('../models/User');
const Post = require('../models/Post');
const Notification = require('../models/Notification');
2025-11-10 20:13:22 +00:00
const ALLOWED_SEARCH_PREFERENCES = ['furry', 'anime'];
2025-11-03 20:35:01 +00:00
// Получить профиль пользователя
router.get('/:id', authenticate, async (req, res) => {
try {
const user = await User.findById(req.params.id)
.select('-__v')
.populate('followers', 'username firstName lastName photoUrl')
.populate('following', 'username firstName lastName photoUrl');
if (!user) {
return res.status(404).json({ error: 'Пользователь не найден' });
}
// Проверить подписку текущего пользователя
const isFollowing = user.followers.some(f => f._id.equals(req.user._id));
res.json({
user: {
id: user._id,
username: user.username,
firstName: user.firstName,
lastName: user.lastName,
photoUrl: user.photoUrl,
bio: user.bio,
followersCount: user.followers.length,
followingCount: user.following.length,
isFollowing,
createdAt: user.createdAt
}
});
} catch (error) {
console.error('Ошибка получения профиля:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Получить посты пользователя
router.get('/:id/posts', authenticate, async (req, res) => {
try {
const { page = 1, limit = 20 } = req.query;
const posts = await Post.find({ author: req.params.id })
.populate('author', 'username firstName lastName photoUrl')
.sort({ createdAt: -1 })
.limit(limit * 1)
.skip((page - 1) * limit)
.exec();
const count = await Post.countDocuments({ author: req.params.id });
res.json({
posts,
totalPages: Math.ceil(count / limit),
currentPage: page
});
} catch (error) {
console.error('Ошибка получения постов:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Подписаться / отписаться
router.post('/:id/follow', authenticate, async (req, res) => {
try {
if (req.params.id === req.user._id.toString()) {
return res.status(400).json({ error: 'Нельзя подписаться на себя' });
}
const targetUser = await User.findById(req.params.id);
if (!targetUser) {
return res.status(404).json({ error: 'Пользователь не найден' });
}
const isFollowing = targetUser.followers.includes(req.user._id);
if (isFollowing) {
// Отписаться
targetUser.followers = targetUser.followers.filter(id => !id.equals(req.user._id));
req.user.following = req.user.following.filter(id => !id.equals(targetUser._id));
} else {
// Подписаться
targetUser.followers.push(req.user._id);
req.user.following.push(targetUser._id);
// Создать уведомление
const notification = new Notification({
recipient: targetUser._id,
sender: req.user._id,
type: 'follow'
});
await notification.save();
}
await targetUser.save();
await req.user.save();
res.json({
following: !isFollowing,
followersCount: targetUser.followers.length
});
} catch (error) {
console.error('Ошибка подписки:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Обновить профиль
router.put('/profile', authenticate, async (req, res) => {
try {
const { bio, settings } = req.body;
if (bio !== undefined) {
req.user.bio = bio;
}
if (settings) {
2025-11-10 20:13:22 +00:00
req.user.settings = req.user.settings || {};
if (settings.whitelist) {
const currentWhitelist =
req.user.settings.whitelist && typeof req.user.settings.whitelist.toObject === 'function'
? req.user.settings.whitelist.toObject()
: { ...(req.user.settings.whitelist || {}) };
req.user.settings.whitelist = {
...currentWhitelist,
...settings.whitelist
};
}
if (settings.searchPreference) {
req.user.settings.searchPreference = ALLOWED_SEARCH_PREFERENCES.includes(settings.searchPreference)
? settings.searchPreference
: 'furry';
}
if (!req.user.settings.searchPreference) {
req.user.settings.searchPreference = 'furry';
}
if (!req.user.settings.whitelist) {
req.user.settings.whitelist = { noNSFW: true };
} else if (req.user.settings.whitelist.noNSFW === undefined) {
req.user.settings.whitelist.noNSFW = true;
}
req.user.markModified('settings');
2025-11-03 20:35:01 +00:00
}
await req.user.save();
res.json({
message: 'Профиль обновлен',
user: req.user
});
} catch (error) {
console.error('Ошибка обновления профиля:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Поиск пользователей
router.get('/search/:query', authenticate, async (req, res) => {
try {
const users = await User.find({
$or: [
{ username: { $regex: req.params.query, $options: 'i' } },
{ firstName: { $regex: req.params.query, $options: 'i' } },
{ lastName: { $regex: req.params.query, $options: 'i' } }
]
})
.select('username firstName lastName photoUrl')
.limit(10);
res.json({ users });
} catch (error) {
console.error('Ошибка поиска пользователей:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
module.exports = router;