nakama/backend/scripts/fixReferrals.mongosh.js

141 lines
5.2 KiB
JavaScript
Raw Normal View History

2025-12-08 14:57:15 +00:00
// Скрипт для mongosh для исправления незасчитанных рефералов
// Использование:
// mongosh "mongodb://your-connection-string/nakama" fixReferrals.mongosh.js
// или
// mongosh nakama --file fixReferrals.mongosh.js
// Функция для получения начала дня по московскому времени (UTC+3)
function getMoscowStartOfDay(date) {
if (!date) {
date = new Date();
}
// Создаем копию даты
const moscowDate = new Date(date);
// Получаем UTC время
const utcTime = moscowDate.getTime() + (moscowDate.getTimezoneOffset() * 60 * 1000);
// Добавляем 3 часа для московского времени
const moscowOffset = 3 * 60 * 60 * 1000;
const moscowTime = new Date(utcTime + moscowOffset);
// Устанавливаем время на 00:00:00
moscowTime.setHours(0, 0, 0, 0);
return moscowTime;
}
// Функция для получения уникальных дат из массива loginDates
function getUniqueDates(loginDates) {
const uniqueDates = new Set();
if (!loginDates || !Array.isArray(loginDates)) {
return uniqueDates;
}
loginDates.forEach(date => {
if (!date) return;
const dateObj = getMoscowStartOfDay(new Date(date));
// Используем timestamp начала дня для сравнения
uniqueDates.add(dateObj.getTime());
});
return uniqueDates;
}
print("🔍 Поиск пользователей с незасчитанными рефералами...\n");
// Найти всех пользователей с referredBy, но не засчитанных
const usersWithReferrals = db.users.find({
referredBy: { $exists: true, $ne: null },
referralCounted: { $ne: true }
}).toArray();
print(`📊 Найдено ${usersWithReferrals.length} пользователей с незасчитанными рефералами\n`);
let fixed = 0;
let needMoreDays = 0;
let errors = 0;
let skipped = 0;
usersWithReferrals.forEach(user => {
try {
// Получить реферера
const referrer = db.users.findOne({ _id: user.referredBy });
if (!referrer) {
print(`⚠️ Пользователь ${user.username || user._id} имеет referredBy, но реферер не найден\n`);
skipped++;
return;
}
// Инициализировать loginDates если его нет
if (!user.loginDates || user.loginDates.length === 0) {
print(`📅 ${user.username || user._id}: нет дат входа. Пропускаем.\n`);
needMoreDays++;
return;
}
// Получить уникальные даты
const uniqueDates = getUniqueDates(user.loginDates);
const uniqueDatesCount = uniqueDates.size;
print(`👤 ${user.username || user._id}`);
print(` Реферер: ${referrer.username || referrer._id}`);
print(` Уникальных дат входа: ${uniqueDatesCount}`);
// Показать даты
const datesArray = Array.from(uniqueDates).map(t => {
const d = new Date(t);
return d.toLocaleDateString('ru-RU');
});
if (datesArray.length > 0) {
print(` Даты: ${datesArray.join(', ')}`);
}
// Если есть 2 или более уникальные даты, засчитать реферала
if (uniqueDatesCount >= 2) {
// Увеличить счетчик рефералов у реферера
const currentCount = referrer.referralsCount || 0;
const newCount = currentCount + 1;
const updateResult = db.users.updateOne(
{ _id: referrer._id },
{ $set: { referralsCount: newCount } }
);
if (updateResult.modifiedCount > 0) {
print(` ✅ РЕФЕРАЛ ЗАСЧИТАН! Новый счетчик: ${newCount}`);
} else {
print(` ⚠️ Не удалось обновить счетчик рефералов`);
}
// Пометить пользователя как засчитанного и очистить loginDates
const userUpdateResult = db.users.updateOne(
{ _id: user._id },
{
$set: {
referralCounted: true,
loginDates: []
}
}
);
if (userUpdateResult.modifiedCount > 0) {
print(` ✅ Пользователь помечен как засчитанный\n`);
fixed++;
} else {
print(` ⚠️ Не удалось пометить пользователя как засчитанного\n`);
}
} else {
print(` ⏳ Нужно еще ${2 - uniqueDatesCount} уникальных дат входа\n`);
needMoreDays++;
}
} catch (error) {
print(` ❌ Ошибка при обработке пользователя ${user._id}: ${error.message}\n`);
errors++;
}
});
print(`\n📊 Итого:`);
print(` ✅ Засчитано рефералов: ${fixed}`);
print(` ⏳ Требуется больше дней: ${needMoreDays}`);
print(` ⚠️ Пропущено (нет реферера): ${skipped}`);
print(` ❌ Ошибок: ${errors}`);
print(`\n✅ Готово!`);