修复签到bug
This commit is contained in:
@@ -117,3 +117,28 @@ CREATE TABLE IF NOT EXISTS message_archive.tasks
|
|||||||
)
|
)
|
||||||
comment '机器人定时任务表';
|
comment '机器人定时任务表';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 修改签到表,添加必要字段
|
||||||
|
ALTER TABLE t_sign_record ADD COLUMN last_continuous_days INT DEFAULT 0 COMMENT '历史最长连续签到天数';
|
||||||
|
ALTER TABLE t_sign_record ADD COLUMN total_sign_days INT DEFAULT 0 COMMENT '总签到天数';
|
||||||
|
ALTER TABLE t_sign_record ADD COLUMN last_sign_date DATETIME NULL COMMENT '上一次签到日期';
|
||||||
|
ALTER TABLE t_sign_record ADD COLUMN streak_start_sign_date DATETIME NULL COMMENT '连续签到第一天日期';
|
||||||
|
-- 添加断签前连签天数字段
|
||||||
|
ALTER TABLE t_sign_record ADD COLUMN previous_streak INT DEFAULT 0 COMMENT '断签前的连签天数';
|
||||||
|
|
||||||
|
|
||||||
|
-- 创建签到历史记录表
|
||||||
|
CREATE TABLE IF NOT EXISTS message_archive.t_sign_history (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '历史记录ID',
|
||||||
|
wx_id VARCHAR(100) NOT NULL COMMENT '用户微信ID',
|
||||||
|
group_id VARCHAR(100) NOT NULL COMMENT '群聊ID',
|
||||||
|
sign_date DATE NOT NULL COMMENT '签到日期',
|
||||||
|
sign_time DATETIME NOT NULL COMMENT '签到时间',
|
||||||
|
is_makeup TINYINT(1) DEFAULT 0 COMMENT '是否为补签',
|
||||||
|
points_earned INT DEFAULT 0 COMMENT '获得的积分',
|
||||||
|
streak_count INT DEFAULT 1 COMMENT '当时的连签天数',
|
||||||
|
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
|
||||||
|
INDEX idx_user_group (wx_id, group_id),
|
||||||
|
INDEX idx_sign_date (sign_date)
|
||||||
|
) COMMENT '用户签到历史记录表';
|
||||||
@@ -109,3 +109,20 @@ class SignInDB(BaseDBOperator):
|
|||||||
wx_id, group_id
|
wx_id, group_id
|
||||||
)
|
)
|
||||||
self.execute_update(sql, params)
|
self.execute_update(sql, params)
|
||||||
|
|
||||||
|
def update_sign_record_with_previous_streak(self, wx_id: str, group_id: str, wx_nick_name: str,
|
||||||
|
points_to_add: int, sign_time: datetime, streak: int,
|
||||||
|
last_sign_date: datetime, previous_streak: int) -> bool:
|
||||||
|
"""更新签到记录,包括上次签到日期和断签前连签天数"""
|
||||||
|
sql = """
|
||||||
|
UPDATE t_sign_record
|
||||||
|
SET wx_nick_name = %s, points = points + %s,
|
||||||
|
sign_stat = %s, signin_streak = %s,
|
||||||
|
last_sign_date = %s, previous_streak = %s, update_time = %s
|
||||||
|
WHERE wx_id = %s AND group_id = %s
|
||||||
|
"""
|
||||||
|
params = (wx_nick_name, points_to_add,
|
||||||
|
sign_time, streak,
|
||||||
|
last_sign_date, previous_streak, datetime.now(),
|
||||||
|
wx_id, group_id)
|
||||||
|
return self.execute_update(sql, params)
|
||||||
|
|||||||
@@ -244,6 +244,9 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
(roomid if roomid else sender), sender)
|
(roomid if roomid else sender), sender)
|
||||||
return False, "已签到"
|
return False, "已签到"
|
||||||
|
|
||||||
|
# 在_handle_sign_in方法中,修改断签处理逻辑
|
||||||
|
# 找到约在第247行的代码块
|
||||||
|
|
||||||
streak = 0
|
streak = 0
|
||||||
streak_broken = False
|
streak_broken = False
|
||||||
old_streak = 1
|
old_streak = 1
|
||||||
@@ -259,8 +262,11 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
old_streak = streak
|
old_streak = streak
|
||||||
streak_broken = False
|
streak_broken = False
|
||||||
else:
|
else:
|
||||||
|
# 断签时,保存之前的连签天数
|
||||||
streak = 1
|
streak = 1
|
||||||
streak_broken = True
|
streak_broken = True
|
||||||
|
# 保存断签前的连签天数,用于后续补签恢复
|
||||||
|
previous_streak = user_record['signin_streak']
|
||||||
else:
|
else:
|
||||||
streak = 1
|
streak = 1
|
||||||
|
|
||||||
@@ -273,12 +279,23 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
if user_record:
|
if user_record:
|
||||||
# 保存上次签到时间
|
# 保存上次签到时间
|
||||||
last_sign_date = user_record.get('sign_stat')
|
last_sign_date = user_record.get('sign_stat')
|
||||||
self.sign_in_db.update_sign_record_with_last_date(
|
|
||||||
sender, roomid, wx_nick_name,
|
# 如果断签,保存断签前的连签天数
|
||||||
points_to_add,
|
if streak_broken and user_record['signin_streak'] > 1:
|
||||||
current_time, streak,
|
self.sign_in_db.update_sign_record_with_previous_streak(
|
||||||
last_sign_date # 保存上次签到时间
|
sender, roomid, wx_nick_name,
|
||||||
)
|
points_to_add,
|
||||||
|
current_time, streak,
|
||||||
|
last_sign_date, # 保存上次签到时间
|
||||||
|
user_record['signin_streak'] # 保存断签前的连签天数
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.sign_in_db.update_sign_record_with_last_date(
|
||||||
|
sender, roomid, wx_nick_name,
|
||||||
|
points_to_add,
|
||||||
|
current_time, streak,
|
||||||
|
last_sign_date # 保存上次签到时间
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.sign_in_db.create_sign_record_with_last_date(
|
self.sign_in_db.create_sign_record_with_last_date(
|
||||||
sender, roomid, wx_nick_name,
|
sender, roomid, wx_nick_name,
|
||||||
@@ -334,23 +351,26 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
total_points = base_points + extra_points
|
total_points = base_points + extra_points
|
||||||
return min(total_points, self.max_point)
|
return min(total_points, self.max_point)
|
||||||
|
|
||||||
|
# 修改_handle_makeup_sign方法,实现连签恢复功能
|
||||||
|
|
||||||
def _handle_makeup_sign(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
def _handle_makeup_sign(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理补签请求"""
|
"""处理补签请求"""
|
||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
all_contacts = message.get("all_contacts", {})
|
all_contacts = message.get("all_contacts", {})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 获取当前时间,带有时区信息
|
# 获取当前时间,带有时区信息
|
||||||
current_time = datetime.now(tz=pytz.timezone(self.timezone))
|
current_time = datetime.now(tz=pytz.timezone(self.timezone))
|
||||||
|
today_date = current_time.date()
|
||||||
today_start = current_time.replace(hour=0, minute=0, second=0, microsecond=0)
|
today_start = current_time.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
yesterday = today_start - timedelta(days=1)
|
yesterday = today_start - timedelta(days=1)
|
||||||
day_before_yesterday = today_start - timedelta(days=2)
|
day_before_yesterday = today_start - timedelta(days=2)
|
||||||
|
|
||||||
# 获取用户的签到记录
|
# 获取用户的签到记录
|
||||||
user_record = self.get_user_record(sender, roomid)
|
user_record = self.get_user_record(sender, roomid)
|
||||||
wx_nick_name = all_contacts.get(sender, sender)
|
wx_nick_name = all_contacts.get(sender, sender)
|
||||||
|
|
||||||
# 检查用户是否有签到记录
|
# 检查用户是否有签到记录
|
||||||
if not user_record:
|
if not user_record:
|
||||||
self.message_util.send_text_msg(
|
self.message_util.send_text_msg(
|
||||||
@@ -358,25 +378,25 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
(roomid if roomid else sender), sender
|
(roomid if roomid else sender), sender
|
||||||
)
|
)
|
||||||
return True, "无签到记录"
|
return True, "无签到记录"
|
||||||
|
|
||||||
# 获取上次签到时间并规范化到零点
|
# 获取上次签到时间并规范化到零点
|
||||||
last_sign_date = None
|
last_sign_date = None
|
||||||
if user_record.get('last_sign_date'):
|
if user_record.get('last_sign_date'):
|
||||||
last_sign_date = user_record['last_sign_date'].replace(hour=0, minute=0, second=0, microsecond=0)
|
last_sign_date = user_record['last_sign_date'].replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
elif user_record.get('sign_stat'):
|
elif user_record.get('sign_stat'):
|
||||||
last_sign_date = user_record['sign_stat'].replace(hour=0, minute=0, second=0, microsecond=0)
|
last_sign_date = user_record['sign_stat'].replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
|
||||||
# 确保时区一致
|
# 确保时区一致
|
||||||
if isinstance(last_sign_date, datetime) and last_sign_date.tzinfo is None:
|
if isinstance(last_sign_date, datetime) and last_sign_date.tzinfo is None:
|
||||||
last_sign_date = pytz.timezone(self.timezone).localize(last_sign_date)
|
last_sign_date = pytz.timezone(self.timezone).localize(last_sign_date)
|
||||||
|
|
||||||
# 获取当前签到状态并规范化到零点
|
# 获取当前签到状态并规范化到零点
|
||||||
sign_stat = None
|
sign_stat = None
|
||||||
if user_record.get('sign_stat'):
|
if user_record.get('sign_stat'):
|
||||||
sign_stat = user_record['sign_stat'].replace(hour=0, minute=0, second=0, microsecond=0)
|
sign_stat = user_record['sign_stat'].replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
if sign_stat.tzinfo is None:
|
if sign_stat.tzinfo is None:
|
||||||
sign_stat = pytz.timezone(self.timezone).localize(sign_stat)
|
sign_stat = pytz.timezone(self.timezone).localize(sign_stat)
|
||||||
|
|
||||||
# 检查是否已经签到今天
|
# 检查是否已经签到今天
|
||||||
if sign_stat and sign_stat >= today_start:
|
if sign_stat and sign_stat >= today_start:
|
||||||
# 今天已经签到,检查是否需要补签昨天
|
# 今天已经签到,检查是否需要补签昨天
|
||||||
@@ -400,7 +420,7 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
(roomid if roomid else sender), sender
|
(roomid if roomid else sender), sender
|
||||||
)
|
)
|
||||||
return True, "不符合补签条件"
|
return True, "不符合补签条件"
|
||||||
|
|
||||||
if last_sign_date >= yesterday:
|
if last_sign_date >= yesterday:
|
||||||
self.LOG.info(f"昨天已签到,last_sign_date: {last_sign_date}")
|
self.LOG.info(f"昨天已签到,last_sign_date: {last_sign_date}")
|
||||||
self.message_util.send_text_msg(
|
self.message_util.send_text_msg(
|
||||||
@@ -408,67 +428,95 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
(roomid if roomid else sender), sender
|
(roomid if roomid else sender), sender
|
||||||
)
|
)
|
||||||
return True, "无需补签"
|
return True, "无需补签"
|
||||||
|
|
||||||
# 检查用户积分是否足够
|
# 检查用户积分是否足够
|
||||||
from db.points_db import PointsDBOperator, PointSource
|
from db.points_db import PointsDBOperator, PointSource
|
||||||
points_db = PointsDBOperator(self.db_manager)
|
points_db = PointsDBOperator(self.db_manager)
|
||||||
user_points = points_db.get_user_points(sender, roomid)
|
user_points = points_db.get_user_points(sender, roomid)
|
||||||
|
|
||||||
if not user_points or user_points["total_points"] < self.makeup_cost:
|
if not user_points or user_points["total_points"] < self.makeup_cost:
|
||||||
self.message_util.send_text_msg(
|
self.message_util.send_text_msg(
|
||||||
f"❌ 积分不足!补签需要 {self.makeup_cost} 积分,您当前只有 {user_points.get('total_points', 0)} 积分。",
|
f"❌ 积分不足!补签需要 {self.makeup_cost} 积分,您当前只有 {user_points.get('total_points', 0)} 积分。",
|
||||||
(roomid if roomid else sender), sender
|
(roomid if roomid else sender), sender
|
||||||
)
|
)
|
||||||
return True, "积分不足"
|
return True, "积分不足"
|
||||||
|
|
||||||
# 扣除积分
|
# 扣除积分
|
||||||
deduct_success, deduct_result = points_db.deduct_points(
|
deduct_success, deduct_result = points_db.deduct_points(
|
||||||
sender, roomid, self.makeup_cost, PointSource.PLUGIN,
|
sender, roomid, self.makeup_cost, PointSource.PLUGIN,
|
||||||
"签到补签消费"
|
"签到补签消费"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not deduct_success:
|
if not deduct_success:
|
||||||
self.message_util.send_text_msg(
|
self.message_util.send_text_msg(
|
||||||
f"❌ 扣除积分失败:{deduct_result.get('error', '未知错误')}",
|
f"❌ 扣除积分失败:{deduct_result.get('error', '未知错误')}",
|
||||||
(roomid if roomid else sender), sender
|
(roomid if roomid else sender), sender
|
||||||
)
|
)
|
||||||
return True, "扣除积分失败"
|
return True, "扣除积分失败"
|
||||||
|
|
||||||
# 获取原连签天数
|
# 获取原连签天数和断签前连签天数
|
||||||
original_streak = user_record['signin_streak']
|
original_streak = user_record['signin_streak']
|
||||||
|
previous_streak = user_record.get('previous_streak', 0)
|
||||||
|
|
||||||
|
# 计算新的连签天数
|
||||||
|
new_streak = original_streak
|
||||||
|
|
||||||
|
# 如果今天已签到且有断签前记录,恢复连签
|
||||||
|
if sign_stat and sign_stat >= today_start and previous_streak > 0:
|
||||||
|
# 恢复连签:断签前连签天数 + 1 (今天已签到)
|
||||||
|
new_streak = previous_streak + 1
|
||||||
|
self.LOG.info(f"恢复连签: {previous_streak} + 1 = {new_streak}")
|
||||||
|
# 如果今天未签到且有断签前记录,也可以恢复连签
|
||||||
|
elif previous_streak > 0:
|
||||||
|
# 恢复连签:断签前连签天数
|
||||||
|
new_streak = previous_streak
|
||||||
|
self.LOG.info(f"恢复连签: {previous_streak}")
|
||||||
|
# 如果没有断签前记录,则连签天数+1
|
||||||
|
else:
|
||||||
|
new_streak = original_streak + 1
|
||||||
|
self.LOG.info(f"普通补签: {original_streak} + 1 = {new_streak}")
|
||||||
|
|
||||||
# 更新签到记录
|
# 更新签到记录
|
||||||
yesterday_time = yesterday.replace(hour=current_time.hour, minute=current_time.minute,
|
yesterday_time = yesterday.replace(hour=current_time.hour, minute=current_time.minute,
|
||||||
second=current_time.second)
|
second=current_time.second)
|
||||||
|
|
||||||
# 如果今天已经签到,则更新last_sign_date为昨天,保持sign_stat不变
|
# 如果今天已经签到,则更新last_sign_date为昨天,保持sign_stat不变
|
||||||
if sign_stat and sign_stat >= today_start:
|
if sign_stat and sign_stat >= today_start:
|
||||||
self.sign_in_db.update_makeup_sign(
|
self.sign_in_db.update_makeup_sign_with_streak_recovery(
|
||||||
sender, roomid, wx_nick_name,
|
sender, roomid, wx_nick_name,
|
||||||
0, # 补签不增加积分
|
0, # 补签不增加积分
|
||||||
sign_stat, original_streak + 1,
|
sign_stat, new_streak,
|
||||||
yesterday_time # 设置last_sign_date为昨天
|
yesterday_time, # 设置last_sign_date为昨天
|
||||||
|
0 # 清除previous_streak,因为已经恢复了
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# 如果今天没签到,则更新sign_stat为昨天,last_sign_date为上次签到时间
|
# 如果今天没签到,则更新sign_stat为昨天,last_sign_date为上次签到时间
|
||||||
self.sign_in_db.update_sign_record_with_last_date(
|
self.sign_in_db.update_sign_record_with_streak_recovery(
|
||||||
sender, roomid, wx_nick_name,
|
sender, roomid, wx_nick_name,
|
||||||
0, # 补签不增加积分
|
0, # 补签不增加积分
|
||||||
yesterday_time, original_streak + 1,
|
yesterday_time, new_streak,
|
||||||
last_sign_date # 保留原来的last_sign_date
|
last_sign_date, # 保留原来的last_sign_date
|
||||||
|
0 # 清除previous_streak,因为已经恢复了
|
||||||
)
|
)
|
||||||
|
|
||||||
# 发送成功消息
|
# 发送成功消息
|
||||||
|
success_message = f"✅ 补签成功!\n💰 消费 {self.makeup_cost} 积分\n"
|
||||||
|
|
||||||
|
# 如果恢复了连签,显示恢复信息
|
||||||
|
if new_streak > original_streak + 1:
|
||||||
|
success_message += f"🎉 恢复连签!连续签到天数:{new_streak}\n"
|
||||||
|
else:
|
||||||
|
success_message += f"🔄 连续签到天数:{new_streak}\n"
|
||||||
|
|
||||||
|
success_message += f"💰 当前积分:{user_points['total_points'] - self.makeup_cost}"
|
||||||
|
|
||||||
self.message_util.send_text_msg(
|
self.message_util.send_text_msg(
|
||||||
f"✅ 补签成功!\n"
|
success_message,
|
||||||
f"💰 消费 {self.makeup_cost} 积分\n"
|
|
||||||
f"🔄 连续签到天数:{original_streak + 1}\n"
|
|
||||||
f"💰 当前积分:{user_points['total_points'] - self.makeup_cost}",
|
|
||||||
(roomid if roomid else sender), sender
|
(roomid if roomid else sender), sender
|
||||||
)
|
)
|
||||||
|
|
||||||
return True, "补签成功"
|
return True, "补签成功"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.LOG.error(f"处理补签请求出错: {e}")
|
self.LOG.error(f"处理补签请求出错: {e}")
|
||||||
self.message_util.send_text_msg(
|
self.message_util.send_text_msg(
|
||||||
|
|||||||
Reference in New Issue
Block a user