Taio_O преди 2 седмици
родител
ревизия
4393e7a688
променени са 2 файла, в които са добавени 201 реда и са изтрити 44 реда
  1. 113 39
      admin/index.js
  2. 88 5
      admin/models/Transaction.js

+ 113 - 39
admin/index.js

@@ -264,7 +264,7 @@ bot.on('message', async (msg) => {
         }
     }
 
-    // 2. 处理回款命令
+    // 2. 处理下发命令
     else if (text.startsWith('下发')) {
         let amount, exchangeRate, feeRate;
         const parts = text.replace(/[^0-9./-]/g, '').split('/');
@@ -281,40 +281,76 @@ bot.on('message', async (msg) => {
         }
 
         if (!isNaN(amount)) {
+            // 获取当前账单信息
+            const [records] = await pool.query(`
+                SELECT t.*, 
+                       COALESCE(t.fee_rate, g.in_fee_rate) as fee_rate,
+                       COALESCE(t.exchange_rate, g.in_exchange_rate) as exchange_rate,
+                       t.totalDeposit as total_deposit,
+                       t.totalWithdrawal as total_withdrawal,
+                       t.depositFee as deposit_fee,
+                       t.withdrawalFee as withdrawal_fee,
+                       t.totalUDeposit as total_u_deposit,
+                       t.totalUWithdrawal as total_u_withdrawal
+                FROM transactions t
+                LEFT JOIN groups g ON t.group_id = g.group_id
+                WHERE t.group_id = ? 
+                AND DATE(t.time) = CURDATE()
+                ORDER BY t.time DESC
+                LIMIT 1
+            `, [msg.chat.id.toString()]);
+
+            if (!records || records.length === 0) {
+                await sendMessage(msg.chat.id, '暂无交易记录,无法计算下发金额');
+                return;
+            }
+
+            const latestRecord = records[0];
+            const totalUDeposit = parseFloat(latestRecord.total_u_deposit) || 0;
+            const totalUWithdrawal = parseFloat(latestRecord.total_u_withdrawal) || 0;
+
+            // 直接使用输入的金额,不再限制
+            const actualAmount = amount;
+
+            if (actualAmount <= 0) {
+                await sendMessage(msg.chat.id, '下发金额必须大于0');
+                return;
+            }
+
             const transactionData = {
                 groupId: msg.chat.id.toString(),
                 groupName: msg.chat.title || '未命名群组',
-                amount: amount,
-                type: 'withdrawal',
+                amount: actualAmount,
+                type: 'distribute',
                 exchangeRate: exchangeRate,
                 feeRate: feeRate,
                 operatorId: msg.from.id
             };
 
             try {
-                const result = await Transaction.withdrawal(transactionData);
+                const result = await Transaction.distribute(transactionData);
                 if (result.success) {
                     const billMessage = await generateBillMessage(msg.chat.id);
                     if (billMessage) {
                         await sendMessage(msg.chat.id, billMessage, {
                             reply_markup: generateInlineKeyboard(msg.chat.id)
                         });
-                        console.log(`回款成功 - 群组: ${msg.chat.title}, 金额: ${amount}, 时间: ${new Date().toLocaleString()}`);
+                        console.log(`下发成功 - 群组: ${msg.chat.title}, 金额: ${actualAmount}, 时间: ${new Date().toLocaleString()}`);
                     } else {
-                        await sendMessage(msg.chat.id, '回款成功,但获取账单信息失败');
-                        console.log(`回款成功(无账单) - 群组: ${msg.chat.title}, 金额: ${amount}, 时间: ${new Date().toLocaleString()}`);
+                        await sendMessage(msg.chat.id, '下发成功,但获取账单信息失败');
+                        console.log(`下发成功(无账单) - 群组: ${msg.chat.title}, 金额: ${actualAmount}, 时间: ${new Date().toLocaleString()}`);
                     }
                 } else {
-                    await sendMessage(msg.chat.id, result.message || '回款失败');
-                    console.log(`回款失败 - 群组: ${msg.chat.title}, 金额: ${amount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
+                    await sendMessage(msg.chat.id, result.message || '下发失败');
+                    console.log(`下发失败 - 群组: ${msg.chat.title}, 金额: ${actualAmount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
                 }
             } catch (error) {
-                console.error('快捷回款失败:', error);
-                await sendMessage(msg.chat.id, '记录回款失败,请稍后重试');
+                console.error('快捷下发失败:', error);
+                await sendMessage(msg.chat.id, '记录下发失败,请稍后重试');
             }
         }
     }
-    // 2.1 处理回款修正命令
+    // 2.1 处理下发修正命令
     else if (text.startsWith('下发-')) {
         let amount, exchangeRate, feeRate;
         const parts = text.replace(/[^0-9./-]/g, '').split('/');
@@ -331,36 +367,73 @@ bot.on('message', async (msg) => {
         }
 
         if (!isNaN(amount)) {
+            // 获取当前账单信息
+            const [records] = await pool.query(`
+                SELECT t.*, 
+                       COALESCE(t.fee_rate, g.in_fee_rate) as fee_rate,
+                       COALESCE(t.exchange_rate, g.in_exchange_rate) as exchange_rate,
+                       t.totalDeposit as total_deposit,
+                       t.totalWithdrawal as total_withdrawal,
+                       t.depositFee as deposit_fee,
+                       t.withdrawalFee as withdrawal_fee,
+                       t.totalUDeposit as total_u_deposit,
+                       t.totalUWithdrawal as total_u_withdrawal
+                FROM transactions t
+                LEFT JOIN groups g ON t.group_id = g.group_id
+                WHERE t.group_id = ? 
+                AND DATE(t.time) = CURDATE()
+                ORDER BY t.time DESC
+                LIMIT 1
+            `, [msg.chat.id.toString()]);
+
+            if (!records || records.length === 0) {
+                await sendMessage(msg.chat.id, '暂无交易记录,无法计算下发修正金额');
+                return;
+            }
+
+            const latestRecord = records[0];
+            const totalUDeposit = parseFloat(latestRecord.total_u_deposit) || 0;
+            const totalUWithdrawal = parseFloat(latestRecord.total_u_withdrawal) || 0;
+            const remainingAmount = totalUDeposit - totalUWithdrawal;
+
+            // 计算实际修正金额
+            const actualAmount = Math.min(amount, totalUWithdrawal);
+
+            if (actualAmount <= 0) {
+                await sendMessage(msg.chat.id, '没有可修正的下发金额');
+                return;
+            }
+
             const transactionData = {
                 groupId: msg.chat.id.toString(),
                 groupName: msg.chat.title || '未命名群组',
-                amount: -amount,
-                type: 'withdrawal',
+                amount: -actualAmount,
+                type: 'distribute',
                 exchangeRate: exchangeRate,
                 feeRate: feeRate,
                 operatorId: msg.from.id
             };
 
             try {
-                const result = await Transaction.withdrawal(transactionData);
+                const result = await Transaction.distribute(transactionData);
                 if (result.success) {
                     const billMessage = await generateBillMessage(msg.chat.id);
                     if (billMessage) {
                         await sendMessage(msg.chat.id, billMessage, {
                             reply_markup: generateInlineKeyboard(msg.chat.id)
                         });
-                        console.log(`回款修正成功 - 群组: ${msg.chat.title}, 金额: -${amount}, 时间: ${new Date().toLocaleString()}`);
+                        console.log(`下发修正成功 - 群组: ${msg.chat.title}, 金额: -${actualAmount}, 时间: ${new Date().toLocaleString()}`);
                     } else {
-                        await sendMessage(msg.chat.id, '回款修正成功,但获取账单信息失败');
-                        console.log(`回款修正成功(无账单) - 群组: ${msg.chat.title}, 金额: -${amount}, 时间: ${new Date().toLocaleString()}`);
+                        await sendMessage(msg.chat.id, '下发修正成功,但获取账单信息失败');
+                        console.log(`下发修正成功(无账单) - 群组: ${msg.chat.title}, 金额: -${actualAmount}, 时间: ${new Date().toLocaleString()}`);
                     }
                 } else {
-                    await sendMessage(msg.chat.id, result.message || '回款修正失败');
-                    console.log(`回款修正失败 - 群组: ${msg.chat.title}, 金额: -${amount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
+                    await sendMessage(msg.chat.id, result.message || '下发修正失败');
+                    console.log(`下发修正失败 - 群组: ${msg.chat.title}, 金额: -${actualAmount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
                 }
             } catch (error) {
-                console.error('快捷回款修正失败:', error);
-                await sendMessage(msg.chat.id, '记录回款修正失败,请稍后重试');
+                console.error('快捷下发修正失败:', error);
+                await sendMessage(msg.chat.id, '记录下发修正失败,请稍后重试');
             }
         }
     }
@@ -762,32 +835,33 @@ async function generateBillMessage(chatId) {
             message += `<b>入款笔数</b>:<code>0</code>\n\n`;
         }
 
-        // 添加出款记录
-        if (withdrawals.length > 0) {
-            message += `<b>出款笔数</b>:<code>${withdrawals.length}</code>\n`;
-            withdrawals.forEach(withdrawal => {
-                message += `<code>${moment(withdrawal.time).format('HH:mm:ss')} ${parseFloat(withdrawal.amount).toFixed(2)}</code>\n`;
-            });
-            message += '\n';
-        } else {
-            message += `<b>出款笔数</b>:<code>0</code>\n\n`;
-        }
+        // // 添加出款记录
+        // if (withdrawals.length > 0) {
+        //     message += `<b>出款笔数</b>:<code>${withdrawals.length}</code>\n`;
+        //     withdrawals.forEach(withdrawal => {
+        //         message += `<code>${moment(withdrawal.time).format('HH:mm:ss')} ${parseFloat(withdrawal.amount).toFixed(2)}</code>\n`;
+        //     });
+        //     message += '\n';
+        // } else {
+        //     message += `<b>出款笔数</b>:<code>0</code>\n\n`;
+        // }
 
         // 添加费率信息
         message += `<b>入款费率</b>:<code>${inFeeRate}%</code>\n`;
         message += `<b>入款汇率</b>:<code>${inExchangeRate}</code>\n`;
         message += `<b>入款总额</b>:<code>${totalDeposit.toFixed(2)}</code>\n`;
-        message += `<b>入款合计</b>:<code>${(totalDeposit - depositFee).toFixed(2)}|${totalUDeposit.toFixed(2)}U</code>\n\n`;
+        message += `<b>入款合计</b>:<code>${totalDeposit.toFixed(2)}|${totalUDeposit.toFixed(2)}U</code>\n\n`;
 
-        message += `<b>出款费率</b>:<code>${outFeeRate}%</code>\n`;
-        message += `<b>出款汇率</b>:<code>${outExchangeRate}</code>\n`;
-        message += `<b>出款总额</b>:<code>${totalWithdrawal.toFixed(2)}</code>\n`;
-        message += `<b>出款合计</b>:<code>${(totalWithdrawal - withdrawalFee).toFixed(2)}|${totalUWithdrawal.toFixed(2)}U</code>\n\n`;
+        // message += `<b>出款费率</b>:<code>${outFeeRate}%</code>\n`;
+        // message += `<b>出款汇率</b>:<code>${outExchangeRate}</code>\n`;
+        // message += `<b>出款总额</b>:<code>${totalWithdrawal.toFixed(2)}</code>\n`;
+        // message += `<b>出款合计</b>:<code>${(totalWithdrawal - withdrawalFee).toFixed(2)}|${totalUWithdrawal.toFixed(2)}U</code>\n\n`;
 
         // 添加余额信息
-        message += `<b>应下发</b>:<code>${totalUDeposit.toFixed(2)}U</code>\n`;
+        const remainingAmount = totalUDeposit - totalUWithdrawal;
+        message += `<b>应下发</b>:<code>${(remainingAmount < 0 ? 0 : remainingAmount).toFixed(2)}U</code>\n`;
         message += `<b>已下发</b>:<code>${totalUWithdrawal.toFixed(2)}U</code>\n`;
-        message += `<b>未下发</b>:<code>${(totalUDeposit - totalUWithdrawal).toFixed(2)}U</code>`;
+        message += `<b>未下发</b>:<code>${(remainingAmount < 0 ? 0 : remainingAmount).toFixed(2)}U</code>`;
 
         console.log(`账单消息生成成功 - 群组ID: ${chatId}`);
         return message;

+ 88 - 5
admin/models/Transaction.js

@@ -112,7 +112,7 @@ const Transaction = {
 
             // 根据交易类型选择对应的费率和汇率
             const defaultFeeRate = transactionData.type === 'deposit' ? 
-                groupInfo[0].in_fee_rate : (100+parseFloat(groupInfo[0].out_fee_rate));
+                groupInfo[0].in_fee_rate : parseFloat(groupInfo[0].out_fee_rate);
             const defaultExchangeRate = transactionData.type === 'deposit' ? 
                 groupInfo[0].in_exchange_rate : groupInfo[0].out_exchange_rate;
 
@@ -143,11 +143,19 @@ const Transaction = {
                 totalUWithdrawal = parseFloat(lastRecord[0].totalUWithdrawal) || 0;
             }
 
-            // 计算本条交易的手续费
-            const currentFee = Math.abs(transactionData.amount) * (feeRate / 100);
+            // 计算本条交易的手续费和实际金额
+            let currentFee = 0;
+            let actualAmount = 0;
             
-            // 计算本条交易的实际金额(减去手续费)
-            const actualAmount = Math.abs(transactionData.amount) - currentFee;
+            if (transactionData.type === 'deposit') {
+                // 入款:手续费 = 金额 * 费率
+                currentFee = Math.abs(transactionData.amount) * (feeRate / 100);
+                actualAmount = Math.abs(transactionData.amount) - currentFee;
+            } else {
+                // 出款:实际金额 = 金额 * (1 + 费率)
+                actualAmount = Math.abs(transactionData.amount) * (1 + feeRate / 100);
+                currentFee = actualAmount - Math.abs(transactionData.amount);
+            }
             
             // 计算本条交易的U币金额(保持与金额相同的正负号)
             const uAmount = (actualAmount / exchangeRate) * (transactionData.amount < 0 ? -1 : 1);
@@ -266,6 +274,81 @@ const Transaction = {
         }
     },
 
+    // 下发方法
+    distribute: async (transactionData) => {
+        try {
+            // 获取上一条记录的总金额数据
+            const [lastRecord] = await pool.query(
+                'SELECT totalDeposit, totalWithdrawal, totalUDeposit, totalUWithdrawal FROM transactions WHERE group_id = ? ORDER BY time DESC LIMIT 1',
+                [transactionData.groupId]
+            );
+
+            // 初始化总金额数据
+            let totalDeposit = 0;
+            let totalWithdrawal = 0;
+            let totalUDeposit = 0;
+            let totalUWithdrawal = 0;
+
+            // 如果有上一条记录,使用其数据
+            if (lastRecord && lastRecord.length > 0) {
+                totalDeposit = parseFloat(lastRecord[0].totalDeposit) || 0;
+                totalWithdrawal = parseFloat(lastRecord[0].totalWithdrawal) || 0;
+                totalUDeposit = parseFloat(lastRecord[0].totalUDeposit) || 0;
+                totalUWithdrawal = parseFloat(lastRecord[0].totalUWithdrawal) || 0;
+            }
+
+            // 下发金额直接使用输入的U币金额
+            const uAmount = parseFloat(transactionData.amount);
+
+            // 更新总金额
+            totalUWithdrawal += uAmount; // 累加下发金额
+
+            const [result] = await pool.query(
+                `INSERT INTO transactions (
+                    group_id, group_name, type, amount, remark, operator_id, 
+                    fee_rate, exchange_rate, totalDeposit, totalWithdrawal,
+                    depositFee, withdrawalFee, totalUDeposit, totalUWithdrawal
+                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
+                [
+                    transactionData.groupId,
+                    transactionData.groupName,
+                    'distribute', // 使用withdrawal类型,因为distribute类型还未添加
+                    uAmount,
+                    transactionData.remark || null,
+                    transactionData.operatorId || 1,
+                    0, // fee_rate
+                    1, // exchange_rate
+                    totalDeposit,
+                    totalWithdrawal,
+                    0, // depositFee
+                    0, // withdrawalFee
+                    totalUDeposit,
+                    totalUWithdrawal
+                ]
+            );
+
+            const transaction = await Transaction.findById(result.insertId);
+            if (transaction) {
+                return {
+                    success: true,
+                    transaction,
+                    message: '下发记录创建成功'
+                };
+            } else {
+                return {
+                    success: false,
+                    message: '下发记录创建失败'
+                };
+            }
+        } catch (error) {
+            console.error('下发记录创建失败:', error);
+            return {
+                success: false,
+                message: '下发记录创建失败,请稍后重试'
+            };
+        }
+    },
+
     // 查询群组账单
     getGroupTransactions: async (groupId, options = {}) => {
         const {