Bladeren bron

群组状态变更暂存

Taio_O 4 weken geleden
bovenliggende
commit
3a5748d791
3 gewijzigde bestanden met toevoegingen van 492 en 117 verwijderingen
  1. 6 3
      admin/config/initDb.js
  2. 459 112
      admin/index.js
  3. 27 2
      admin/数据文件路径

+ 6 - 3
admin/config/initDb.js

@@ -41,10 +41,11 @@ async function initDatabase() {
                 id INT AUTO_INCREMENT PRIMARY KEY,
                 group_id VARCHAR(255) NOT NULL UNIQUE,
                 group_name VARCHAR(255) NOT NULL,
-                group_type ENUM('personal', 'private', 'public') NOT NULL DEFAULT 'public' COMMENT '群组类型:个人用户/私聊群组/公开群组',
+                group_type ENUM('personal', 'group', 'supergroup') NOT NULL DEFAULT 'group' COMMENT '群组类型:个人用户/私聊群组/超级群组',
                 creator_id VARCHAR(255) NOT NULL,
                 is_active BOOLEAN DEFAULT true,
                 last_join_time DATETIME DEFAULT CURRENT_TIMESTAMP,
+                last_leave_time DATETIME DEFAULT CURRENT_TIMESTAMP,
                 created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                 updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
             )
