update planned wallets function
This commit is contained in:
parent
66f5251795
commit
5ae148a2ba
@ -1,3 +1,5 @@
|
||||
// database.js
|
||||
|
||||
import sqlite3 from 'sqlite3';
|
||||
import { promisify } from 'util';
|
||||
import { dirname } from 'path';
|
||||
|
@ -15,90 +15,145 @@ export default class AdminUserHandler {
|
||||
|
||||
static async calculateStatistics() {
|
||||
try {
|
||||
// Получаем общую статистику по пользователям
|
||||
const users = await db.allAsync(`
|
||||
SELECT
|
||||
u.*,
|
||||
COUNT(DISTINCT p.id) as total_purchases,
|
||||
COUNT(DISTINCT cw.id) as total_wallets
|
||||
FROM users u
|
||||
LEFT JOIN purchases p ON u.id = p.user_id
|
||||
LEFT JOIN crypto_wallets cw ON u.id = cw.user_id
|
||||
LEFT JOIN transactions t ON u.id = t.user_id
|
||||
GROUP BY u.id
|
||||
ORDER BY u.created_at DESC
|
||||
` );
|
||||
|
||||
// Calculate general statistics
|
||||
SELECT
|
||||
u.*,
|
||||
COUNT(DISTINCT p.id) as total_purchases,
|
||||
COUNT(DISTINCT cw.id) as total_wallets
|
||||
FROM users u
|
||||
LEFT JOIN purchases p ON u.id = p.user_id
|
||||
LEFT JOIN crypto_wallets cw ON u.id = cw.user_id
|
||||
LEFT JOIN transactions t ON u.id = t.user_id
|
||||
GROUP BY u.id
|
||||
ORDER BY u.created_at DESC
|
||||
`);
|
||||
|
||||
// Общие метрики
|
||||
const totalUsers = users.length;
|
||||
const activeUsers = users.filter(u => u.total_purchases > 0).length;
|
||||
const totalBalance = users.reduce((sum, u) => sum + (u.total_balance || 0), 0);
|
||||
const bonusBalance = users.reduce((sum, u) => sum + (u.bonus_balance || 0), 0);
|
||||
const totalPurchases = users.reduce((sum, u) => sum + (u.total_purchases || 0), 0);
|
||||
|
||||
// Create statistics message
|
||||
|
||||
// Рассчитываем общий баланс активных и архивных кошельков
|
||||
let totalActiveWalletsBalance = 0;
|
||||
let totalArchivedWalletsBalance = 0;
|
||||
|
||||
for (const user of users) {
|
||||
const activeWalletsBalance = await WalletService.getActiveWalletsBalance(user.id);
|
||||
const archivedWalletsBalance = await WalletService.getArchivedWalletsBalance(user.id);
|
||||
totalActiveWalletsBalance += activeWalletsBalance;
|
||||
totalArchivedWalletsBalance += archivedWalletsBalance;
|
||||
}
|
||||
|
||||
// Рассчитываем общий реальный баланс (крипто + бонусы)
|
||||
const totalRealBalance = totalActiveWalletsBalance + totalArchivedWalletsBalance + bonusBalance;
|
||||
|
||||
// Получаем статистику по транзакциям
|
||||
const totalTransactions = await db.getAsync(`
|
||||
SELECT COUNT(*) as total_transactions FROM transactions
|
||||
`);
|
||||
|
||||
// Получаем статистику по продуктам
|
||||
const totalProducts = await db.getAsync(`
|
||||
SELECT COUNT(*) as total_products FROM products
|
||||
`);
|
||||
|
||||
// Получаем статистику по локациям
|
||||
const totalLocations = await db.getAsync(`
|
||||
SELECT COUNT(*) as total_locations FROM locations
|
||||
`);
|
||||
|
||||
// Получаем статистику по категориям
|
||||
const totalCategories = await db.getAsync(`
|
||||
SELECT COUNT(*) as total_categories FROM categories
|
||||
`);
|
||||
|
||||
// Формируем сообщение со статистикой
|
||||
let message = `📊 System Statistics\n\n`;
|
||||
message += `👥 Total Users: ${totalUsers}\n`;
|
||||
message += `✅ Active Users: ${activeUsers}\n`;
|
||||
message += `💰 Bonus Balance: $${bonusBalance.toFixed(2)}\n`;
|
||||
message += `💰 Total Balance: $${(totalBalance + bonusBalance).toFixed(2)}\n`;
|
||||
message += `🛍 Total Purchases: ${totalPurchases}`;
|
||||
|
||||
message += `💰 Total All Users Balance: $${totalRealBalance.toFixed(2)}\n`;
|
||||
message += ` ├ Active Wallets Balance: $${totalActiveWalletsBalance.toFixed(2)}\n`;
|
||||
message += ` ├ Archived Wallets Balance: $${totalArchivedWalletsBalance.toFixed(2)}\n`;
|
||||
message += ` └ Bonus Balance: $${bonusBalance.toFixed(2)}\n`;
|
||||
message += `🛍 Total Purchases: ${totalPurchases}\n`;
|
||||
message += `💸 Total Transactions: ${totalTransactions.total_transactions}\n`;
|
||||
message += `📦 Total Products: ${totalProducts.total_products}\n`;
|
||||
message += `📍 Total Locations: ${totalLocations.total_locations}\n`;
|
||||
message += `📂 Total Categories: ${totalCategories.total_categories}\n`;
|
||||
|
||||
return message;
|
||||
} catch (error) {
|
||||
return null
|
||||
console.error('Error in calculateStatistics:', error);
|
||||
return 'Error loading statistics. Please try again.';
|
||||
}
|
||||
}
|
||||
|
||||
static async viewUserPage(page) {
|
||||
const limit = 10;
|
||||
const offset = (page || 0) * limit;
|
||||
|
||||
|
||||
const previousPage = page > 0 ? page - 1 : 0;
|
||||
const nextPage = page + 1;
|
||||
|
||||
|
||||
try {
|
||||
const users = await db.allAsync(`
|
||||
SELECT
|
||||
u.*,
|
||||
COUNT(DISTINCT p.id) as total_purchases,
|
||||
COUNT(DISTINCT cw.id) as total_wallets
|
||||
FROM users u
|
||||
LEFT JOIN purchases p ON u.id = p.user_id
|
||||
LEFT JOIN crypto_wallets cw ON u.id = cw.user_id
|
||||
LEFT JOIN transactions t ON u.id = t.user_id
|
||||
GROUP BY u.id
|
||||
ORDER BY u.created_at DESC
|
||||
LIMIT ?
|
||||
OFFSET ?
|
||||
`, [limit, offset]);
|
||||
SELECT
|
||||
u.*,
|
||||
COUNT(DISTINCT p.id) as total_purchases,
|
||||
COUNT(DISTINCT cw.id) as total_wallets
|
||||
FROM users u
|
||||
LEFT JOIN purchases p ON u.id = p.user_id
|
||||
LEFT JOIN crypto_wallets cw ON u.id = cw.user_id
|
||||
LEFT JOIN transactions t ON u.id = t.user_id
|
||||
GROUP BY u.id
|
||||
ORDER BY u.created_at DESC
|
||||
LIMIT ?
|
||||
OFFSET ?
|
||||
`, [limit, offset]);
|
||||
|
||||
if ((users.length === 0) && (page == 0)) {
|
||||
return {text: 'No users registered yet.'};
|
||||
return { text: 'No users registered yet.' };
|
||||
}
|
||||
|
||||
|
||||
if ((users.length === 0) && (page > 0)) {
|
||||
return await this.viewUserPage(page - 1);
|
||||
}
|
||||
|
||||
const statistics = await this.calculateStatistics()
|
||||
|
||||
// Calculate balances for each user
|
||||
const usersWithBalances = await Promise.all(users.map(async (user) => {
|
||||
const activeWalletsBalance = await WalletService.getActiveWalletsBalance(user.id);
|
||||
const archivedWalletsBalance = await WalletService.getArchivedWalletsBalance(user.id);
|
||||
const totalBalance = (user.total_balance || 0) + (user.bonus_balance || 0) + activeWalletsBalance + archivedWalletsBalance;
|
||||
return {
|
||||
...user,
|
||||
activeWalletsBalance,
|
||||
archivedWalletsBalance,
|
||||
totalBalance
|
||||
};
|
||||
}));
|
||||
|
||||
const statistics = await this.calculateStatistics();
|
||||
const message = `${statistics}\n\nSelect a user from the list below:`;
|
||||
|
||||
|
||||
// Create inline keyboard with user list
|
||||
const keyboard = {
|
||||
inline_keyboard: users.map(user => [{
|
||||
text: `ID: ${user.telegram_id} | Nickname: ${user.username ? "@" + user.username : "None"} | Balance: $${(user.total_balance || 0) + (user.bonus_balance || 0)}`,
|
||||
inline_keyboard: usersWithBalances.map(user => [{
|
||||
text: `ID: ${user.telegram_id} | Nickname: ${user.username ? "@" + user.username : "None"} | Balance: $${user.totalBalance.toFixed(2)}`,
|
||||
callback_data: `view_user_${user.telegram_id}`
|
||||
}])
|
||||
};
|
||||
|
||||
|
||||
keyboard.inline_keyboard.push([
|
||||
{text: `«`, callback_data: `list_users_${previousPage}`},
|
||||
{text: `»`, callback_data: `list_users_${nextPage}`},
|
||||
])
|
||||
|
||||
return {text: message, markup: keyboard}
|
||||
{ text: `«`, callback_data: `list_users_${previousPage}` },
|
||||
{ text: `»`, callback_data: `list_users_${nextPage}` },
|
||||
]);
|
||||
|
||||
return { text: message, markup: keyboard };
|
||||
} catch (error) {
|
||||
console.error('Error in handleUserList:', error);
|
||||
return {text: 'Error loading user list. Please try again.'}
|
||||
return { text: 'Error loading user list. Please try again.' };
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,19 +190,19 @@ export default class AdminUserHandler {
|
||||
|
||||
static async handleViewUser(callbackQuery) {
|
||||
if (!this.isAdmin(callbackQuery.from.id)) return;
|
||||
|
||||
|
||||
const telegramId = callbackQuery.data.replace('view_user_', '');
|
||||
const chatId = callbackQuery.message.chat.id;
|
||||
|
||||
|
||||
try {
|
||||
const detailedUser = await UserService.getDetailedUserByTelegramId(telegramId);
|
||||
const user = await UserService.getUserByTelegramId(telegramId);
|
||||
|
||||
|
||||
if (!detailedUser) {
|
||||
await bot.sendMessage(chatId, 'User not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Get recent transactions
|
||||
const transactions = await db.allAsync(`
|
||||
SELECT t.amount, t.created_at, t.wallet_type, t.tx_hash
|
||||
@ -157,7 +212,7 @@ export default class AdminUserHandler {
|
||||
ORDER BY t.created_at DESC
|
||||
LIMIT 5
|
||||
`, [telegramId]);
|
||||
|
||||
|
||||
// Get recent purchases
|
||||
const purchases = await db.allAsync(`
|
||||
SELECT p.quantity, p.total_price, p.purchase_date,
|
||||
@ -169,7 +224,7 @@ export default class AdminUserHandler {
|
||||
ORDER BY p.purchase_date DESC
|
||||
LIMIT 5
|
||||
`, [telegramId]);
|
||||
|
||||
|
||||
// Get pending purchases
|
||||
const pendingPurchases = await db.allAsync(`
|
||||
SELECT p.quantity, p.total_price, p.purchase_date,
|
||||
@ -180,37 +235,40 @@ export default class AdminUserHandler {
|
||||
WHERE u.telegram_id = ? AND p.status = 'pending'
|
||||
ORDER BY p.purchase_date DESC
|
||||
`, [telegramId]);
|
||||
|
||||
|
||||
// Get wallet balances
|
||||
const activeWalletsBalance = await WalletService.getActiveWalletsBalance(user.id);
|
||||
const archivedWalletsBalance = await WalletService.getArchivedWalletsBalance(user.id);
|
||||
|
||||
|
||||
// Общий баланс (крипто + бонусы + total_balance)
|
||||
const totalBalance = activeWalletsBalance + archivedWalletsBalance + user.bonus_balance + (user.total_balance || 0);
|
||||
|
||||
const message = `
|
||||
👤 User Profile:
|
||||
|
||||
ID: ${telegramId}
|
||||
📍 Location: ${detailedUser.country || 'Not set'}, ${detailedUser.city || 'Not set'}, ${detailedUser.district || 'Not set'}
|
||||
|
||||
📊 Activity:
|
||||
- Total Purchases: ${detailedUser.purchase_count}
|
||||
- Total Spent: $${detailedUser.total_spent || 0}
|
||||
- Active Wallets: ${detailedUser.crypto_wallet_count} ($${activeWalletsBalance.toFixed(2)})
|
||||
- Archived Wallets: ${detailedUser.archived_wallet_count} ($${archivedWalletsBalance.toFixed(2)})
|
||||
- Bonus Balance: $${user.bonus_balance || 0}
|
||||
- Total Balance: $${((user.total_balance || 0) + (user.bonus_balance || 0)).toFixed(2)}
|
||||
|
||||
💰 Recent Transactions (Last 5 of ${transactions.length}):
|
||||
${transactions.map(t => ` • $${t.amount} ${t.wallet_type} (${t.tx_hash}) at ${new Date(t.created_at).toLocaleString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })}`).join('\n')}
|
||||
|
||||
🛍 Recent Purchases (Last 5 of ${purchases.length}):
|
||||
${purchases.map(p => ` • ${p.product_name} x${p.quantity} - $${p.total_price}`).join('\n')}
|
||||
|
||||
🕒 Pending Purchases:
|
||||
${pendingPurchases.map(p => ` • ${p.product_name} x${p.quantity} - $${p.total_price}`).join('\n') || ' • No pending purchases'}
|
||||
|
||||
📅 Registered: ${new Date(detailedUser.created_at).toLocaleString()}
|
||||
`;
|
||||
|
||||
👤 User Profile:
|
||||
|
||||
ID: ${telegramId}
|
||||
📍 Location: ${detailedUser.country || 'Not set'}, ${detailedUser.city || 'Not set'}, ${detailedUser.district || 'Not set'}
|
||||
|
||||
📊 Activity:
|
||||
- Total Purchases: ${detailedUser.purchase_count}
|
||||
- Total Spent: $${detailedUser.total_spent || 0}
|
||||
- Active Wallets: ${detailedUser.crypto_wallet_count} ($${activeWalletsBalance.toFixed(2)})
|
||||
- Archived Wallets: ${detailedUser.archived_wallet_count} ($${archivedWalletsBalance.toFixed(2)})
|
||||
- Bonus Balance: $${user.bonus_balance || 0}
|
||||
- Total Balance: $${totalBalance.toFixed(2)}
|
||||
|
||||
💰 Recent Transactions (Last 5 of ${transactions.length}):
|
||||
${transactions.map(t => ` • $${t.amount} ${t.wallet_type} (${t.tx_hash}) at ${new Date(t.created_at).toLocaleString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })}`).join('\n')}
|
||||
|
||||
🛍 Recent Purchases (Last 5 of ${purchases.length}):
|
||||
${purchases.map(p => ` • ${p.product_name} x${p.quantity} - $${p.total_price}`).join('\n')}
|
||||
|
||||
🕒 Pending Purchases:
|
||||
${pendingPurchases.map(p => ` • ${p.product_name} x${p.quantity} - $${p.total_price}`).join('\n') || ' • No pending purchases'}
|
||||
|
||||
📅 Registered: ${new Date(detailedUser.created_at).toLocaleString()}
|
||||
`;
|
||||
|
||||
const keyboard = {
|
||||
inline_keyboard: [
|
||||
[
|
||||
@ -224,7 +282,7 @@ ${pendingPurchases.map(p => ` • ${p.product_name} x${p.quantity} - $${p.total
|
||||
[{text: '« Back to User List', callback_data: `list_users_0`}]
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
await bot.editMessageText(message, {
|
||||
chat_id: chatId,
|
||||
message_id: callbackQuery.message.message_id,
|
||||
|
@ -43,22 +43,22 @@ export default class AdminWalletsHandler {
|
||||
const action = callbackQuery.data;
|
||||
const chatId = callbackQuery.message.chat.id;
|
||||
const walletType = action.split('_').pop();
|
||||
|
||||
|
||||
try {
|
||||
// Удаляем предыдущее сообщение перед отправкой нового
|
||||
await bot.deleteMessage(chatId, callbackQuery.message.message_id);
|
||||
|
||||
// Получаем все кошельки выбранного типа
|
||||
|
||||
// Получаем все кошельки выбранного типа (активные и архивные)
|
||||
const wallets = await WalletService.getWalletsByType(walletType);
|
||||
|
||||
|
||||
if (wallets.length === 0) {
|
||||
await bot.sendMessage(chatId, `No wallets found for ${walletType}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Вычисляем суммарный баланс
|
||||
const totalBalance = await this.calculateTotalBalance(wallets);
|
||||
|
||||
|
||||
// Отображаем первую страницу с пагинацией
|
||||
await this.displayWalletsPage(chatId, wallets, walletType, totalBalance, 0);
|
||||
} catch (error) {
|
||||
@ -72,7 +72,7 @@ export default class AdminWalletsHandler {
|
||||
const startIndex = page * pageSize;
|
||||
const endIndex = startIndex + pageSize;
|
||||
const walletsPage = wallets.slice(startIndex, endIndex);
|
||||
|
||||
|
||||
// Формируем список кошельков с балансами
|
||||
let walletList = '';
|
||||
for (const wallet of walletsPage) {
|
||||
@ -83,16 +83,17 @@ export default class AdminWalletsHandler {
|
||||
null, // userId не нужен для админки
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
|
||||
|
||||
const balances = await walletUtilsInstance.getAllBalances();
|
||||
const balance = balances[wallet.wallet_type] || { amount: 0, usdValue: 0 };
|
||||
|
||||
const baseType = WalletUtils.getBaseWalletType(wallet.wallet_type);
|
||||
const balance = balances[baseType] || { amount: 0, usdValue: 0 };
|
||||
|
||||
walletList += `💰 *${wallet.wallet_type}*\n`;
|
||||
walletList += `├ Balance: ${balance.amount.toFixed(8)} ${wallet.wallet_type}\n`;
|
||||
walletList += `├ Value: $${balance.usdValue.toFixed(2)}\n`;
|
||||
walletList += `└ Address: \`${wallet.address}\`\n\n`;
|
||||
}
|
||||
|
||||
|
||||
// Создаем клавиатуру с пагинацией
|
||||
const keyboard = {
|
||||
inline_keyboard: [
|
||||
@ -106,17 +107,17 @@ export default class AdminWalletsHandler {
|
||||
]
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
// Убираем кнопку "Назад", если это первая страница
|
||||
if (page === 0) {
|
||||
keyboard.inline_keyboard[0].shift();
|
||||
}
|
||||
|
||||
|
||||
// Убираем кнопку "Далее", если это последняя страница
|
||||
if (endIndex >= wallets.length) {
|
||||
keyboard.inline_keyboard[0].pop();
|
||||
}
|
||||
|
||||
|
||||
// Отправляем сообщение с суммарным балансом и списком кошельков
|
||||
await bot.sendMessage(
|
||||
chatId,
|
||||
@ -139,12 +140,13 @@ export default class AdminWalletsHandler {
|
||||
null, // userId не нужен для админки
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
|
||||
|
||||
const balances = await walletUtilsInstance.getAllBalances();
|
||||
const balance = balances[wallet.wallet_type] || { usdValue: 0 };
|
||||
const baseType = WalletUtils.getBaseWalletType(wallet.wallet_type);
|
||||
const balance = balances[baseType] || { usdValue: 0 };
|
||||
totalBalance += balance.usdValue;
|
||||
}
|
||||
|
||||
|
||||
return totalBalance;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
// userHandler.js
|
||||
|
||||
import config from "../../config/config.js";
|
||||
import bot from "../../context/bot.js";
|
||||
import UserService from "../../services/userService.js";
|
||||
import WalletService from "../../services/walletService.js";
|
||||
|
||||
export default class UserHandler {
|
||||
static async canUseBot(msg) {
|
||||
@ -30,44 +33,51 @@ export default class UserHandler {
|
||||
static async showProfile(msg) {
|
||||
const chatId = msg.chat.id;
|
||||
const telegramId = msg.from.id;
|
||||
|
||||
|
||||
try {
|
||||
await UserService.recalculateUserBalanceByTelegramId(telegramId);
|
||||
const userStats = await UserService.getDetailedUserByTelegramId(telegramId);
|
||||
|
||||
|
||||
if (!userStats) {
|
||||
await bot.sendMessage(chatId, 'Profile not found. Please use /start to create one.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Получаем балансы активных и архивных кошельков
|
||||
const activeWalletsBalance = await WalletService.getActiveWalletsBalance(userStats.id);
|
||||
const archivedWalletsBalance = await WalletService.getArchivedWalletsBalance(userStats.id);
|
||||
|
||||
// Общий баланс (крипто + бонусы + total_balance)
|
||||
const totalBalance = activeWalletsBalance + archivedWalletsBalance + userStats.bonus_balance + (userStats.total_balance || 0);
|
||||
|
||||
const locationText = userStats.country && userStats.city && userStats.district
|
||||
? `${userStats.country}, ${userStats.city}, ${userStats.district}`
|
||||
: 'Not set';
|
||||
|
||||
|
||||
const text = `
|
||||
👤 *Your Profile*
|
||||
|
||||
📱 Telegram ID: \`${telegramId}\`
|
||||
📍 Location: ${locationText}
|
||||
|
||||
📊 Statistics:
|
||||
├ Total Purchases: ${userStats.purchase_count || 0}
|
||||
├ Total Spent: $${userStats.total_spent || 0}
|
||||
├ Active Wallets: ${userStats.crypto_wallet_count || 0}
|
||||
├ Archived Wallets: ${userStats.archived_wallet_count || 0}
|
||||
├ Bonus Balance: $${userStats.bonus_balance || 0}
|
||||
└ Available Balance: $${(userStats.total_balance || 0) + (userStats.bonus_balance || 0)}
|
||||
|
||||
📅 Member since: ${new Date(userStats.created_at).toLocaleDateString()}
|
||||
`;
|
||||
|
||||
👤 *Your Profile*
|
||||
|
||||
📱 Telegram ID: \`${telegramId}\`
|
||||
📍 Location: ${locationText}
|
||||
|
||||
📊 Statistics:
|
||||
├ Total Purchases: ${userStats.purchase_count || 0}
|
||||
├ Total Spent: $${userStats.total_spent || 0}
|
||||
├ Active Wallets: ${userStats.crypto_wallet_count || 0} ($${activeWalletsBalance.toFixed(2)})
|
||||
├ Archived Wallets: ${userStats.archived_wallet_count || 0} ($${archivedWalletsBalance.toFixed(2)})
|
||||
├ Bonus Balance: $${userStats.bonus_balance || 0}
|
||||
└ Available Balance: $${totalBalance.toFixed(2)}
|
||||
|
||||
📅 Member since: ${new Date(userStats.created_at).toLocaleDateString()}
|
||||
`;
|
||||
|
||||
const keyboard = {
|
||||
inline_keyboard: [
|
||||
[{text: '📍 Set Location', callback_data: 'set_location'}],
|
||||
[{text: '❌ Delete Account', callback_data: 'delete_account'}]
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
await bot.sendMessage(chatId, text, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_markup: keyboard
|
||||
|
@ -1,3 +1,5 @@
|
||||
// userWalletsHandler.js
|
||||
|
||||
import db from '../../config/database.js';
|
||||
import WalletGenerator from '../../utils/walletGenerator.js';
|
||||
import WalletUtils from '../../utils/walletUtils.js';
|
||||
@ -27,7 +29,7 @@ export default class UserWalletsHandler {
|
||||
|
||||
// Получаем активные криптокошельки
|
||||
const cryptoWallets = await db.allAsync(`
|
||||
SELECT wallet_type, address
|
||||
SELECT wallet_type, address, balance
|
||||
FROM crypto_wallets
|
||||
WHERE user_id = ?
|
||||
ORDER BY wallet_type
|
||||
@ -42,11 +44,10 @@ export default class UserWalletsHandler {
|
||||
cryptoWallets.find(w => w.wallet_type === 'ETH')?.address, // ETH address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDT')?.address, // USDT address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDC')?.address, // USDC address
|
||||
updatedUser.id,
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
updatedUser.id
|
||||
);
|
||||
|
||||
const balances = await walletUtilsInstance.getAllBalances();
|
||||
const balances = await walletUtilsInstance.getAllBalancesFromDB();
|
||||
let totalUsdValue = 0;
|
||||
|
||||
// Отображаем активные кошельки
|
||||
@ -68,12 +69,12 @@ export default class UserWalletsHandler {
|
||||
// Бонусный баланс
|
||||
message += `🎁 *Bonus Balance:* $${updatedUser.bonus_balance.toFixed(2)}\n`;
|
||||
|
||||
// Общий баланс (крипто + бонусы)
|
||||
const totalBalance = totalUsdValue + updatedUser.bonus_balance;
|
||||
// Общий баланс (крипто + бонусы + total_balance)
|
||||
const totalBalance = totalUsdValue + updatedUser.bonus_balance + (updatedUser.total_balance || 0);
|
||||
message += `💰 *Total Balance:* $${totalBalance.toFixed(2)}\n`;
|
||||
|
||||
// Доступный баланс (общий баланс минус расходы на покупки)
|
||||
const availableBalance = updatedUser.total_balance + updatedUser.bonus_balance;
|
||||
const availableBalance = totalBalance; // Теперь availableBalance включает криптобаланс
|
||||
message += `💳 *Available Balance:* $${availableBalance.toFixed(2)}\n`;
|
||||
} else {
|
||||
message = 'You don\'t have any active wallets yet.';
|
||||
@ -112,7 +113,7 @@ export default class UserWalletsHandler {
|
||||
console.error('Error in showBalance:', error);
|
||||
await bot.sendMessage(chatId, 'Error loading balance. Please try again.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async handleTransactionHistory(callbackQuery, page = 0) {
|
||||
const chatId = callbackQuery.message.chat.id;
|
||||
@ -259,10 +260,10 @@ export default class UserWalletsHandler {
|
||||
case 'ETH':
|
||||
address = walletAddresses.eth;
|
||||
break;
|
||||
case 'USDT ERC-20':
|
||||
case 'USDT':
|
||||
address = walletAddresses.usdt;
|
||||
break;
|
||||
case 'USDC ERC-20':
|
||||
case 'USDC':
|
||||
address = walletAddresses.usdc;
|
||||
break;
|
||||
default:
|
||||
|
@ -22,58 +22,80 @@ class WalletService {
|
||||
static async getActiveWalletsBalance(userId) {
|
||||
try {
|
||||
const wallets = await db.allAsync(
|
||||
`SELECT wallet_type, address
|
||||
`SELECT wallet_type, balance
|
||||
FROM crypto_wallets
|
||||
WHERE user_id = ? AND wallet_type NOT LIKE '%#_%' ESCAPE '#'`,
|
||||
[userId]
|
||||
);
|
||||
|
||||
|
||||
const prices = await WalletUtils.getCryptoPrices();
|
||||
|
||||
let totalBalance = 0;
|
||||
for (const wallet of wallets) {
|
||||
const walletUtils = new WalletUtils(
|
||||
wallet.wallet_type === 'BTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'LTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'ETH' ? wallet.address : null,
|
||||
wallet.wallet_type === 'USDT' ? wallet.address : null,
|
||||
wallet.wallet_type === 'USDC' ? wallet.address : null,
|
||||
userId
|
||||
);
|
||||
|
||||
const balances = await walletUtils.getAllBalances();
|
||||
totalBalance += balances[wallet.wallet_type]?.usdValue || 0;
|
||||
const baseType = WalletUtils.getBaseWalletType(wallet.wallet_type);
|
||||
const balance = wallet.balance || 0;
|
||||
|
||||
switch (baseType) {
|
||||
case 'BTC':
|
||||
totalBalance += balance * prices.btc;
|
||||
break;
|
||||
case 'LTC':
|
||||
totalBalance += balance * prices.ltc;
|
||||
break;
|
||||
case 'ETH':
|
||||
totalBalance += balance * prices.eth;
|
||||
break;
|
||||
case 'USDT':
|
||||
totalBalance += balance; // USDT is 1:1 with USD
|
||||
break;
|
||||
case 'USDC':
|
||||
totalBalance += balance; // USDC is 1:1 with USD
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return totalBalance;
|
||||
} catch (error) {
|
||||
console.error('Error fetching active wallets balance:', error);
|
||||
throw new Error('Failed to fetch active wallets balance');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static async getArchivedWalletsBalance(userId) {
|
||||
try {
|
||||
const wallets = await db.allAsync(
|
||||
`SELECT wallet_type, address
|
||||
`SELECT wallet_type, balance
|
||||
FROM crypto_wallets
|
||||
WHERE user_id = ? AND wallet_type LIKE '%#_%' ESCAPE '#'`,
|
||||
[userId]
|
||||
);
|
||||
|
||||
|
||||
const prices = await WalletUtils.getCryptoPrices();
|
||||
|
||||
let totalBalance = 0;
|
||||
for (const wallet of wallets) {
|
||||
const walletUtils = new WalletUtils(
|
||||
wallet.wallet_type === 'BTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'LTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'ETH' ? wallet.address : null,
|
||||
wallet.wallet_type === 'USDT' ? wallet.address : null,
|
||||
wallet.wallet_type === 'USDC' ? wallet.address : null,
|
||||
userId
|
||||
);
|
||||
|
||||
const balances = await walletUtils.getAllBalances();
|
||||
totalBalance += balances[wallet.wallet_type]?.usdValue || 0;
|
||||
const baseType = WalletUtils.getBaseWalletType(wallet.wallet_type);
|
||||
const balance = wallet.balance || 0;
|
||||
|
||||
switch (baseType) {
|
||||
case 'BTC':
|
||||
totalBalance += balance * prices.btc;
|
||||
break;
|
||||
case 'LTC':
|
||||
totalBalance += balance * prices.ltc;
|
||||
break;
|
||||
case 'ETH':
|
||||
totalBalance += balance * prices.eth;
|
||||
break;
|
||||
case 'USDT':
|
||||
totalBalance += balance; // USDT is 1:1 with USD
|
||||
break;
|
||||
case 'USDC':
|
||||
totalBalance += balance; // USDC is 1:1 with USD
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return totalBalance;
|
||||
} catch (error) {
|
||||
console.error('Error fetching archived wallets balance:', error);
|
||||
@ -87,10 +109,10 @@ class WalletService {
|
||||
const wallets = await db.allAsync(
|
||||
`SELECT *
|
||||
FROM crypto_wallets
|
||||
WHERE wallet_type = ?`,
|
||||
[walletType]
|
||||
WHERE wallet_type = ? OR wallet_type LIKE ?`,
|
||||
[walletType, `${walletType}_%`]
|
||||
);
|
||||
|
||||
|
||||
return wallets;
|
||||
} catch (error) {
|
||||
console.error('Error fetching wallets by type:', error);
|
||||
|
@ -1,3 +1,5 @@
|
||||
// walletUtils.js
|
||||
|
||||
import axios from 'axios';
|
||||
import db from '../config/database.js'; // Импортируем базу данных
|
||||
|
||||
@ -264,24 +266,24 @@ export default class WalletUtils {
|
||||
|
||||
async getAllBalancesFromDB() {
|
||||
const prices = await WalletUtils.getCryptoPrices();
|
||||
|
||||
|
||||
const balances = {
|
||||
BTC: { amount: 0, usdValue: 0 },
|
||||
LTC: { amount: 0, usdValue: 0 },
|
||||
ETH: { amount: 0, usdValue: 0 },
|
||||
'USDT ERC-20': { amount: 0, usdValue: 0 },
|
||||
'USDC ERC-20': { amount: 0, usdValue: 0 }
|
||||
USDT: { amount: 0, usdValue: 0 },
|
||||
USDC: { amount: 0, usdValue: 0 }
|
||||
};
|
||||
|
||||
|
||||
// Получаем балансы из таблицы crypto_wallets
|
||||
const wallets = await db.allAsync(`
|
||||
SELECT wallet_type, balance FROM crypto_wallets WHERE user_id = ?
|
||||
`, [this.userId]);
|
||||
|
||||
|
||||
for (const wallet of wallets) {
|
||||
const baseType = WalletUtils.getBaseWalletType(wallet.wallet_type);
|
||||
const [baseType] = wallet.wallet_type.split('_'); // Учитываем только базовый тип
|
||||
const balance = wallet.balance || 0;
|
||||
|
||||
|
||||
switch (baseType) {
|
||||
case 'BTC':
|
||||
balances.BTC.amount += balance;
|
||||
@ -296,16 +298,16 @@ export default class WalletUtils {
|
||||
balances.ETH.usdValue += balance * prices.eth;
|
||||
break;
|
||||
case 'USDT':
|
||||
balances['USDT ERC-20'].amount += balance;
|
||||
balances['USDT ERC-20'].usdValue += balance;
|
||||
balances.USDT.amount += balance;
|
||||
balances.USDT.usdValue += balance;
|
||||
break;
|
||||
case 'USDC':
|
||||
balances['USDC ERC-20'].amount += balance;
|
||||
balances['USDC ERC-20'].usdValue += balance;
|
||||
balances.USDC.amount += balance;
|
||||
balances.USDC.usdValue += balance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return balances;
|
||||
}
|
||||
|
||||
@ -315,7 +317,7 @@ export default class WalletUtils {
|
||||
|
||||
async getAllBalancesExt() {
|
||||
console.log('[DEBUG] getAllBalancesExt called'); // Логируем вызов метода
|
||||
|
||||
|
||||
const [
|
||||
btcBalance,
|
||||
ltcBalance,
|
||||
@ -331,7 +333,7 @@ export default class WalletUtils {
|
||||
this.getUsdcErc20Balance(),
|
||||
WalletUtils.getCryptoPrices()
|
||||
]);
|
||||
|
||||
|
||||
console.log('[DEBUG] Balances fetched:', { // Логируем полученные балансы
|
||||
btcBalance,
|
||||
ltcBalance,
|
||||
@ -340,13 +342,13 @@ export default class WalletUtils {
|
||||
usdcErc20Balance,
|
||||
prices
|
||||
});
|
||||
|
||||
|
||||
return {
|
||||
BTC: { amount: btcBalance, usdValue: btcBalance * prices.btc },
|
||||
LTC: { amount: ltcBalance, usdValue: ltcBalance * prices.ltc },
|
||||
ETH: { amount: ethBalance, usdValue: ethBalance * prices.eth },
|
||||
'USDT ERC-20': { amount: usdtErc20Balance, usdValue: usdtErc20Balance },
|
||||
'USDC ERC-20': { amount: usdcErc20Balance, usdValue: usdcErc20Balance }
|
||||
USDT: { amount: usdtErc20Balance, usdValue: usdtErc20Balance },
|
||||
USDC: { amount: usdcErc20Balance, usdValue: usdcErc20Balance }
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user