1.使用的数据结构
思路是需要将指定数量的红包提前压栈,然后当用户来“抢红包”的时候,将红包取出来。
规定每个用户只能抢一次,并且最小金额是1块钱。
选择redis中的list结构模拟。
2.模拟发红包。
@GetMapping("/give-red-packets")
public String access(Integer money,Integer count){//金额 和红包数量
if(count > money) return "金额有误";
String id = UUID.randomUUID().toString();
//分配金额
for(int i=count;i>0;i--){
int amount = getMoney(money,i);
redisTemplate.opsForList().rightPush(id,amount);
money-=amount;
}
return "红包id为"+id;
}
private int getMoney(Integer money, int i) {//i剩余多少人
if(i==1) return money;
int maxLimit = money - i + 2;
Random random = new Random();
int tmp = random.nextInt(maxLimit);
if(tmp == 0) tmp=1;
return tmp;
}
3.用户抢红包
将红包id和userId作为key,表明当前的红包是否已经被userId的用户抢过一次了。
//用户过来抢红包
@GetMapping("/grab-red-packets")
public String grab(String id,String userId){
long size = redisTemplate.opsForList().size(id);
if(size==0) return "红包已被抢完";
String lock = id + userId;
Integer money = redisTemplate.opsForValue().get(lock);//记录id的红包是否已经被当前用户抢过一次
//如果已经抢过了 那么不能抢第二次
if(money != null) return "您已经抢过了,金额是" + money;
money = redisTemplate.opsForList().rightPop(id);//取出一个红包
redisTemplate.opsForValue().set(lock,money);
return "抢到的红包金额" + money;
}