@@ -54,11 +55,13 @@ async function initDatabase() {
         try {
             await pool.query(`
                 ALTER TABLE groups
-                ADD COLUMN group_type ENUM('personal', 'private', 'public') NOT NULL DEFAULT 'public' COMMENT '群组类型:个人用户/私聊群组/公开群组' AFTER group_name,
+                MODIFY COLUMN group_type ENUM('personal', 'group', 'supergroup') NOT NULL DEFAULT 'group' COMMENT '群组类型:个人用户/私聊群组/超级群组',
                 ADD COLUMN fee_rate DECIMAL(5,2) DEFAULT 0.00 COMMENT '费率' AFTER group_type,
                 ADD COLUMN exchange_rate DECIMAL(10,4) DEFAULT 1.0000 COMMENT '汇率' AFTER fee_rate,
                 ADD COLUMN admin_id INT NOT NULL COMMENT '管理员ID' AFTER exchange_rate,
-                ADD COLUMN last_join_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '机器人最后加入时间' AFTER is_active
+                ADD COLUMN last_join_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '机器人最后加入时间' AFTER is_active,
+                ADD COLUMN last_leave_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '机器人最后离开时间' AFTER last_join_time,
+                ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间' AFTER last_leave_time
             `);
         } catch (error) {
             // 如果列已存在,忽略错误

+ 459 - 112
admin/index.js

@@ -5,11 +5,31 @@ const path = require('path');
 const TelegramBot = require('node-telegram-bot-api');
 const fs = require('fs');
 const moment = require('moment');
-const { pool, testConnection } = require('./config/database');
+const {
+    pool,
+    testConnection
+} = require('./config/database');
 const initDatabase = require('./config/initDb');
 const Group = require('./models/Group');
 const Transaction = require('./models/Transaction');
 
+// 日志格式化函数
+function formatLog(data) {
+    const separator = '-'.repeat(30);
+    let logMessage = `${separator}\n`;
+
+    if (typeof data === 'object') {
+        logMessage += Object.entries(data)
+            .map(([key, value]) => `${key}: ${value}`)
+            .join('\n');
+    } else {
+        logMessage += data;
+    }
+
+    logMessage += `\n${separator}\n`;
+    return logMessage;
+}
+
 const app = express();
 
 // 初始化数据存储
@@ -17,11 +37,13 @@ let data = {
     deposits: [], // 入款记录
     withdrawals: [], // 下发记录
     lastUpdate: null,
-    allowedGroups: ['4754375683'] // 允许使用的群组ID
+    allowedGroups: [] // 允许使用的群组ID
 };
 
 // 创建机器人实例
-const bot = new TelegramBot(process.env.BOT_TOKEN, { polling: true });
+const bot = new TelegramBot(process.env.BOT_TOKEN, {
+    polling: true
+});
 
 // 中间件
 app.use(cors());
@@ -42,8 +64,8 @@ app.use('/api/settings', require('./routes/settingsRoutes'));
 // 检查群组权限
 function isGroupAllowed(chatId) {
     const chatIdStr = chatId.toString();
-    return data.allowedGroups.includes(chatIdStr) || 
-           data.allowedGroups.includes(chatIdStr.replace('-', ''));
+    return data.allowedGroups.includes(chatIdStr) ||
+        data.allowedGroups.includes(chatIdStr.replace('-', ''));
 }
 
 // 检查是否是管理员
@@ -59,11 +81,16 @@ async function sendMessage(chatId, text, options = {}) {
             const keyboard = generateInlineKeyboard(chatId);
             if (!keyboard) {
                 // 如果键盘无效,发送不带键盘的消息
-                return await bot.sendMessage(chatId, text, { parse_mode: 'HTML' });
+                return await bot.sendMessage(chatId, text, {
+                    parse_mode: 'HTML'
+                });
             }
             options.reply_markup = keyboard;
         }
-        return await bot.sendMessage(chatId, text, { ...options, parse_mode: 'HTML' });
+        return await bot.sendMessage(chatId, text, {
+            ...options,
+            parse_mode: 'HTML'
+        });
     } catch (error) {
         console.error('发送消息失败:', error);
         if (error.message.includes('bot was kicked from the group chat')) {
@@ -154,18 +181,15 @@ bot.on('message', async (msg) => {
 bot.on('new_chat_members', async (msg) => {
     const chatId = msg.chat.id;
     const newMembers = msg.new_chat_members;
-    
+
     for (const member of newMembers) {
         if (member.id === (await bot.getMe()).id) {
-            // 机器人被添加到群组
-            console.log(`机器人被添加到群组: ${chatId}`);
-            
             // 检查群组是否在允许列表中
             const chatIdStr = chatId.toString();
             try {
                 // 先检查数据库中是否存在该群组
                 const existingGroup = await Group.findByGroupId(chatIdStr);
-                
+
                 if (existingGroup) {
                     // 如果群组存在,更新群组状态为活跃,同时更新群组名称和加入时间
                     await pool.query(`
@@ -181,6 +205,13 @@ bot.on('new_chat_members', async (msg) => {
                         data.allowedGroups.push(chatIdStr);
                         saveData();
                     }
+                    // console.log(formatLog({
+                    //     ID: chatIdStr,
+                    //     名称: msg.chat.title || existingGroup.group_name,
+                    //     类型: msg.chat.type,
+                    //     状态: '重新激活',
+                    //     更新时间: new Date().toLocaleString()
+                    // }));
                     // 发送欢迎消息并显示当前账单
                     await sendMessage(chatId, '感谢重新添加我为群组成员!');
                     const billMessage = await generateBillMessage(chatId);
@@ -190,42 +221,149 @@ bot.on('new_chat_members', async (msg) => {
                         });
                     }
                 } else {
+                    // 如果是新群组,打印被添加到新群组的信息
+                    console.log(formatLog({
+                        ID: chatId,
+                        名称: msg.chat.title || '未命名群组',
+                        类型: msg.chat.type,
+                        描述: msg.chat.description || '无',
+                        '添加者信息': {
+                            ID: msg.from.id,
+                            用户名: msg.from.username || '无',
+                            姓名: msg.from.first_name,
+                            ...(msg.from.last_name && {
+                                姓: msg.from.last_name
+                            })
+                        },
+                        添加时间: new Date().toLocaleString()
+                    }));
+
                     // 如果群组不存在,创建新群组
                     const groupData = {
                         groupId: chatIdStr,
                         groupName: msg.chat.title || '未命名群组',
-                        groupType: msg.chat.type === 'private' ? 'personal' : 'public',
+                        groupType: msg.chat.type === 'private' ? 'personal' : msg.chat.type,
                         creatorId: msg.from.id.toString()
                     };
-                    
-                    const id = await Group.create({ 
-                        groupId: groupData.groupId, 
-                        groupName: groupData.groupName,
-                        creatorId: groupData.creatorId
-                    });  
-                    const group = await Group.findById(id);
-
-                    if (group) {
+
+                    console.log(formatLog(groupData));
+
+                    try {
+                        // 直接使用 SQL 插入群组数据
+                        const [result] = await pool.query(`
+                            INSERT INTO groups 
+                            (group_id, group_name, group_type, creator_id, is_active, last_join_time) 
+                            VALUES (?, ?, ?, ?, true, CURRENT_TIMESTAMP)
+                        `, [
+                            groupData.groupId,
+                            groupData.groupName,
+                            groupData.groupType,
+                            groupData.creatorId
+                        ]);
+
+                        console.log(formatLog(result));
+
                         // 更新内存中的群组列表
-                        data.allowedGroups.push(chatIdStr);
-                        saveData();
-                        await sendMessage(chatId, '感谢添加我为群组成员!使用 /help 查看可用命令。');
-                    } else {
-                        await sendMessage(chatId, '添加群组失败,请联系管理员。');
+                        if (!data.allowedGroups.includes(chatIdStr)) {
+                            data.allowedGroups.push(chatIdStr);
+                            saveData();
+                            console.log(formatLog({
+                                ID: chatIdStr,
+                                名称: groupData.groupName,
+                                类型: groupData.groupType,
+                                状态: '已启用',
+                                添加时间: new Date().toLocaleString(),
+                                操作者: msg.from.username || msg.from.first_name + ' (' + msg.from.id + ')'
+                            }));
+                        }
+
+                        console.log(formatLog({
+                            ID: chatIdStr,
+                            名称: groupData.groupName,
+                            类型: groupData.groupType,
+                            状态: '已启用',
+                            添加时间: new Date().toLocaleString(),
+                            操作者: msg.from.username || msg.from.first_name + ' (' + msg.from.id + ')'
+                        }));
+
+                        try {
+                            // 尝试发送欢迎消息
+                            const welcomeMessage = await bot.sendMessage(chatId, '感谢添加我为群组成员!使用 /help 查看可用命令。', {
+                                parse_mode: 'HTML'
+                            });
+                            console.log(formatLog(welcomeMessage));
+
+                            // 尝试发送账单消息
+                            const billMessage = await generateBillMessage(chatId);
+                            if (billMessage) {
+                                const billResult = await bot.sendMessage(chatId, billMessage, {
+                                    parse_mode: 'HTML',
+                                    reply_markup: generateInlineKeyboard(chatId)
+                                });
+                                console.log(formatLog(billResult));
+                            }
+                        } catch (messageError) {
+                            console.error(formatLog(messageError));
+                        }
+                    } catch (error) {
+                        console.error(formatLog('创建群组过程中出错', error));
+                        try {
+                            await bot.sendMessage(chatId, '添加群组失败,请联系管理员。', {
+                                parse_mode: 'HTML'
+                            });
+                        } catch (messageError) {
+                            console.error(formatLog('发送错误消息失败', messageError));
+                        }
                     }
                 }
             } catch (error) {
-                console.error('处理群组加入失败:', error);
+                console.error(formatLog('处理群组加入失败', error));
                 await sendMessage(chatId, '添加群组失败,请联系管理员。');
             }
         } else {
             // 其他新成员
-            console.log(`新成员加入群组: ${member.username || member.first_name} (${member.id})`);
+            console.log(formatLog({
+                member: member.username || member.first_name + ' (' + member.id + ')'
+            }));
             await sendMessage(chatId, `欢迎 ${member.username || member.first_name} 加入群组!`);
         }
     }
 });
 
+// 处理机器人被移出群组
+bot.on('left_chat_member', async (msg) => {
+    if (msg.left_chat_member.id === (await bot.getMe()).id) {
+        const chatId = msg.chat.id.toString();
+        try {
+            // 更新数据库中的群组状态
+            await pool.query(`
+                UPDATE groups 
+                SET is_active = false,
+                    last_leave_time = CURRENT_TIMESTAMP
+                WHERE group_id = ?
+            `, [chatId]);
+
+            // 从内存中的允许列表中移除
+            const index = data.allowedGroups.indexOf(chatId);
+            if (index > -1) {
+                data.allowedGroups.splice(index, 1);
+                saveData();
+            }
+
+            // console.log(formatLog({
+            //     ID: chatId,
+            //     名称: msg.chat.title || '未命名群组',
+            //     类型: msg.chat.type,
+            //     状态: '已移除',
+            //     移除时间: new Date().toLocaleString(),
+            //     操作者: msg.from.username || msg.from.first_name + ' (' + msg.from.id + ')'
+            // }));
+        } catch (error) {
+            console.error(formatLog('处理机器人被移出群组失败', error));
+        }
+    }
+});
+
 // 处理管理员命令
 bot.onText(/\/addgroup (.+)/, async (msg, match) => {
     if (!isAdmin(msg.from.id)) {
@@ -243,17 +381,26 @@ bot.onText(/\/addgroup (.+)/, async (msg, match) => {
                 groupType: 'public',
                 creatorId: msg.from.id.toString()
             };
-            
-            const result = await createGroup({ body: groupData });
+
+            const result = await createGroup({
+                body: groupData
+            });
             if (result) {
                 data.allowedGroups.push(groupId);
                 saveData();
+                console.log(formatLog({
+                    ID: groupId,
+                    名称: groupData.groupName,
+                    状态: '已启用',
+                    添加时间: new Date().toLocaleString(),
+                    操作者: msg.from.username || msg.from.first_name + ' (' + msg.from.id + ')'
+                }));
                 sendMessage(msg.chat.id, `群组 ${groupId} 已添加到允许列表。`);
             } else {
                 sendMessage(msg.chat.id, '添加群组失败,请检查群组ID是否正确。');
             }
         } catch (error) {
-            console.error('创建群组失败:', error);
+            console.error(formatLog('创建群组失败', error));
             sendMessage(msg.chat.id, '添加群组失败,请稍后重试。');
         }
     } else {
@@ -261,62 +408,6 @@ bot.onText(/\/addgroup (.+)/, async (msg, match) => {
     }
 });
 
-bot.onText(/\/removegroup (.+)/, async (msg, match) => {
-    if (!isAdmin(msg.from.id)) {
-        sendMessage(msg.chat.id, '您没有权限执行此命令。');
-        return;
-    }
-
-    const groupId = match[1].trim();
-    try {
-        // 使用 updateGroup 更新群组状态
-        const result = await updateGroup({ 
-            params: { id: groupId },
-            body: { isActive: false }
-        });
-        
-        if (result) {
-            const index = data.allowedGroups.indexOf(groupId);
-            if (index > -1) {
-                data.allowedGroups.splice(index, 1);
-                saveData();
-                sendMessage(msg.chat.id, `群组 ${groupId} 已从允许列表中移除。`);
-            } else {
-                sendMessage(msg.chat.id, '该群组不在允许列表中。');
-            }
-        } else {
-            sendMessage(msg.chat.id, '移除群组失败,请稍后重试。');
-        }
-    } catch (error) {
-        console.error('更新群组状态失败:', error);
-        sendMessage(msg.chat.id, '移除群组失败,请稍后重试。');
-    }
-});
-
-bot.onText(/\/listgroups/, async (msg) => {
-    if (!isAdmin(msg.from.id)) {
-        sendMessage(msg.chat.id, '您没有权限执行此命令。');
-        return;
-    }
-
-    try {
-        const groups = await pool.query('SELECT group_id, group_name, group_type, is_active FROM groups WHERE is_active = 1');
-        if (groups.length === 0) {
-            sendMessage(msg.chat.id, '当前没有允许的群组。');
-            return;
-        }
-
-        const groupsList = groups.map(group => 
-            `ID: ${group.group_id}\n名称: ${group.group_name}\n类型: ${group.group_type}\n状态: ${group.is_active ? '启用' : '禁用'}`
-        ).join('\n\n');
-        
-        sendMessage(msg.chat.id, `允许的群组列表:\n\n${groupsList}`);
-    } catch (error) {
-        console.error('获取群组列表失败:', error);
-        sendMessage(msg.chat.id, '获取群组列表失败,请稍后重试。');
-    }
-});
-
 // 处理入款命令
 bot.onText(/\/deposit (.+)/, async (msg, match) => {
     if (!isGroupAllowed(msg.chat.id)) {
@@ -354,7 +445,7 @@ bot.onText(/\/deposit (.+)/, async (msg, match) => {
             console.log(`入款失败 - 群组: ${msg.chat.title}, 金额: ${amount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
         }
     } catch (error) {
-        console.error('记录入款失败:', error);
+        console.error(formatLog('记录入款失败', error));
         await sendMessage(msg.chat.id, '记录入款失败,请稍后重试');
     }
 });
@@ -396,7 +487,7 @@ bot.onText(/\/withdraw (.+)/, async (msg, match) => {
             console.log(`出款失败 - 群组: ${msg.chat.title}, 金额: ${amount}, 原因: ${result.message}, 时间: ${new Date().toLocaleString()}`);
         }
     } catch (error) {
-        console.error('记录出款失败:', error);
+        console.error(formatLog('记录出款失败', error));
         await sendMessage(msg.chat.id, '记录出款失败,请稍后重试');
     }
 });
@@ -468,7 +559,7 @@ async function generateBillMessage(chatId) {
 
         const deposits = records.filter(r => r.type === 'deposit');
         const withdrawals = records.filter(r => r.type === 'withdrawal');
-        
+
         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);
@@ -507,7 +598,7 @@ async function generateBillMessage(chatId) {
 
         return message;
     } catch (error) {
-        console.error('生成账单消息失败:', error);
+        console.error(formatLog('生成账单消息失败', error));
         return '获取账单信息失败,请稍后重试';
     }
 }
@@ -516,18 +607,14 @@ async function generateBillMessage(chatId) {
 function generateInlineKeyboard(chatId) {
     const keyboard = {
         inline_keyboard: [
-            [
-                {
-                    text: '点击跳转完整账单',
-                    callback_data: `bill_page_${chatId}`
-                }
-            ],
-            [
-                {
-                    text: '24小时商务对接',
-                    callback_data: 'business_contact'
-                }
-            ]
+            [{
+                text: '点击跳转完整账单',
+                callback_data: `bill_page_${chatId}`
+            }],
+            [{
+                text: '24小时商务对接',
+                callback_data: 'business_contact'
+            }]
         ]
     };
     return keyboard;
@@ -550,7 +637,7 @@ bot.on('callback_query', async (callbackQuery) => {
             });
         }
     } catch (error) {
-        console.error('处理内联按钮回调失败:', error);
+        console.error(formatLog('处理内联按钮回调失败', error));
         await bot.answerCallbackQuery(callbackQuery.id, {
             text: '操作失败,请稍后重试',
             show_alert: true
@@ -563,7 +650,7 @@ function saveData() {
     try {
         fs.writeFileSync(process.env.DB_FILE, JSON.stringify(data, null, 2));
     } catch (error) {
-        console.error('Error saving data:', error);
+        console.error(formatLog('Error saving data', error));
     }
 }
 
@@ -572,10 +659,13 @@ function loadData() {
     try {
         if (fs.existsSync(process.env.DB_FILE)) {
             const savedData = JSON.parse(fs.readFileSync(process.env.DB_FILE));
-            data = { ...data, ...savedData };
+            data = {
+                ...data,
+                ...savedData
+            };
         }
     } catch (error) {
-        console.error('Error loading data:', error);
+        console.error(formatLog('Error loading data', error));
     }
 }
 
@@ -585,15 +675,272 @@ testConnection().then(() => {
 }).then(() => {
     // 加载数据
     loadData();
-    
+
     // 启动服务器
     const PORT = process.env.PORT || 3000;
     app.listen(PORT, () => {
-        console.log(`服务器运行在端口 ${PORT}`);
+        console.log(formatLog({
+            PORT: PORT
+        }));
         console.log('机器人已准备就绪!');
     });
 }).catch(error => {
-    console.error('启动失败:', error);
+    console.error(formatLog('启动失败', error));
     process.exit(1);
-}); 
+});
+
+// 处理机器人被添加到群组
+async function handleBotAdded(msg, chatId, chatType, chatIdStr, existingGroup) {
+    try {
+        // 获取群组链接
+        const chatInfo = await bot.getChat(chatId);
+        const groupInfo = {
+            ID: chatId,
+            名称: msg.chat.title || '未命名群组',
+            类型: chatType,
+            状态: existingGroup ? '重新激活' : '已激活',
+            群组链接: chatInfo.invite_link || '未设置',
+            更新时间: new Date().toLocaleString()
+        };
+        // console.log('机器人首次被添加到群组');
+        // console.log(formatLog(groupInfo));
+
+        // 如果群组不存在,创建新群组
+        if (!existingGroup) {
+            const groupData = {
+                groupId: chatIdStr,
+                groupName: msg.chat.title || '未命名群组',
+                groupType: chatType === 'private' ? 'private' : 'public',
+                creatorId: msg.from.id.toString()
+            };
+
+            const id = await Group.create({
+                groupId: groupData.groupId,
+                groupName: groupData.groupName,
+                creatorId: groupData.creatorId
+            });
+
+            if (id) {
+                // 更新内存中的群组列表
+                if (!data.allowedGroups.includes(chatIdStr)) {
+                    data.allowedGroups.push(chatIdStr);
+                    saveData();
+                }
+                console.log('机器人首次被添加到群组');
+                console.log(formatLog(groupInfo));
+                await sendMessage(chatId, '感谢添加我为群组成员!使用 /help 查看可用命令。');
+            } else {
+                await sendMessage(chatId, '添加群组失败,请联系管理员。');
+            }
+        }
+    } catch (error) {
+        console.error(formatLog({
+            错误: '处理机器人首次加入群组失败',
+            详情: error.message
+        }));
+        await sendMessage(chatId, '添加群组失败,请联系管理员。');
+    }
+}
+
+// 处理群组信息更新
+async function handleGroupUpdate(msg, chatId, chatType, chatIdStr, existingGroup, newStatus) {
+    const connection = await pool.getConnection();
+    await connection.beginTransaction();
+
+    try {
+        // 更新群组ID和类型
+        const newType = chatType === 'private' ? 'private' :
+            chatType === 'supergroup' ? 'supergroup' : 'group';
+        const oldGroupId = existingGroup.group_id;
+
+        // 如果群组ID发生变化,更新所有相关记录
+        if (existingGroup.group_type != newType) {
+            console.log(formatLog({
+                操作: '群组类型更新',
+                名称: msg.chat.title || existingGroup.group_name,
+                旧ID: oldGroupId,
+                新ID: chatIdStr,
+                旧类型: existingGroup.group_type,
+                新类型: newType,
+                状态: newStatus !== 'kicked' && newStatus !== 'left' ? '活跃' : '已移除'
+            }));
+
+            // 开始事务
+            await connection.beginTransaction();
+
+            try {
+                // 检查目标ID是否已存在
+                const [existingTargetGroup] = await connection.query(
+                    'SELECT * FROM groups WHERE group_id = ?',
+                    [chatIdStr]
+                );
+
+                if (existingTargetGroup && existingTargetGroup.length > 0) {
+                    // 更新交易记录
+                    await connection.query(`
+                        UPDATE transactions 
+                        SET group_id = ?
+                        WHERE group_id = ?
+                    `, [chatIdStr, oldGroupId]);
+
+                    // 更新资金记录
+                    await connection.query(`
+                        UPDATE money_records 
+                        SET group_id = ?
+                        WHERE group_id = ?
+                    `, [chatIdStr, oldGroupId]);
+
+                    // 删除旧群组记录
+                    await connection.query(
+                        'DELETE FROM groups WHERE group_id = ?',
+                        [oldGroupId]
+                    );
+
+                    // 更新目标群组信息
+                    await connection.query(`
+                        UPDATE groups 
+                        SET group_type = ?,
+                            group_name = ?,
+                            is_active = ?,
+                            updated_at = CURRENT_TIMESTAMP
+                        WHERE group_id = ?
+                    `, [
+                        newType,
+                        msg.chat.title || existingGroup.group_name,
+                        newStatus !== 'kicked' && newStatus !== 'left',
+                        chatIdStr
+                    ]);
+                } else {
+                    // 如果目标ID不存在,执行正常的更新操作
+                    // 先删除旧记录
+                    await connection.query(
+                        'DELETE FROM groups WHERE group_id = ?',
+                        [oldGroupId]
+                    );
+
+                    // 插入新记录
+                    await connection.query(`
+                        INSERT INTO groups 
+                        (group_id, group_name, group_type, creator_id, is_active, last_join_time) 
+                        VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
+                    `, [
+                        chatIdStr,
+                        msg.chat.title || existingGroup.group_name,
+                        newType,
+                        existingGroup.creator_id,
+                        newStatus !== 'kicked' && newStatus !== 'left'
+                    ]);
+
+                    // 更新交易记录
+                    await connection.query(`
+                        UPDATE transactions 
+                        SET group_id = ?
+                        WHERE group_id = ?
+                    `, [chatIdStr, oldGroupId]);
 
+                    // 更新资金记录
+                    await connection.query(`
+                        UPDATE money_records 
+                        SET group_id = ?
+                        WHERE group_id = ?
+                    `, [chatIdStr, oldGroupId]);
+                }
+
+                // 提交事务
+                await connection.commit();
+
+                // 更新内存中的群组列表
+                const index = data.allowedGroups.indexOf(oldGroupId);
+                if (index > -1) {
+                    if (newStatus === 'kicked' || newStatus === 'left') {
+                        data.allowedGroups.splice(index, 1);
+                    } else {
+                        data.allowedGroups[index] = chatIdStr;
+                    }
+                    saveData();
+                }
+            } catch (error) {
+                // 回滚事务
+                await connection.rollback();
+                console.error(formatLog('更新群组信息失败', error));
+                throw error;
+            }
+        } else {
+            // 如果ID没有变化,只更新其他信息
+            await connection.query(`
+                UPDATE groups 
+                SET group_type = ?,
+                    group_name = ?,
+                    is_active = ?,
+                    updated_at = CURRENT_TIMESTAMP
+                WHERE group_id = ?
+            `, [
+                newType,
+                msg.chat.title || existingGroup.group_name,
+                newStatus !== 'kicked' && newStatus !== 'left',
+                chatIdStr
+            ]);
+        }
+
+        await connection.commit();
+        console.log('【群组状态变更】');
+        console.log(formatLog({
+            ID: oldGroupId + ' -> ' + chatIdStr,
+            type: existingGroup.group_type + ' -> ' + newType,
+            name: existingGroup.group_name + ' -> ' + msg.chat.title || existingGroup.group_name,
+            status: newStatus === 'kicked' || newStatus === 'left' ? '已移除' : '活跃'
+        }));
+    } catch (error) {
+        await connection.rollback();
+        console.error(formatLog({
+            错误: '更新群组信息失败',
+            详情: error.message
+        }));
+        throw error;
+    } finally {
+        connection.release();
+    }
+}
+
+// 处理群组状态变更
+bot.on('my_chat_member', async (msg) => {
+    try {
+        const chatId = msg.chat.id;
+        const newStatus = msg.new_chat_member.status;
+        const oldStatus = msg.old_chat_member.status;
+        const chatType = msg.chat.type;
+        const chatIdStr = chatId.toString();
+
+        // 查找群组,同时检查新旧ID
+        const existingGroup = await Group.findByGroupId(chatIdStr) ||
+            await Group.findByGroupId(chatIdStr.replace('-', ''));
+
+        // 获取群组详细信息(如果机器人还在群组中)
+        if (newStatus !== 'kicked' && newStatus !== 'left') {
+            try {
+                const chatInfo = await bot.getChat(chatId);
+            } catch (error) {
+                console.log(formatLog('获取群组详细信息失败', error.message));
+            }
+        } else {
+            console.log('机器人已被移出群组,无法获取详细信息');
+        }
+
+        const newType = chatType === 'private' ? 'private' :
+            chatType === 'supergroup' ? 'supergroup' : 'group';
+            
+        // 如果是机器人首次被添加到群组(从非成员变为成员)
+        if (oldStatus === 'left' && newStatus === 'member' && existingGroup.group_type != newType) {
+            await handleBotAdded(msg, chatId, chatType, chatIdStr, existingGroup);
+        }
+
+        if (existingGroup) {
+            await handleGroupUpdate(msg, chatId, chatType, chatIdStr, existingGroup, newStatus);
+        }
+    } catch (error) {
+        console.error(formatLog({
+            错误: '处理群组状态变更失败',
+            详情: error.message
+        }));
+    }
+});

+ 27 - 2
admin/数据文件路径

@@ -16,8 +16,33 @@
   "withdrawals": [],
   "lastUpdate": "2025-05-07T03:00:11.021Z",
   "allowedGroups": [
-    "4754375683",
     "-4757139029",
-    "-4754375683"
+    "-4754375683",
+    "-1002676340401",
+    "-4782474181",
+    "-1002328843156",
+    "-4736540754",
+    "-4679143059",
+    "-4736190877",
+    "-1002508864668",
+    "-4781700605",
+    "-1002638601488",
+    "-4728758160",
+    "-1002507251732",
+    "-4689700915",
+    "-1002540995528",
+    "-4643654016",
+    "-1002639080928",
+    "-4782160269",
+    "-1002605840070",
+    "-4725391423",
+    "-1002687863096",
+    "-4638252809",
+    "-1002643652677",
+    "-1002511060617",
+    "-4726238942",
+    "-1002590582945",
+    "-4719273162",
+    "-1002602451051"
   ]
 }