From df5daf591080aa811c9b3660fdd045f14ccb1d72 Mon Sep 17 00:00:00 2001 From: wells <123456@qq.com> Date: Sun, 9 Aug 2026 19:49:14 +0800 Subject: [PATCH] =?UTF-8?q?fix=E7=99=BD=E5=90=8D=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tailbet/controller/GameController.java | 4 - .../java/com/tailbet/job/GameBroadcaster.java | 54 +++++++++--- .../com/tailbet/mapper/DigitWhiteMapper.java | 12 --- .../com/tailbet/model/entity/DigitWhite.java | 28 ------- .../tailbet/service/impl/PushServiceImpl.java | 84 +++++++++++++++---- src/main/resources/sql/init.sql | 18 ++-- 6 files changed, 120 insertions(+), 80 deletions(-) delete mode 100644 src/main/java/com/tailbet/mapper/DigitWhiteMapper.java delete mode 100644 src/main/java/com/tailbet/model/entity/DigitWhite.java diff --git a/src/main/java/com/tailbet/controller/GameController.java b/src/main/java/com/tailbet/controller/GameController.java index f1d0a2f..673fbc8 100644 --- a/src/main/java/com/tailbet/controller/GameController.java +++ b/src/main/java/com/tailbet/controller/GameController.java @@ -1,20 +1,17 @@ package com.tailbet.controller; import com.tailbet.job.GameJob; -import com.tailbet.mapper.DigitWhiteMapper; import com.tailbet.model.dto.BetDTO; import com.tailbet.model.dto.GameOperateDTO; import com.tailbet.model.dto.HistoryQueryDTO; import com.tailbet.model.dto.SetDigitDTO; import com.tailbet.model.entity.BetOrder; -import com.tailbet.model.entity.DigitWhite; import com.tailbet.model.entity.GameRound; import com.tailbet.model.vo.DigitTrialVo; import com.tailbet.model.vo.R; import com.tailbet.model.vo.UserContext; import com.tailbet.service.IBetService; import com.tailbet.service.IGameService; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -32,7 +29,6 @@ public class GameController { private final IGameService gameService; private final IBetService betService; private final GameJob gameJob; - private final DigitWhiteMapper digitWhiteMapper; /** * 开始游戏(群主) diff --git a/src/main/java/com/tailbet/job/GameBroadcaster.java b/src/main/java/com/tailbet/job/GameBroadcaster.java index 862057f..595034a 100644 --- a/src/main/java/com/tailbet/job/GameBroadcaster.java +++ b/src/main/java/com/tailbet/job/GameBroadcaster.java @@ -1,13 +1,13 @@ package com.tailbet.job; import com.tailbet.config.OpenIMProperties; -import com.tailbet.mapper.DigitWhiteMapper; import com.tailbet.mapper.DrawRecordMapper; import com.tailbet.mapper.GameRoundMapper; +import com.tailbet.mapper.GroupMemberMapper; import com.tailbet.mapper.UserMapper; -import com.tailbet.model.entity.DigitWhite; import com.tailbet.model.entity.DrawRecord; import com.tailbet.model.entity.GameRound; +import com.tailbet.model.entity.GroupMember; import com.tailbet.model.entity.User; import com.tailbet.openim.OpenIMApiClient; import com.tailbet.service.IGameService; @@ -17,6 +17,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * 游戏广播器 —— 把 OpenIM 消息发送逻辑从 {@link GameJob} 抽出 @@ -48,25 +50,57 @@ public class GameBroadcaster { private final OpenIMProperties openIMProperties; private final GameRoundMapper gameRoundMapper; private final DrawRecordMapper drawRecordMapper; - private final DigitWhiteMapper digitWhiteMapper; private final UserMapper userMapper; + private final GroupMemberMapper groupMemberMapper; private final IGameService gameService; /** - * 通知白名单用户(尾数试算完成) + * 通知当前群的白名单用户(尾数试算完成) + *

白名单以 {@code user.is_white=1} 为权威源,与本群成员({@code group_member})取交集后通知。 */ public void notifyWhiteUsers(Long roundId) { try { GameRound round = gameRoundMapper.selectById(roundId); if (round == null) return; + Long groupId = round.getGroupId(); - List whites = digitWhiteMapper.selectList(new LambdaQueryWrapper<>()); - for (DigitWhite white : whites) { - User user = userMapper.selectById(white.getUserId()); - if (user == null) continue; + // 1. 取本群成员用户ID集合(逻辑删除由全局配置自动过滤) + Set memberIds = groupMemberMapper.selectList( + new LambdaQueryWrapper() + .eq(GroupMember::getGroupId, groupId) + .select(GroupMember::getUserId)) + .stream() + .map(GroupMember::getUserId) + .collect(Collectors.toSet()); + if (memberIds.isEmpty()) { + log.debug("本局{}所属群{}无成员,跳过白名单通知", roundId, groupId); + return; + } - sendC2C(user.getId(), "尾数试算完成,请前往修改尾数。期号: " + round.getRoundNo()); - log.info("通知白名单用户尾数试算完成: userId={}, roundId={}", user.getId(), roundId); + // 2. 取白名单用户ID集合(user.is_white = 1) + Set whiteIds = userMapper.selectList( + new LambdaQueryWrapper() + .eq(User::getIsWhite, 1) + .select(User::getId)) + .stream() + .map(User::getId) + .collect(Collectors.toSet()); + if (whiteIds.isEmpty()) { + log.debug("无白名单用户,跳过通知: roundId={}", roundId); + return; + } + + // 3. 取交集:本群成员 � 白名单 + memberIds.retainAll(whiteIds); + if (memberIds.isEmpty()) { + log.debug("本局{}所属群{}无白名单成员,跳过通知", roundId, groupId); + return; + } + + String message = "尾数试算完成,请前往修改尾数。期号: " + round.getRoundNo(); + for (Long userId : memberIds) { + sendC2C(userId, message); + log.info("通知白名单用户尾数试算完成: userId={}, groupId={}, roundId={}", userId, groupId, roundId); } } catch (Exception e) { log.error("通知白名单用户失败: roundId={}, error={}", roundId, e.getMessage(), e); diff --git a/src/main/java/com/tailbet/mapper/DigitWhiteMapper.java b/src/main/java/com/tailbet/mapper/DigitWhiteMapper.java deleted file mode 100644 index 385bcb2..0000000 --- a/src/main/java/com/tailbet/mapper/DigitWhiteMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.tailbet.mapper; - -import com.tailbet.model.entity.DigitWhite; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Mapper; - -/** - * 尾数控制白名单Mapper - */ -@Mapper -public interface DigitWhiteMapper extends BaseMapper { -} diff --git a/src/main/java/com/tailbet/model/entity/DigitWhite.java b/src/main/java/com/tailbet/model/entity/DigitWhite.java deleted file mode 100644 index b4ec5bc..0000000 --- a/src/main/java/com/tailbet/model/entity/DigitWhite.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.tailbet.model.entity; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import java.time.LocalDateTime; - -/** - * 尾数控制白名单表 - */ -@Data -@TableName("digit_white") -public class DigitWhite { - - @TableId(type = IdType.AUTO) - private Long id; - - /** - * 用户ID - */ - private Long userId; - - /** - * 创建时间 - */ - private LocalDateTime createTime; -} diff --git a/src/main/java/com/tailbet/service/impl/PushServiceImpl.java b/src/main/java/com/tailbet/service/impl/PushServiceImpl.java index eff7ff3..af69cdf 100644 --- a/src/main/java/com/tailbet/service/impl/PushServiceImpl.java +++ b/src/main/java/com/tailbet/service/impl/PushServiceImpl.java @@ -2,8 +2,8 @@ package com.tailbet.service.impl; import com.tailbet.mapper.UserMapper; -import com.tailbet.mapper.DigitWhiteMapper; -import com.tailbet.model.entity.DigitWhite; +import com.tailbet.mapper.GroupMemberMapper; +import com.tailbet.model.entity.GroupMember; import com.tailbet.model.entity.User; import com.tailbet.openim.OpenIMApiClient; import com.tailbet.service.IPushService; @@ -13,6 +13,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * 推送服务实现 @@ -23,30 +25,76 @@ import java.util.List; public class PushServiceImpl implements IPushService { private final UserMapper userMapper; - private final DigitWhiteMapper digitWhiteMapper; + private final GroupMemberMapper groupMemberMapper; private final OpenIMApiClient openIMApiClient; private final com.tailbet.config.OpenIMProperties openIMProperties; /** - * 推送尾数试算完成通知给白名单用户 + * 推送尾数试算完成通知给当前群的白名单用户 + *

白名单以 {@code user.is_white=1} 为权威源,与本群成员({@code group_member})取交集后推送。 */ @Override public void pushDigitTrialComplete(Long groupId, Long roundId) { - List whites = digitWhiteMapper.selectList(new LambdaQueryWrapper()); - for (DigitWhite white : whites) { - User user = userMapper.selectById(white.getUserId()); - if (user != null) { - IPushService.PushMessage message = new IPushService.PushMessage(); - message.setType(PUSH_TYPE_DIGIT_TRIAL); - message.setTitle("尾数试算完成"); - message.setContent("可前往修改尾数"); - message.setUserId(user.getId()); - message.setGroupId(groupId); - message.setRoundId(roundId); - - sendPush(message); - } + // 1. 取本群成员用户ID集合 + Set memberIds = groupMemberMapper.selectList( + new LambdaQueryWrapper() + .eq(GroupMember::getGroupId, groupId) + .select(GroupMember::getUserId)) + .stream() + .map(GroupMember::getUserId) + .collect(Collectors.toSet()); + if (memberIds.isEmpty()) { + log.debug("群{}无成员,跳过白名单通知", groupId); + return; } + + // 2. 取白名单用户ID集合(user.is_white = 1) + Set whiteIds = userMapper.selectList( + new LambdaQueryWrapper() + .eq(User::getIsWhite, 1) + .select(User::getId)) + .stream() + .map(User::getId) + .collect(Collectors.toSet()); + if (whiteIds.isEmpty()) { + log.debug("无白名单用户,跳过通知: groupId={}", groupId); + return; + } + + // 3. 交集:本群成员 ∩ 白名单 + memberIds.retainAll(whiteIds); + if (memberIds.isEmpty()) { + log.debug("群{}无白名单成员,跳过通知", groupId); + return; + } + + IPushService.PushMessage template = new IPushService.PushMessage(); + template.setType(PUSH_TYPE_DIGIT_TRIAL); + template.setTitle("尾数试算完成"); + template.setContent("可前往修改尾数"); + template.setGroupId(groupId); + template.setRoundId(roundId); + + for (Long userId : memberIds) { + IPushService.PushMessage message = cloneMessage(template); + message.setUserId(userId); + sendPush(message); + } + } + + /** + * 克隆推送消息模板,避免多个用户共享同一对象 + */ + private IPushService.PushMessage cloneMessage(IPushService.PushMessage src) { + IPushService.PushMessage dst = new IPushService.PushMessage(); + dst.setType(src.getType()); + dst.setTitle(src.getTitle()); + dst.setContent(src.getContent()); + dst.setGroupId(src.getGroupId()); + dst.setRoundId(src.getRoundId()); + dst.setRoundNo(src.getRoundNo()); + dst.setDigit(src.getDigit()); + return dst; } /** diff --git a/src/main/resources/sql/init.sql b/src/main/resources/sql/init.sql index c94d893..f64ec7a 100644 --- a/src/main/resources/sql/init.sql +++ b/src/main/resources/sql/init.sql @@ -168,14 +168,16 @@ CREATE TABLE IF NOT EXISTS draw_record ( INDEX idx_group_time (group_id, create_time) ) COMMENT '开奖记录表'; --- 尾数控制白名单表 -CREATE TABLE IF NOT EXISTS digit_white ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - user_id BIGINT NOT NULL UNIQUE COMMENT '用户ID', - deleted TINYINT DEFAULT 0 COMMENT '逻辑删除', - create_time DATETIME DEFAULT CURRENT_TIMESTAMP, - INDEX idx_user (user_id) -) COMMENT '尾数控制白名单'; +-- 尾数控制白名单表(已废弃:白名单以 user.is_white 字段为准,digit_white 表不再被应用写入) +-- 如需彻底清理可执行: +-- DROP TABLE IF EXISTS `digit_white`; +-- CREATE TABLE IF NOT EXISTS digit_white ( +-- id BIGINT PRIMARY KEY AUTO_INCREMENT, +-- user_id BIGINT NOT NULL UNIQUE COMMENT '用户ID', +-- deleted TINYINT DEFAULT 0 COMMENT '逻辑删除', +-- create_time DATETIME DEFAULT CURRENT_TIMESTAMP, +-- INDEX idx_user (user_id) +-- ) COMMENT '尾数控制白名单'; -- 审计日志表 CREATE TABLE IF NOT EXISTS audit_log (