diff --git a/point_trade/config.toml b/point_trade/config.toml new file mode 100644 index 0000000..aa1e560 --- /dev/null +++ b/point_trade/config.toml @@ -0,0 +1,8 @@ +[PointTrade] +enable = true +command = ["积分交易", "积分转账", "转账积分", "积分赠送", "赠送积分", "积分转移", "转移积分", "送积分", "积分送人", "送人积分", "积分赠予", "赠予"] +command-format = """ +-----Bot----- +🔄转账积分: +积分转账 积分数 @用户 +""" \ No newline at end of file diff --git a/point_trade/main.py b/point_trade/main.py new file mode 100644 index 0000000..f4c3d8c --- /dev/null +++ b/point_trade/main.py @@ -0,0 +1,192 @@ +import logging +import tomllib +from datetime import datetime + +from wcferry import Wcf, WxMsg + +from robot_cmd.robot_command import GroupBotManager + +import xml.etree.ElementTree as ET + +import mysql.connector.pooling + + +class PointTrade: + description = "积分交易" + author = "shui niu" + version = "1.0.0" + + def __init__(self, wcf: Wcf, gbm: GroupBotManager, db_pool: mysql.connector.pooling.MySQLConnectionPool): + self.LOG = logging.getLogger(__name__) + self.wcf = wcf # 假设 wcf 对象在此类中初始化 + self.gbm = gbm # 权限功能 + self.db_pool = db_pool + with open("point_trade/config.toml", "rb") as f: + plugin_config = tomllib.load(f) + + config = plugin_config["Music"] + + self.enable = config["enable"] + self.command = config["command"] + self.command_format = config["command-format"] + self.LOG.info(f"[积分交易] 组件初始化完成,指令: {self.command}") + + def at_list(self, xml): + # xml demo内容 + # xml_data = ''' + # + # + # + # 1 + # 1 + # 5 + # V1_tTavqCYr|v1_tTavqCYr + # + # + # + # + # + # 1 + # + # + # ''' + # 解析 XML 数据 + root = ET.fromstring(xml) + + # 查找 元素并提取其文本内容 + atuserlist_element = root.find('.//atuserlist') + atuserlist_content = atuserlist_element.text if atuserlist_element is not None else '' + + # 去除前后的逗号,并按逗号分割成列表,然后转换成集合 + atuserlist_set = set(atuserlist_content.strip(',').split(',')) + + # 输出集合 + print("atuserlist 集合:", atuserlist_set) + return atuserlist_set + + def handle_text(self, message: WxMsg): + if not self.enable: + return + + content = str(message.content).strip() + command = content.split(" ") + + if command[0] not in self.command: + return + + if len(command) < 3: + self.wcf.send_text(f"-----Bot-----\n❌命令格式错误!{self.command_format}", + (message.roomid if message.from_group() else message.sender), message.sender) + return + if not command[1].isdigit(): + self.wcf.send_text(f"-----Bot-----\n🈚️转账积分无效(必须为正整数!) \n{self.command_format}", + (message.roomid if message.from_group() else message.sender), message.sender) + return + + if len(self.at_list(message.xml)) != 1: + self.wcf.send_text(f"-----Bot-----\n转账失败❌\n🈚️转账人无效! \n{self.command_format}", + (message.roomid if message.from_group() else message.sender), message.sender) + return + + reward_points = int(command[1]) + + target_wxid = next(iter(self.at_list(message.xml))) + trader_wxid = message.sender + group_id = message.roomid + # 查询发信人的记录(获取发信人当前积分) + sender_result = self._get_user_record(trader_wxid, group_id) + if not sender_result: + self.wcf.send_text(f"-----Bot-----\n❌打赏失败!\n没有找到你的记录,无法进行打赏!", + (message.roomid if message.from_group() else message.sender), message.sender) + return + + sender_user_id, sender_wx_id, sender_wx_nick_name, sender_current_points = sender_result + + # 如果发信人积分不足 + if sender_current_points < reward_points: + self.wcf.send_text( + f"-----Bot-----\n❌打赏失败!\n你的积分不足以进行打赏!当前积分:{sender_current_points},你需要 {reward_points} 积分。", + (message.roomid if message.from_group() else message.sender), message.sender) + return + + # 查询被打赏人的记录 + recipient_result = self._get_user_record_by_nick(target_wxid, group_id) + + if not recipient_result: + self.wcf.send_text( + f"-----Bot-----\n❌打赏失败!\n接收人[{target_wxid}]无法收取积分", + (message.roomid if message.from_group() else message.sender), message.sender) + return + + recipient_user_id, recipient_wx_id, recipient_wx_nick_name, recipient_current_points = recipient_result + + # 计算发信人和接收者的新积分 + new_sender_points = sender_current_points - reward_points + new_recipient_points = recipient_current_points + reward_points + + # 更新发信人和接收者的积分 + self._update_user_points(sender_user_id, new_sender_points) + self._update_user_points(recipient_user_id, new_recipient_points) + + output = ( + f"\n-----Bot-----\n" + f"✅积分赠送成功!✨\n" + f"🤝{sender_wx_nick_name} 现在有 {new_sender_points} 点积分➖\n" + f"🤝{recipient_wx_nick_name} 现在有 {new_recipient_points} 点积分➕\n" + f"⌚️时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" + ) + + self.wcf.send_text( + output, + (message.roomid if message.from_group() else message.sender), + ','.join({sender_user_id, recipient_user_id}) + ) + + def _get_db_connection(self): + """从连接池获取数据库连接""" + return self.db_pool.get_connection() + + def _get_user_record(self, wx_id, group_id): + """ + 查询用户的记录 + :param wx_id: 用户的微信ID + :param group_id: 群组ID + :return: 用户记录(id, wx_id, wx_nick_name, points) + """ + # 连接到数据库 + with self._get_db_connection() as conn: + with conn.cursor(dictionary=True) as cursor: + cursor.execute(""" + SELECT id, wx_id, wx_nick_name, points FROM t_sign_record + WHERE wx_id = %s AND group_id = %s + """, (wx_id, group_id)) + return cursor.fetchone() + + def _get_user_record_by_nick(self, wx_nick_name, group_id): + """ + 根据微信昵称查询用户的记录 + :param wx_nick_name: 用户的微信昵称 + :param group_id: 群组ID + :return: 用户记录(id, wx_id, wx_nick_name, points) + """ + with self._get_db_connection() as conn: + with conn.cursor(dictionary=True) as cursor: + cursor.execute(""" + SELECT id, wx_id, wx_nick_name, points FROM t_sign_record + WHERE wx_nick_name = %s AND group_id = %s + """, (wx_nick_name, group_id)) + return self.cursor.fetchone() + + def _update_user_points(self, user_id, new_points): + """ + 更新用户积分 + :param user_id: 用户ID + :param new_points: 新的积分数 + """ + with self._get_db_connection() as conn: + with conn.cursor(dictionary=True) as cursor: + cursor.execute(""" + UPDATE t_sign_record + SET points = %s, update_time = %s + WHERE id = %s + """, (new_points, datetime.now(), user_id)) diff --git a/robot.py b/robot.py index ec6fd6f..8fe3e85 100644 --- a/robot.py +++ b/robot.py @@ -33,6 +33,7 @@ from group_auto.group_member_change import GroupMemberChange from message_sign.main import SignInSystem from message_storage.message_to_db import MessageStorage from music.bot_music import BotMusic +from point_trade.main import PointTrade from robot_cmd.robot_command import GroupBotManager from job_mgmt import Job from robot_cmd.robot_command import Feature @@ -81,6 +82,8 @@ class Robot(Job): self.music = BotMusic(wcf, self.gbm) # 签到模块加载 self.signin = SignInSystem(wcf, self.gbm, self.allContacts, self.db_pool, self.redis_pool) + # 积分赠送功能加载 + self.trade = PointTrade(wcf, self.gbm, self.db_pool) if ChatType.is_in_chat_types(chat_type): if chat_type == ChatType.TIGER_BOT.value and TigerBot.value_check(self.config.TIGERBOT): @@ -335,7 +338,11 @@ class Robot(Job): except Exception as e: self.LOG.error(f"member_sign_in error: {e}") - #加入积分赠与功能 + # 加入积分赠与功能 + try: + self.trade.handle_text(message=msg) + except Exception as e: + self.LOG.error(f"point trade error: {e}") if msg.is_at(self.wxid): # 被@ self.toAt(msg)