init
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
package com.tailbet.service.impl;
|
||||
|
||||
import com.tailbet.model.entity.User;
|
||||
import com.tailbet.model.entity.GameRound;
|
||||
import com.tailbet.mapper.UserMapper;
|
||||
import com.tailbet.mapper.GameRoundMapper;
|
||||
import com.tailbet.service.IFakeUserService;
|
||||
import com.tailbet.service.IBetService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 假人服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class FakeUserServiceImpl implements IFakeUserService {
|
||||
|
||||
private final UserMapper userMapper;
|
||||
private final GameRoundMapper gameRoundMapper;
|
||||
private final IBetService betService;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
private static final String FAKE_ACTIVE_KEY = "fake:active:";
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
// 假人昵称素材
|
||||
private static final String[] NICKNAME_PREFIXES = {"小", "老", "阿", "超", "酷"};
|
||||
private static final String[] NICKNAME_SUFFIXES = {"哥", "弟", "姐", "妹", "宝"};
|
||||
|
||||
/**
|
||||
* 初始化群假人
|
||||
*/
|
||||
@Override
|
||||
public void initGroupFakeUsers(Long groupId, int minCount, int maxCount) {
|
||||
int count = minCount + RANDOM.nextInt(maxCount - minCount + 1);
|
||||
log.info("为群{}初始化{}个假人", groupId, count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
createFakeUser(groupId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建单个假人
|
||||
*/
|
||||
@Override
|
||||
public User createFakeUser(Long groupId) {
|
||||
User fake = new User();
|
||||
fake.setUsername("fake_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12));
|
||||
fake.setNickname(generateNickname());
|
||||
fake.setPoints((long) (1000 + RANDOM.nextInt(49000)));
|
||||
fake.setIsFake(1);
|
||||
fake.setIsBot(0);
|
||||
fake.setIsOps(0);
|
||||
fake.setIsWhite(0);
|
||||
fake.setStatus(1);
|
||||
userMapper.insert(fake);
|
||||
return fake;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机昵称
|
||||
*/
|
||||
private String generateNickname() {
|
||||
String prefix = NICKNAME_PREFIXES[RANDOM.nextInt(NICKNAME_PREFIXES.length)];
|
||||
String suffix = NICKNAME_SUFFIXES[RANDOM.nextInt(NICKNAME_SUFFIXES.length)];
|
||||
int number = RANDOM.nextInt(1000);
|
||||
return prefix + suffix + number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每日重置活跃假人
|
||||
*/
|
||||
@Override
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
public void resetDailyActiveFakes() {
|
||||
// 清理昨天的活跃标记
|
||||
Set<String> keys = redisTemplate.opsForSet().members(FAKE_ACTIVE_KEY + "yesterday");
|
||||
if (keys != null) {
|
||||
for (String userId : keys) {
|
||||
redisTemplate.opsForSet().remove(FAKE_ACTIVE_KEY + "yesterday", userId);
|
||||
}
|
||||
}
|
||||
|
||||
// 查询所有假人
|
||||
List<User> fakes = userMapper.selectList(new LambdaQueryWrapper<User>()
|
||||
.eq(User::getIsFake, 1)
|
||||
.eq(User::getStatus, 1));
|
||||
|
||||
if (fakes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 随机选15-20个作为今日活跃
|
||||
int activeCount = 15 + RANDOM.nextInt(6);
|
||||
activeCount = Math.min(activeCount, fakes.size());
|
||||
|
||||
Collections.shuffle(fakes);
|
||||
List<String> activeUserIds = new ArrayList<>();
|
||||
for (int i = 0; i < activeCount; i++) {
|
||||
activeUserIds.add(String.valueOf(fakes.get(i).getId()));
|
||||
}
|
||||
|
||||
// 存入Redis
|
||||
String today = java.time.LocalDate.now().toString();
|
||||
redisTemplate.opsForSet().add(FAKE_ACTIVE_KEY + today, activeUserIds.toArray(new String[0]));
|
||||
|
||||
log.info("今日活跃假人已更新: {}个", activeCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否是今日活跃假人
|
||||
*/
|
||||
@Override
|
||||
public boolean isTodayActiveFake(Long userId) {
|
||||
String today = java.time.LocalDate.now().toString();
|
||||
Boolean isMember = redisTemplate.opsForSet().isMember(FAKE_ACTIVE_KEY + today, String.valueOf(userId));
|
||||
return Boolean.TRUE.equals(isMember);
|
||||
}
|
||||
|
||||
/**
|
||||
* 假人下注
|
||||
*/
|
||||
@Override
|
||||
public void fakeBet(Long groupId) {
|
||||
// 获取今日活跃假人
|
||||
String today = java.time.LocalDate.now().toString();
|
||||
Set<String> activeFakes = redisTemplate.opsForSet().members(FAKE_ACTIVE_KEY + today);
|
||||
if (activeFakes == null || activeFakes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 随机选一个假人
|
||||
List<String> fakeList = new ArrayList<>(activeFakes);
|
||||
String fakeIdStr = fakeList.get(RANDOM.nextInt(fakeList.size()));
|
||||
Long fakeId = Long.parseLong(fakeIdStr);
|
||||
|
||||
// 检查是否有进行中的局
|
||||
GameRound round = gameRoundMapper.selectOne(new LambdaQueryWrapper<GameRound>()
|
||||
.eq(GameRound::getGroupId, groupId)
|
||||
.eq(GameRound::getStatus, 0));
|
||||
|
||||
if (round == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 随机玩法和金额
|
||||
String[] playTypes = {"单", "双", "大", "小"};
|
||||
String playType = playTypes[RANDOM.nextInt(playTypes.length)];
|
||||
int amount = (1 + RANDOM.nextInt(10)) * 10; // 10,20,30...100
|
||||
|
||||
try {
|
||||
betService.placeBet(fakeId, groupId, "fake_" + UUID.randomUUID(), playType, amount);
|
||||
log.debug("假人{}下注: {} {}", fakeId, playType, amount);
|
||||
} catch (Exception e) {
|
||||
log.debug("假人下注失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取假人列表
|
||||
*/
|
||||
@Override
|
||||
public List<User> getFakeUsers() {
|
||||
return userMapper.selectList(new LambdaQueryWrapper<User>()
|
||||
.eq(User::getIsFake, 1)
|
||||
.eq(User::getStatus, 1));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user