|
@@ -113,13 +113,15 @@ bot.on('message', async (msg) => {
|
|
|
const text = msg.text?.trim();
|
|
|
if (!text) return;
|
|
|
|
|
|
+ // 处理入款命令
|
|
|
if (text.startsWith('+')) {
|
|
|
const amount = parseFloat(text.substring(1));
|
|
|
if (!isNaN(amount)) {
|
|
|
const transactionData = {
|
|
|
groupId: msg.chat.id.toString(),
|
|
|
groupName: msg.chat.title || '未命名群组',
|
|
|
- amount: amount
|
|
|
+ amount: amount,
|
|
|
+ type: 'deposit'
|
|
|
};
|
|
|
|
|
|
try {
|
|
@@ -144,13 +146,50 @@ bot.on('message', async (msg) => {
|
|
|
await sendMessage(msg.chat.id, '记录入款失败,请稍后重试');
|
|
|
}
|
|
|
}
|
|
|
- } else if (text.startsWith('-')) {
|
|
|
+ }
|
|
|
+ // 处理入款修正命令
|
|
|
+ else if (text.startsWith('-') && !text.includes('u')) {
|
|
|
const amount = parseFloat(text.substring(1));
|
|
|
if (!isNaN(amount)) {
|
|
|
const transactionData = {
|
|
|
groupId: msg.chat.id.toString(),
|
|
|
groupName: msg.chat.title || '未命名群组',
|
|
|
- amount: amount
|
|
|
+ amount: -amount,
|
|
|
+ type: 'deposit'
|
|
|
+ };
|
|
|
+
|
|
|
+ try {
|
|
|
+ const result = await Transaction.deposit(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()}`);
|
|
|
+ } else {
|
|
|
+ await sendMessage(msg.chat.id, '入款修正成功,但获取账单信息失败');
|
|
|
+ console.log(`入款修正成功(无账单) - 群组: ${msg.chat.title}, 金额: -${amount}, 时间: ${new Date().toLocaleString()}`);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ await sendMessage(msg.chat.id, result.message || '入款修正失败');
|
|
|
+ console.log(`入款修正失败 - 群组: ${msg.chat.title}, 金额: -${amount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('快捷入款修正失败:', error);
|
|
|
+ await sendMessage(msg.chat.id, '记录入款修正失败,请稍后重试');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 处理回款命令
|
|
|
+ else if (text.toLowerCase().includes('u')) {
|
|
|
+ const amount = parseFloat(text.replace(/[^0-9.-]/g, ''));
|
|
|
+ if (!isNaN(amount)) {
|
|
|
+ const transactionData = {
|
|
|
+ groupId: msg.chat.id.toString(),
|
|
|
+ groupName: msg.chat.title || '未命名群组',
|
|
|
+ amount: amount,
|
|
|
+ type: 'withdrawal'
|
|
|
};
|
|
|
|
|
|
try {
|
|
@@ -161,18 +200,52 @@ bot.on('message', async (msg) => {
|
|
|
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}, 金额: ${amount}, 时间: ${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}, 金额: ${amount}, 时间: ${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}, 金额: ${amount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- console.error('快捷出款失败:', error);
|
|
|
- await sendMessage(msg.chat.id, '记录出款失败,请稍后重试');
|
|
|
+ console.error('快捷回款失败:', error);
|
|
|
+ await sendMessage(msg.chat.id, '记录回款失败,请稍后重试');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 处理回款修正命令
|
|
|
+ else if (text.toLowerCase().includes('u') && text.includes('-')) {
|
|
|
+ const amount = parseFloat(text.replace(/[^0-9.-]/g, ''));
|
|
|
+ if (!isNaN(amount)) {
|
|
|
+ const transactionData = {
|
|
|
+ groupId: msg.chat.id.toString(),
|
|
|
+ groupName: msg.chat.title || '未命名群组',
|
|
|
+ amount: -amount,
|
|
|
+ type: 'withdrawal'
|
|
|
+ };
|
|
|
+
|
|
|
+ try {
|
|
|
+ const result = await Transaction.withdrawal(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()}`);
|
|
|
+ } else {
|
|
|
+ await sendMessage(msg.chat.id, '回款修正成功,但获取账单信息失败');
|
|
|
+ console.log(`回款修正成功(无账单) - 群组: ${msg.chat.title}, 金额: -${amount}, 时间: ${new Date().toLocaleString()}`);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ await sendMessage(msg.chat.id, result.message || '回款修正失败');
|
|
|
+ console.log(`回款修正失败 - 群组: ${msg.chat.title}, 金额: -${amount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('快捷回款修正失败:', error);
|
|
|
+ await sendMessage(msg.chat.id, '记录回款修正失败,请稍后重试');
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -534,7 +607,7 @@ async function generateBillMessage(chatId) {
|
|
|
try {
|
|
|
// 获取群组的最后加入时间和费率信息
|
|
|
const [groupInfo] = await pool.query(
|
|
|
- 'SELECT last_join_time, fee_rate FROM groups WHERE group_id = ?',
|
|
|
+ 'SELECT last_join_time, in_fee_rate, in_exchange_rate, out_fee_rate, out_exchange_rate FROM groups WHERE group_id = ?',
|
|
|
[chatId.toString()]
|
|
|
);
|
|
|
|
|
@@ -543,7 +616,10 @@ async function generateBillMessage(chatId) {
|
|
|
}
|
|
|
|
|
|
const lastJoinTime = groupInfo[0].last_join_time;
|
|
|
- const feeRate = parseFloat(groupInfo[0].fee_rate) || 0;
|
|
|
+ const inFeeRate = parseFloat(groupInfo[0].in_fee_rate) || 0;
|
|
|
+ const inExchangeRate = parseFloat(groupInfo[0].in_exchange_rate) || 0;
|
|
|
+ const outFeeRate = parseFloat(groupInfo[0].out_fee_rate) || 0;
|
|
|
+ const outExchangeRate = parseFloat(groupInfo[0].out_exchange_rate) || 0;
|
|
|
|
|
|
// 获取机器人加入后的交易记录
|
|
|
const [records] = await pool.query(`
|
|
@@ -551,7 +627,6 @@ async function generateBillMessage(chatId) {
|
|
|
WHERE group_id = ?
|
|
|
AND DATE(time) = CURDATE()
|
|
|
ORDER BY time DESC
|
|
|
- LIMIT 10
|
|
|
`, [chatId.toString()]);
|
|
|
|
|
|
if (!records || records.length === 0) {
|
|
@@ -563,39 +638,55 @@ async function generateBillMessage(chatId) {
|
|
|
|
|
|
const totalDeposit = deposits.reduce((sum, d) => sum + parseFloat(d.amount), 0);
|
|
|
const totalWithdrawal = withdrawals.reduce((sum, w) => sum + parseFloat(w.amount), 0);
|
|
|
- const depositFee = totalDeposit * (feeRate / 100);
|
|
|
- const withdrawalFee = totalWithdrawal * (feeRate / 100);
|
|
|
+ const depositFee = totalDeposit * (inFeeRate / 100);
|
|
|
+ const withdrawalFee = totalWithdrawal * (outFeeRate / 100);
|
|
|
const remaining = totalDeposit - depositFee - totalWithdrawal - withdrawalFee;
|
|
|
+ const remainingU = (remaining / inExchangeRate).toFixed(2);
|
|
|
+
|
|
|
+ // 获取当前日期
|
|
|
+ const today = new Date();
|
|
|
+ const version = 'v29'; // 版本号
|
|
|
+ const dateStr = today.toISOString().split('T')[0].replace(/-/g, '-');
|
|
|
|
|
|
- let message = `📊 *账单明细*\n\n`;
|
|
|
+ let message = `当前版本:<b>${dateStr}:${version}</b>\n\n`;
|
|
|
|
|
|
// 添加入款记录
|
|
|
if (deposits.length > 0) {
|
|
|
- message += `💰 *入款记录* (${deposits.length}笔)\n`;
|
|
|
+ message += `<b>入款笔数</b>:<code>${deposits.length}</code>\n`;
|
|
|
deposits.forEach(deposit => {
|
|
|
- message += `• <code>${moment(deposit.time).format('HH:mm:ss')}</code> | ${parseFloat(deposit.amount).toFixed(2)}\n`;
|
|
|
+ message += `<code>${moment(deposit.time).format('HH:mm:ss')} ${parseFloat(deposit.amount).toFixed(2)}</code>\n`;
|
|
|
});
|
|
|
message += '\n';
|
|
|
+ } else {
|
|
|
+ message += `<b>入款笔数</b>:<code>0</code>\n\n`;
|
|
|
}
|
|
|
|
|
|
- // 添加下发记录
|
|
|
+ // 添加出款记录
|
|
|
if (withdrawals.length > 0) {
|
|
|
- message += `💸 *下发记录* (${withdrawals.length}笔)\n`;
|
|
|
+ message += `<b>出款笔数</b>:<code>${withdrawals.length}</code>\n`;
|
|
|
withdrawals.forEach(withdrawal => {
|
|
|
- message += `• <code>${moment(withdrawal.time).format('HH:mm:ss')}</code> | ${parseFloat(withdrawal.amount).toFixed(2)}\n`;
|
|
|
+ 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 += `📈 *统计信息*\n`;
|
|
|
- message += `• 总入款:${totalDeposit.toFixed(2)}\n`;
|
|
|
- message += `• 费率:${feeRate.toFixed(1)}%\n`;
|
|
|
- message += `• 应下发:${(totalDeposit - depositFee).toFixed(2)}\n`;
|
|
|
- message += `• 总下发:${totalWithdrawal.toFixed(2)}\n`;
|
|
|
- message += `• 下发单笔附加费:0.0\n`;
|
|
|
- message += `• 单笔附费加总计:0.0\n\n`;
|
|
|
- message += `💵 *余额:${remaining.toFixed(2)}*`;
|
|
|
+ // 添加费率信息
|
|
|
+ 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)}|${((totalDeposit - depositFee) / inExchangeRate).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)}|${((totalWithdrawal - withdrawalFee) / outExchangeRate).toFixed(2)}U</code>\n\n`;
|
|
|
+
|
|
|
+ // 添加余额信息
|
|
|
+ message += `<b>应下发</b>:<code>${remainingU}U</code>\n`;
|
|
|
+ message += `<b>已下发</b>:<code>${(totalWithdrawal / outExchangeRate).toFixed(2)}U</code>\n`;
|
|
|
+ message += `<b>未下发</b>:<code>${(remainingU - (totalWithdrawal / outExchangeRate)).toFixed(2)}U</code>`;
|
|
|
|
|
|
return message;
|
|
|
} catch (error) {
|