From d4eb5d46c32f36c53bf5be78cf7c007c36fc31ce Mon Sep 17 00:00:00 2001 From: Artyom Ashirov <1323ED5@gmail.com> Date: Thu, 21 Nov 2024 13:43:41 +0300 Subject: [PATCH 1/2] Zip error fix --- src/handlers/adminDumpHandler.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/handlers/adminDumpHandler.js b/src/handlers/adminDumpHandler.js index 6e2b6ed..34e87b6 100644 --- a/src/handlers/adminDumpHandler.js +++ b/src/handlers/adminDumpHandler.js @@ -128,8 +128,9 @@ export default class AdminDumpHandler { await decompress(fileContent, './dump'); - const statistics = await this.getDumpStatistic() + const statistics = await this.getDumpStatistic(); await this.bot.sendMessage(chatId, JSON.stringify(statistics, null, 2)); + this.userStates.delete(chatId); } else { await this.bot.sendMessage(chatId, 'Please upload a valid .zip file.'); return true; From a760cb2d233396df1a9b7f31bdfce2a657a23cce Mon Sep 17 00:00:00 2001 From: Artyom Ashirov <1323ED5@gmail.com> Date: Thu, 21 Nov 2024 14:48:45 +0300 Subject: [PATCH 2/2] Bonus balance editing --- src/handlers/adminUserHandler.js | 76 ++++++++++++++++++++------------ src/index.js | 5 +++ 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/handlers/adminUserHandler.js b/src/handlers/adminUserHandler.js index 7ee340d..a7b1542 100644 --- a/src/handlers/adminUserHandler.js +++ b/src/handlers/adminUserHandler.js @@ -5,6 +5,7 @@ import db from '../config/database.js'; export default class AdminUserHandler { constructor(bot) { this.bot = bot; + this.userStates = new Map(); } isAdmin(userId) { @@ -17,8 +18,7 @@ export default class AdminUserHandler { SELECT u.*, COUNT(DISTINCT p.id) as total_purchases, - COUNT(DISTINCT cw.id) as total_wallets, - COALESCE(SUM(t.amount), 0) as total_balance + 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 @@ -31,13 +31,15 @@ export default class AdminUserHandler { 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 message = `šŸ“Š System Statistics\n\n`; message += `šŸ‘„ Total Users: ${totalUsers}\n`; message += `āœ… Active Users: ${activeUsers}\n`; - message += `šŸ’° Total Balance: $${totalBalance.toFixed(2)}\n`; + message += `šŸ’° Bonus Balance: $${bonusBalance.toFixed(2)}\n`; + message += `šŸ’° Total Balance: $${(totalBalance + bonusBalance).toFixed(2)}\n`; message += `šŸ› Total Purchases: ${totalPurchases}`; return message; @@ -58,8 +60,7 @@ export default class AdminUserHandler { SELECT u.*, COUNT(DISTINCT p.id) as total_purchases, - COUNT(DISTINCT cw.id) as total_wallets, - COALESCE(SUM(t.amount), 0) as total_balance + 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 @@ -83,7 +84,7 @@ export default class AdminUserHandler { // 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}`, + text: `ID: ${user.telegram_id} | Nickname: ${user.username ? "@" + user.username : "None"} | Balance: $${(user.total_balance || 0) + (user.bonus_balance || 0)}`, callback_data: `view_user_${user.telegram_id}` }]) }; @@ -153,6 +154,13 @@ export default class AdminUserHandler { GROUP BY u.id `, [userId]); + const user = await User.getById(userId); + + if (!user) { + await this.bot.sendMessage(chatId, 'User not found.'); + return; + } + if (!userStats) { await this.bot.sendMessage(chatId, 'User not found.'); return; @@ -190,7 +198,8 @@ ID: ${userId} - Total Purchases: ${userStats.purchase_count} - Total Spent: $${userStats.total_spent || 0} - Active Wallets: ${userStats.wallet_count} - - Total Balance: $${userStats.total_balance || 0} + - Bonus Balance: $${user.bonus_balance || 0} + - Total Balance: $${(user.total_balance || 0) + (user.bonus_balance || 0)} šŸ’° Recent Transactions: ${transactions.map(t => ` ā€¢ ${t.amount} ${t.wallet_type} (${t.tx_hash})`).join('\n')} @@ -211,7 +220,7 @@ ${purchases.map(p => ` ā€¢ ${p.product_name} x${p.quantity} - $${p.total_price} {text: 'šŸš« Block User', callback_data: `block_user_${userId}`}, {text: 'āŒ Delete User', callback_data: `delete_user_${userId}`} ], - [{text: 'Ā« Back to User List', callback_data: 'admin_users'}] + [{text: 'Ā« Back to User List', callback_data: `list_users_0`}] ] }; @@ -373,36 +382,45 @@ ${purchases.map(p => ` ā€¢ ${p.product_name} x${p.quantity} - $${p.total_price} return; } - const wallets = await db.allAsync(` - SELECT wallet_type, address - FROM crypto_wallets - WHERE user_id = (SELECT id FROM users WHERE telegram_id = ?) - ORDER BY wallet_type - `, [userId]); - - const keyboard = { - inline_keyboard: [ - ...wallets.map(wallet => [ - { - text: `${wallet.wallet_type}: ${wallet.address}`, - callback_data: `edit_wallet_${wallet.wallet_type}` - } - ]), - [{text: 'Ā« Back', callback_data: `view_user_${userId}`}] - ] - }; - await this.bot.editMessageText( - `Select wallet to edit for user ${userId}:`, + `Enter new value for bonus balance. \n\nšŸ‘„ User: ${userId}\nšŸ’° Bonus Balance Now: $${user.bonus_balance.toFixed(2)}`, { chat_id: chatId, message_id: callbackQuery.message.message_id, - reply_markup: keyboard } ); + + this.userStates.set(chatId, { action: "edit_bonus_balance", telegram_id: userId }); } catch (error) { console.error('Error in handleEditUserBalance:', error); await this.bot.sendMessage(chatId, 'Error loading user wallets. Please try again.'); } } + + async handleBonusBalanceInput(msg) { + if (!this.isAdmin(msg.from.id)) return; + + const chatId = msg.chat.id; + const state = this.userStates.get(chatId); + + if (!state || state.action !== 'edit_bonus_balance') { + return false; + } + + const newValue = parseFloat(msg.text); + + if (isNaN(newValue)) { + await this.bot.sendMessage(chatId, 'Invalid value. Try again'); + return; + } + + try { + await db.runAsync(`UPDATE users SET bonus_balance = ? WHERE telegram_id = ?`, [newValue, state.telegram_id]) + await this.bot.sendMessage(chatId, 'āœ… Done') + } catch (e) { + await this.bot.sendMessage(chatId, 'Something went wrong'); + } + + this.userStates.delete(chatId); + } } \ No newline at end of file diff --git a/src/index.js b/src/index.js index b16f899..825c87a 100644 --- a/src/index.js +++ b/src/index.js @@ -114,6 +114,11 @@ bot.on('message', async (msg) => { return; } + // Check for bonus balance input + if (await adminUserHandler.handleBonusBalanceInput(msg)) { + return; + } + logDebug(msg.text, 'handleMessage'); switch (msg.text) {