抽奖活动 mark

it2022-05-08  8

import lombok.extern.slf4j.Slf4j;import org.redisson.api.RBucket;import org.redisson.api.RLock;import org.redisson.api.RMapCache;import org.redisson.api.RedissonClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.math.BigDecimal;import java.util.*;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;import java.util.stream.Collectors;/** * LotteryActivityRedisService 描述 * 抽奖活动 * @author tomas * @create 2018/10/24 **/@Slf4j@Service("lotteryActivityRedisServiceImpl")public class LotteryActivityRedisServiceImpl extends ActivityRedisService implements LotteryActivityRedisService {@Autowired private RedissonClient redissonClient; @Autowired private ActivityInfoMapper mapper; /** * 初始化 活动信息 * @param activityCode * @return */ @Override public ResultModel init(String activityCode){try { ActivityModel activityInfo = mapper.selectByCode(activityCode); if(null!=activityInfo ){ RBucket<ActivityModel> activityBucket = redissonClient.getBucket(String.format(ACTIVITY_KEY,activityCode)); activityBucket.set(activityInfo); if(new Date().after(activityInfo.getBeginTime())){return ResultModel.getError("非可初始化活动时间"); } //1.初始化奖品 String awardPoolMapKey = String.format(ACTIVITY_PRIZE_POOL_MAP_KEY,activityCode); Prize p1=Prize.builder().id(6).prizeName("30天免单券").prizeType("一等奖").prizeTotalNum(6).remainingPrize(6).prizeRate(0.002).build(); Prize p2=Prize.builder().id(7).prizeName("7天免单券").prizeType("二等奖").prizeTotalNum(30).remainingPrize(30).prizeRate(0.01).build(); Prize p3=Prize.builder().id(8).prizeName("7折优惠券").prizeType("三等奖").prizeTotalNum(0).remainingPrize(0).prizeRate(0.9988).def(true).build(); //Prize p4=Prize.builder().id(0L).prizeName("谢谢参与").prizeType("一等奖").prizeTotalNum(100000000L).remainingPrize(100000000L).prizeRate(0.001).build(); List<Prize> list=new ArrayList<>(); list.add(p1); list.add(p2); list.add(p3); RMapCache<Integer, Prize> mapCache = redissonClient.getMapCache(awardPoolMapKey); for (int i = 0; i < list.size(); i++) {//将奖项数据初始化到redis中 Prize p=list.get(i); mapCache.put(p.getId(),p,10, TimeUnit.DAYS); }//todo 多线程操作/异步操作 System.out.println("数据加载完成"); }return ResultModel.getSuccess("初始化活动成功"); }catch (Exception e){log.error("init activity Error activityCode ={} msg={} ",activityCode,e.getMessage()); }return ResultModel.getError("初始化活动失败"); }/** * 根据 code 和 userId 检查用户参与活动情况 * @param model * @return */ public ResultModel check(ActivityParamModel model){return ResultModel.getSuccess(); }/** * 参与抽奖 * @param model * @return */ public ResultModel lottery(ActivityParamModel model){/* 获取活动奖品列表 */ List<Prize> selectPrizeList = new ArrayList<>(); //获取可抽取的奖品及其的概率集合 Map<String, Object> optionalAwardMap = this.getAllAwardProbability(model.getCode()); //获取可选的奖品集合 selectPrizeList = (List<Prize>) optionalAwardMap.get("selectPrizeList"); //获取可选奖品集合的总概率 double probabilityTotal = (double) optionalAwardMap.get("probabilityTotal"); if (probabilityTotal < 1) {//当中奖概率不等于100%时,补充默认奖品 selectPrizeList = this.supplementDefaultAward( selectPrizeList, probabilityTotal, model.getCode()); }//生成抽奖用的概率集合 List<Double> probabilityResult = this.generatorAwardProbability(selectPrizeList); if(probabilityResult.size()<=0){return ResultModel.getError("没有可抽奖奖品"); }/* 实例化抽奖算法,并抽奖 */ AliasMethod aliasMethod = new AliasMethod(probabilityResult); /* 开始抽奖 */ int index = aliasMethod.next(); // 返回抽中奖品 Prize selectPrize = selectPrizeList.get(index); if (selectPrize != null) {//判断是否是默认的奖品,不是默认奖品 需要 redis 减Remaining 数量 if (!selectPrize.isDef()) { String awardPoolMapKey = String.format(ACTIVITY_PRIZE_POOL_MAP_KEY,model.getCode()); //默认返回数量为0 if (selectPrize.getRemainingPrize()!= null && selectPrize.getRemainingPrize() >= 1 ) { RLock lock = redissonClient.getLock(awardPoolMapKey.concat(String.valueOf(selectPrize.getId()))); lock.lock(200, TimeUnit.MILLISECONDS); selectPrize.setRemainingPrize(new AtomicInteger(selectPrize.getRemainingPrize()).decrementAndGet()); redissonClient.getMapCache(awardPoolMapKey).put(selectPrize.getId(),selectPrize); lock.unlock(); }else {return lottery(model); } }//判断是否 是安慰奖 if(!selectPrize.isComfort()){ } }return ResultModel.getSuccess(selectPrize); }/** * 分享功能 * @param model * @return */ public ResultModel share(ActivityParamModel model){return ResultModel.getSuccess(); }/** * 结束 活动开关 * @param activityCode * @return */ public ResultModel stop(String activityCode){return ResultModel.getSuccess(); }/** * @param selectAwardList 奖品选项 * @return * @Describe 生成奖品概率 */ private List<Double> generatorAwardProbability(List<Prize> selectAwardList) { List<Double> prob = new ArrayList<>(); try {/* 遍历所有奖品,取得奖品概率生成随机算法计算规则 */ for (Prize prize : selectAwardList) {double rate =prize.getPrizeRate().doubleValue(); prob.add(rate); }return prob; } catch (Exception e) {log.error(e.getMessage()); return new ArrayList<>(); } }/** * @param selectAwardList * @param probabilityTotal * @return * @Describe 补充默认的奖品 */ private List<Prize> supplementDefaultAward(List<Prize> selectAwardList, double probabilityTotal,String activityCode) {for (Prize prize : selectAwardList) {if(prize.isDef()){ String awardPoolMapKey = String.format(ACTIVITY_PRIZE_POOL_MAP_KEY,activityCode); BigDecimal bigDecimal = new BigDecimal(1 - probabilityTotal); prize.setPrizeRate(prize.getPrizeRate()+bigDecimal.doubleValue()); RLock lock = redissonClient.getLock(awardPoolMapKey.concat(String.valueOf(prize.getId())).concat("supply")); lock.lock(200, TimeUnit.MILLISECONDS); redissonClient.getMapCache(awardPoolMapKey).put(prize.getId(),prize); lock.unlock(); } }return selectAwardList; }/** * @param activityCode 活动id * @return * @Describe 获取所有的奖品概率 */ private Map<String, Object> getAllAwardProbability(String activityCode) {//返回的结果集 Map<String, Object> result = new HashMap<String, Object>(); /* 中奖率累计 */ double probabilityTotal = 0.0; /* 获取活动对应的奖品列表 */ List<Prize> prizeList = this.getPrizeList(activityCode); List<Prize> selectPrizeList = new ArrayList<>(); /* 奖品结果集 */ for (Prize prize : prizeList) {//查询奖品剩余的数量 //只有数量大于零 的奖品才能放到 selectPrizeList 中 if (null!=prize && prize.getRemainingPrize() > 0) {// 取出当前概率 double probability = prize.getPrizeRate(); probabilityTotal += probability; selectPrizeList.add(prize); } else {continue; } } result.put("probabilityTotal", probabilityTotal); result.put("selectPrizeList", selectPrizeList); return result; }/** * @Describe 获取活动对应的奖品列表 * @param activityCode * @return List<Prize>*/ private List<Prize> getPrizeList(String activityCode) { String awardPoolMapKey = String.format(ACTIVITY_PRIZE_POOL_MAP_KEY,activityCode); RMapCache<Integer, Prize> awardPoolMap = redissonClient.getMapCache(awardPoolMapKey); return awardPoolMap.readAllValues().stream().collect(Collectors.toList()); }}

转载于:https://www.cnblogs.com/wangdaijun/p/9849584.html


最新回复(0)