|
@@ -186,7 +186,7 @@ bot.on('message', async (msg) => {
|
|
operatorId: msg.from.id
|
|
operatorId: msg.from.id
|
|
};
|
|
};
|
|
|
|
|
|
- console.log(transactionData);
|
|
|
|
|
|
+ // console.log(transactionData);
|
|
|
|
|
|
try {
|
|
try {
|
|
const result = await Transaction.deposit(transactionData);
|
|
const result = await Transaction.deposit(transactionData);
|
|
@@ -740,410 +740,85 @@ bot.onText(/\/help/, (msg) => {
|
|
|
|
|
|
// - 4.群组信息更新
|
|
// - 4.群组信息更新
|
|
// 机器人被添加到群组
|
|
// 机器人被添加到群组
|
|
-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(formatLog({
|
|
|
|
- 操作: '处理机器人添加',
|
|
|
|
- 群组信息: groupInfo
|
|
|
|
- }));
|
|
|
|
-
|
|
|
|
- // 如果群组不存在,创建新群组
|
|
|
|
- if (!existingGroup) {
|
|
|
|
- const groupData = {
|
|
|
|
- groupId: chatIdStr,
|
|
|
|
- groupName: msg.chat.title || '未命名群组',
|
|
|
|
- groupType: chatType === 'private' ? 'personal' : chatType,
|
|
|
|
- creatorId: msg.from.id.toString()
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- // 检查群组是否已经存在
|
|
|
|
- const [existingGroupCheck] = await pool.query(
|
|
|
|
- 'SELECT * FROM groups WHERE group_id = ?',
|
|
|
|
- [chatIdStr]
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- if (existingGroupCheck && existingGroupCheck.length > 0) {
|
|
|
|
- console.log(formatLog({
|
|
|
|
- 操作: '群组已存在,更新状态',
|
|
|
|
- 群组ID: chatIdStr
|
|
|
|
- }));
|
|
|
|
-
|
|
|
|
- // 更新现有群组状态
|
|
|
|
- await pool.query(`
|
|
|
|
- UPDATE groups
|
|
|
|
- SET is_active = true,
|
|
|
|
- group_name = ?,
|
|
|
|
- group_type = ?,
|
|
|
|
- last_join_time = CURRENT_TIMESTAMP
|
|
|
|
- WHERE group_id = ?
|
|
|
|
- `, [
|
|
|
|
- groupData.groupName,
|
|
|
|
- groupData.groupType,
|
|
|
|
- chatIdStr
|
|
|
|
- ]);
|
|
|
|
- } else {
|
|
|
|
- // 创建新群组
|
|
|
|
- await pool.query(`
|
|
|
|
- INSERT INTO groups
|
|
|
|
- (group_id, group_name, group_type, creator_id, is_active, last_join_time,
|
|
|
|
- in_fee_rate, in_exchange_rate, out_fee_rate, out_exchange_rate, operators)
|
|
|
|
- VALUES (?, ?, ?, ?, true, CURRENT_TIMESTAMP, 0.00, 1.0000, 0.00, 1.0000, '[]')
|
|
|
|
- `, [
|
|
|
|
- groupData.groupId,
|
|
|
|
- groupData.groupName,
|
|
|
|
- groupData.groupType,
|
|
|
|
- groupData.creatorId
|
|
|
|
- ]);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 更新内存中的群组列表
|
|
|
|
- if (!data.allowedGroups.includes(chatIdStr)) {
|
|
|
|
- data.allowedGroups.push(chatIdStr);
|
|
|
|
- saveData();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- console.log(formatLog({
|
|
|
|
- 操作: '群组添加成功',
|
|
|
|
- 群组ID: chatIdStr,
|
|
|
|
- 群组名称: groupData.groupName
|
|
|
|
- }));
|
|
|
|
-
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error(formatLog({
|
|
|
|
- 错误: '创建群组失败',
|
|
|
|
- 详情: error.message,
|
|
|
|
- 群组ID: groupData.groupId
|
|
|
|
- }));
|
|
|
|
-
|
|
|
|
- // 检查是否是重复添加导致的错误
|
|
|
|
- if (error.code === 'ER_DUP_ENTRY') {
|
|
|
|
- console.log(formatLog({
|
|
|
|
- 操作: '检测到重复添加',
|
|
|
|
- 群组ID: chatIdStr
|
|
|
|
- }));
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- await bot.sendMessage(chatId, '添加群组失败,请联系管理员。', {
|
|
|
|
- parse_mode: 'HTML'
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error(formatLog({
|
|
|
|
- 错误: '处理群组添加失败',
|
|
|
|
- 详情: error.message
|
|
|
|
- }));
|
|
|
|
- await sendMessage(chatId, '添加群组失败,请联系管理员。');
|
|
|
|
|
|
+bot.on('new_chat_members', async (msg) => {
|
|
|
|
+ // 获取机器人ID
|
|
|
|
+ const botInfo = await bot.getMe();
|
|
|
|
+ // console.log('机器人信息:', botInfo);
|
|
|
|
+
|
|
|
|
+ // 检查是否机器人被添加
|
|
|
|
+ const botMember = msg.new_chat_members.find(member => member.id === botInfo.id);
|
|
|
|
+ if (!botMember) {
|
|
|
|
+ console.log('机器人未被添加,忽略事件');
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
-}
|
|
|
|
-// 处理群组信息更新
|
|
|
|
-async function handleGroupUpdate(msg, chatId, chatType, chatIdStr, existingGroup, newStatus, newType) {
|
|
|
|
- const connection = await pool.getConnection();
|
|
|
|
- await connection.beginTransaction();
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
- // 更新群组ID和类型
|
|
|
|
- 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();
|
|
|
|
-
|
|
|
|
- console.log(formatLog({
|
|
|
|
- 操作: '收到群组状态变更',
|
|
|
|
- 群组ID: chatIdStr,
|
|
|
|
- 群组名称: msg.chat.title,
|
|
|
|
- 旧状态: oldStatus,
|
|
|
|
- 新状态: newStatus,
|
|
|
|
- 群组类型: chatType
|
|
|
|
- }));
|
|
|
|
-
|
|
|
|
- // 定义群组类型
|
|
|
|
- const newType = chatType === 'private' ? 'personal' :
|
|
|
|
- chatType === 'supergroup' ? 'supergroup' : 'group';
|
|
|
|
-
|
|
|
|
- // 查找群组,同时检查新旧ID
|
|
|
|
- const existingGroup = await Group.findByGroupId(chatIdStr) ||
|
|
|
|
- await Group.findByGroupId(chatIdStr.replace('-', ''));
|
|
|
|
-
|
|
|
|
- // 如果是机器人首次被添加到群组(从非成员变为成员)
|
|
|
|
- if (oldStatus === 'left' && newStatus === 'member') {
|
|
|
|
- // 如果群组已存在且处于活跃状态,则发送欢迎消息
|
|
|
|
- if (existingGroup && existingGroup.is_active) {
|
|
|
|
- console.log(formatLog({
|
|
|
|
- 操作: '机器人重新加入群组',
|
|
|
|
- 群组ID: chatIdStr,
|
|
|
|
- 群组名称: msg.chat.title || existingGroup.group_name
|
|
|
|
- }));
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- // 发送欢迎消息
|
|
|
|
- await bot.sendMessage(chatId, '感谢重新添加我为群组成员!', {
|
|
|
|
- parse_mode: 'HTML'
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- // 发送账单消息
|
|
|
|
- const billMessage = await generateBillMessage(chatId);
|
|
|
|
- if (billMessage) {
|
|
|
|
- await bot.sendMessage(chatId, billMessage, {
|
|
|
|
- parse_mode: 'HTML',
|
|
|
|
- reply_markup: generateInlineKeyboard(chatId)
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error(formatLog({
|
|
|
|
- 错误: '发送消息失败',
|
|
|
|
- 详情: error.message,
|
|
|
|
- 群组ID: chatIdStr
|
|
|
|
- }));
|
|
|
|
- }
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ const chatId = msg.chat.id.toString();
|
|
|
|
+ const chatTitle = msg.chat.title || '未命名群组';
|
|
|
|
+ const creatorId = msg.from.id.toString();
|
|
|
|
|
|
- // 检查邀请者是否已存在于用户表中
|
|
|
|
- const [existingUser] = await pool.query(
|
|
|
|
- 'SELECT * FROM users WHERE id = ?',
|
|
|
|
- [msg.from.id]
|
|
|
|
- );
|
|
|
|
|
|
+ console.log('开始处理群组初始化:', {
|
|
|
|
+ chatId,
|
|
|
|
+ chatTitle,
|
|
|
|
+ creatorId
|
|
|
|
+ });
|
|
|
|
|
|
- // 如果用户不存在,则创建新用户
|
|
|
|
- if (!existingUser || existingUser.length === 0) {
|
|
|
|
- // 生成唯一的用户名
|
|
|
|
- const username = msg.from.username || `user_${msg.from.id}`;
|
|
|
|
-
|
|
|
|
- await pool.query(`
|
|
|
|
- INSERT INTO users
|
|
|
|
- (id, username, password, role)
|
|
|
|
- VALUES (?, ?, '', 'user')
|
|
|
|
- `, [msg.from.id, username]);
|
|
|
|
-
|
|
|
|
- console.log(formatLog({
|
|
|
|
- 操作: '新增用户',
|
|
|
|
- ID: msg.from.id,
|
|
|
|
- 用户名: username,
|
|
|
|
- 角色: 'user',
|
|
|
|
- 时间: new Date().toLocaleString()
|
|
|
|
- }));
|
|
|
|
- }
|
|
|
|
|
|
+ // 检查群组是否已存在
|
|
|
|
+ const [existingGroup] = await pool.query(
|
|
|
|
+ 'SELECT * FROM groups WHERE group_id = ?',
|
|
|
|
+ [chatId]
|
|
|
|
+ );
|
|
|
|
|
|
- if (!existingGroup) {
|
|
|
|
- await handleBotAdded(msg, chatId, chatType, chatIdStr, null);
|
|
|
|
- } else if (existingGroup.group_type !== newType) {
|
|
|
|
- await handleBotAdded(msg, chatId, chatType, chatIdStr, existingGroup);
|
|
|
|
|
|
+ if (!existingGroup || existingGroup.length === 0) {
|
|
|
|
+ // 创建新群组记录
|
|
|
|
+ await pool.query(`
|
|
|
|
+ INSERT INTO groups (
|
|
|
|
+ group_id,
|
|
|
|
+ group_name,
|
|
|
|
+ creator_id,
|
|
|
|
+ in_fee_rate,
|
|
|
|
+ out_fee_rate,
|
|
|
|
+ in_exchange_rate,
|
|
|
|
+ out_exchange_rate,
|
|
|
|
+ last_join_time,
|
|
|
|
+ created_at,
|
|
|
|
+ updated_at,
|
|
|
|
+ operators
|
|
|
|
+ ) VALUES (?, ?, ?, 0, 0, 1, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '[]')
|
|
|
|
+ `, [chatId, chatTitle, creatorId]);
|
|
|
|
+
|
|
|
|
+ // 将群组添加到允许列表
|
|
|
|
+ if (!data.allowedGroups.includes(chatId)) {
|
|
|
|
+ data.allowedGroups.push(chatId);
|
|
|
|
+ saveData();
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- if (existingGroup) {
|
|
|
|
- // 传递 newType 到 handleGroupUpdate 函数
|
|
|
|
- await handleGroupUpdate(msg, chatId, chatType, chatIdStr, existingGroup, newStatus, newType);
|
|
|
|
- } else if (newStatus === 'member') {
|
|
|
|
- // 如果是新群组且机器人被添加为成员
|
|
|
|
- await handleBotAdded(msg, chatId, chatType, chatIdStr, null);
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error(formatLog({
|
|
|
|
- 错误: '处理群组状态变更失败',
|
|
|
|
- 详情: error.message
|
|
|
|
- }));
|
|
|
|
- }
|
|
|
|
-});
|
|
|
|
-// 处理机器人被移出群组
|
|
|
|
-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 sendMessage(msg.chat.id, `感谢您添加我进入群组!\n\n我已初始化群组账单系统,您可以使用以下命令开始使用:\n\n• <code>/help</code> 查看使用指南\n• <code>/bill</code> 查看当前账单`);
|
|
|
|
+
|
|
|
|
+ console.log(`新群组初始化成功 - 群组: ${chatTitle}, ID: ${chatId}, 创建者: ${creatorId}, 时间: ${new Date().toLocaleString()}`);
|
|
|
|
+ } else {
|
|
|
|
+ // 更新群组信息
|
|
await pool.query(`
|
|
await pool.query(`
|
|
UPDATE groups
|
|
UPDATE groups
|
|
- SET is_active = false,
|
|
|
|
- last_leave_time = CURRENT_TIMESTAMP
|
|
|
|
|
|
+ SET group_name = ?,
|
|
|
|
+ last_join_time = CURRENT_TIMESTAMP,
|
|
|
|
+ updated_at = CURRENT_TIMESTAMP
|
|
WHERE group_id = ?
|
|
WHERE group_id = ?
|
|
- `, [chatId]);
|
|
|
|
|
|
+ `, [chatTitle, chatId]);
|
|
|
|
|
|
- // 从内存中的允许列表中移除
|
|
|
|
- const index = data.allowedGroups.indexOf(chatId);
|
|
|
|
- if (index > -1) {
|
|
|
|
- data.allowedGroups.splice(index, 1);
|
|
|
|
|
|
+ // 确保群组在允许列表中
|
|
|
|
+ if (!data.allowedGroups.includes(chatId)) {
|
|
|
|
+ data.allowedGroups.push(chatId);
|
|
saveData();
|
|
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));
|
|
|
|
|
|
+ await sendMessage(msg.chat.id, `我已重新加入群组!\n\n您可以使用 <code>/help</code> 查看使用指南`);
|
|
|
|
+ console.log(`群组信息更新成功 - 群组: ${chatTitle}, ID: ${chatId}, 时间: ${new Date().toLocaleString()}`);
|
|
}
|
|
}
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('处理新群组失败:', error);
|
|
|
|
+ await sendMessage(msg.chat.id, '初始化群组失败,请稍后重试');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|