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;}