package com.tailbet.service.impl; import com.tailbet.mapper.UserMapper; import com.tailbet.mapper.DigitWhiteMapper; import com.tailbet.model.entity.DigitWhite; import com.tailbet.model.entity.User; import com.tailbet.openim.OpenIMApiClient; import com.tailbet.service.IPushService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; /** * 推送服务实现 */ @Slf4j @RequiredArgsConstructor @Service public class PushServiceImpl implements IPushService { private final UserMapper userMapper; private final DigitWhiteMapper digitWhiteMapper; private final OpenIMApiClient openIMApiClient; private final com.tailbet.config.OpenIMProperties openIMProperties; /** * 推送尾数试算完成通知给白名单用户 */ @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); } } } /** * 推送游戏开始通知 */ @Override public void pushGameStart(Long groupId, String roundNo) { IPushService.PushMessage message = new IPushService.PushMessage(); message.setType(PUSH_TYPE_GAME_START); message.setTitle("游戏开始"); message.setContent(roundNo + "期已开始下注"); message.setGroupId(groupId); message.setRoundNo(roundNo); // 推送给所有群成员 broadcastToGroup(groupId, message); } /** * 推送开奖结果通知 */ @Override public void pushGameResult(Long groupId, String roundNo, int digit, String playWins) { IPushService.PushMessage message = new IPushService.PushMessage(); message.setType(PUSH_TYPE_RESULT); message.setTitle("开奖结果"); message.setContent(roundNo + "期开奖\n尾数: " + digit + "\n中奖玩法: " + playWins); message.setGroupId(groupId); message.setRoundNo(roundNo); message.setDigit(digit); // 广播给所有群成员 broadcastToGroup(groupId, message); } /** * 发送单用户推送 */ @Override public void sendPush(IPushService.PushMessage message) { try { User user = userMapper.selectById(message.getUserId()); if (user == null) { log.warn("推送用户不存在: userId={}", message.getUserId()); return; } // 通过OpenIM单聊发送(生产环境可扩展FCM/APNs离线推送) openIMApiClient.sendMsg( openIMProperties.getAdminUserId(), String.valueOf(user.getId()), 1, // sessionType 1=单聊 101, // contentType 101=文本 java.util.Map.of("content", message.getTitle() + " - " + message.getContent()) ); log.info("推送发送成功: userId={}, type={}", message.getUserId(), message.getType()); } catch (Exception e) { log.error("推送发送失败: userId={}, type={}, error={}", message.getUserId(), message.getType(), e.getMessage()); } } /** * 广播推送消息给群成员 */ @Override public void broadcastToGroup(Long groupId, IPushService.PushMessage message) { try { // 通过OpenIM群消息发送(使用管理员身份发送) openIMApiClient.sendMsg( openIMProperties.getAdminUserId(), String.valueOf(groupId), 3, // sessionType 3=群聊 101, // contentType 101=文本 java.util.Map.of("content", message.getContent()) ); log.info("群广播发送成功: groupId={}, type={}", groupId, message.getType()); } catch (Exception e) { log.error("群广播发送失败: groupId={}, type={}, error={}", groupId, message.getType(), e.getMessage()); } } }