import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.draw( int mode);
}
/**
* 初始化奖池
*
* @return 奖池
*/
public List<AwardItem> initAwardItem() {
List<AwardItem> list = new ArrayList<>(); //此处查数据库 获取 库存>0 且 概率>0 的奖项
list.add(new AwardItem(1, 1, 10000, "iphone"));
list.add(new AwardItem(2, 3, 10000, "耳机"));
list.add(new AwardItem(3, 5, 10000, "周卡"));
list.add(new AwardItem(4, 10, 10000, "次卡"));
list.add(new AwardItem(5, 20, 10000, "100元券"));
list.add(new AwardItem(6, 30, 10000, "300元券"));
list.add(new AwardItem(7, 50, 10000, "500元券"));
// 若无结果,则提示活动结束
if (list.size() == 0) {
throw new RuntimeException("正在努力补货中......");
}
// 业务处理,过滤掉本次不能抽中的奖项(自行处理)
return list;
}
/**
* 抽奖
*
* @param mode 1单次抽 2连连抽
*/
void draw(int mode) {
String uid = null; // 当前登录用户
// 1 检查 是否当前用户还有抽奖次数
int drawCount = 0; // 此处查询数据库当前用户本次活动还剩余的抽奖次数
if (drawCount < 1) {
throw new RuntimeException("您的抽奖次数已经用完");
}
// 计算本次循环抽多少次
// 1、如果是单次抽 循环1次
int count = 1;
// 2、如果是连连抽
if (mode == 2) {
count = 10; // 查询连连抽的次数
}
int usedCount = 0; //本轮抽奖所使用的次数
while (usedCount < count) {
usedCount++;
List<AwardItem> list = initAwardItem();
int awardItemId = doDraw(list);
if (awardItemId == -1) {
throw new RuntimeException("未中奖");
}
// 用当前奖品ID加redis锁(key='DRAW_ITEM_'+awardItemId),扣库存,剪掉用户本次抽奖次数
try {
// 处理中奖的数据
processingTheWinningData(awardItemId, uid);
} finally {
// 此处解锁redis锁(key='DRAW_ITEM_'+awardItemId)
}
}
}
/**
* 处理中奖数据
*
* @param awardItemID 奖项id
* @param uid 用户id
*/
void processingTheWinningData(int awardItemID, String uid) {
// 插入中奖记录 扣减中奖奖品的库存 和 用户抽奖次数
// 此处加事务
}
/**
* 执行抽奖
*
* @param list 奖池
* @return 中奖的奖项ID
*/
int doDraw(List<AwardItem> list) {
// 计算所有奖项权重总和
int sumWeight = list.stream().mapToInt(AwardItem::getProbability).sum();
// 此次中奖的随机数
int randomNum = (int) (Math.random() * sumWeight);
int min = 0;
int max = 0;
int selected = -1;
// 遍历奖池,找出中奖的奖项
for (int i = 0; i < list.size(); i++) {
if (i > 0) {
min = max;
}
max += list.get(i).getProbability();
if (randomNum >= min && randomNum < max) {
selected = i;
break;
}
}
return selected == -1 ? selected : list.get(selected).getId();
}
/**
* 奖项
*/
class AwardItem {
int id;
int probability; // 概率
int stock; // 库存
String name;
public AwardItem(int id, int probability, int stock, String name) {
this.id = id;
this.probability = probability;
this.stock = stock;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getProbability() {
return probability;
}
public void setProbability(int probability) {
this.probability = probability;
}
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
