午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java實(shí)現(xiàn)抽獎(jiǎng)功能

瀏覽:14日期:2022-08-20 13:48:29

本文實(shí)例為大家分享了Java實(shí)現(xiàn)抽獎(jiǎng)功能的具體代碼,供大家參考,具體內(nèi)容如下

1 概述

項(xiàng)目開(kāi)發(fā)中經(jīng)常會(huì)有抽獎(jiǎng)這樣的營(yíng)銷活動(dòng)的需求,例如:積分大轉(zhuǎn)盤(pán)、刮刮樂(lè)、老虎機(jī)等等多種形式,其實(shí)后臺(tái)的實(shí)現(xiàn)方法是一樣的,本文介紹一種常用的抽獎(jiǎng)實(shí)現(xiàn)方法。

整個(gè)抽獎(jiǎng)過(guò)程包括以下幾個(gè)方面:

獎(jiǎng)品 獎(jiǎng)品池 抽獎(jiǎng)算法 獎(jiǎng)品限制 獎(jiǎng)品發(fā)放

2 獎(jiǎng)品

獎(jiǎng)品包括獎(jiǎng)品、獎(jiǎng)品概率和限制、獎(jiǎng)品記錄。獎(jiǎng)品表:

CREATE TABLE `points_luck_draw_prize` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL COMMENT ’獎(jiǎng)品名稱’, `url` varchar(50) DEFAULT NULL COMMENT ’圖片地址’, `value` varchar(20) DEFAULT NULL, `type` tinyint(4) DEFAULT NULL COMMENT ’類型1:紅包2:積分3:體驗(yàn)金4:謝謝惠顧5:自定義’, `status` tinyint(4) DEFAULT NULL COMMENT ’狀態(tài)’, `is_del` bit(1) DEFAULT NULL COMMENT ’是否刪除’, `position` int(5) DEFAULT NULL COMMENT ’位置’, `phase` int(10) DEFAULT NULL COMMENT ’期數(shù)’, `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=164 DEFAULT CHARSET=utf8mb4 COMMENT=’獎(jiǎng)品表’;

獎(jiǎng)品概率限制表:

CREATE TABLE `points_luck_draw_probability` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `points_prize_id` bigint(20) DEFAULT NULL COMMENT ’獎(jiǎng)品ID’, `points_prize_phase` int(10) DEFAULT NULL COMMENT ’獎(jiǎng)品期數(shù)’, `probability` float(4,2) DEFAULT NULL COMMENT ’概率’, `frozen` int(11) DEFAULT NULL COMMENT ’商品抽中后的冷凍次數(shù)’, `prize_day_max_times` int(11) DEFAULT NULL COMMENT ’該商品平臺(tái)每天最多抽中的次數(shù)’, `user_prize_month_max_times` int(11) DEFAULT NULL COMMENT ’每位用戶每月最多抽中該商品的次數(shù)’, `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COMMENT=’抽獎(jiǎng)概率限制表’;

獎(jiǎng)品記錄表:

CREATE TABLE `points_luck_draw_record` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `member_id` bigint(20) DEFAULT NULL COMMENT ’用戶ID’, `member_mobile` varchar(11) DEFAULT NULL COMMENT ’中獎(jiǎng)用戶手機(jī)號(hào)’, `points` int(11) DEFAULT NULL COMMENT ’消耗積分’, `prize_id` bigint(20) DEFAULT NULL COMMENT ’獎(jiǎng)品ID’, `result` smallint(4) DEFAULT NULL COMMENT ’1:中獎(jiǎng) 2:未中獎(jiǎng)’, `month` varchar(10) DEFAULT NULL COMMENT ’中獎(jiǎng)月份’, `daily` date DEFAULT NULL COMMENT ’中獎(jiǎng)日期(不包括時(shí)間)’, `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3078 DEFAULT CHARSET=utf8mb4 COMMENT=’抽獎(jiǎng)記錄表’;

3 獎(jiǎng)品池

獎(jiǎng)品池是根據(jù)獎(jiǎng)品的概率和限制組裝成的抽獎(jiǎng)用的池子。主要包括獎(jiǎng)品的總池值和每個(gè)獎(jiǎng)品所占的池值(分為開(kāi)始值和結(jié)束值)兩個(gè)維度。

獎(jiǎng)品的總池值:所有獎(jiǎng)品池值的總和。 每個(gè)獎(jiǎng)品的池值:算法可以變通,常用的有以下兩種方式 :

1)、獎(jiǎng)品的概率*10000(保證是整數(shù))2)、獎(jiǎng)品的概率10000獎(jiǎng)品的剩余數(shù)量

獎(jiǎng)品池bean:

public class PrizePool implements Serializable{ /** * 總池值 */ private int total; /** * 池中的獎(jiǎng)品 */ private List<PrizePoolBean> poolBeanList;}

池中的獎(jiǎng)品bean:

public class PrizePoolBean implements Serializable{ /** * 數(shù)據(jù)庫(kù)中真實(shí)獎(jiǎng)品的ID */ private Long id; /** * 獎(jiǎng)品的開(kāi)始池值 */ private int begin; /** * 獎(jiǎng)品的結(jié)束池值 */ private int end;}

獎(jiǎng)品池的組裝代碼:

/** * 獲取超級(jí)大富翁的獎(jiǎng)品池 * @param zillionaireProductMap 超級(jí)大富翁獎(jiǎng)品map * @param flag true:有現(xiàn)金 false:無(wú)現(xiàn)金 * @return */ private PrizePool getZillionairePrizePool(Map<Long, ActivityProduct> zillionaireProductMap, boolean flag) { //總的獎(jiǎng)品池值 int total = 0; List<PrizePoolBean> poolBeanList = new ArrayList<>(); for(Entry<Long, ActivityProduct> entry : zillionaireProductMap.entrySet()){ ActivityProduct product = entry.getValue(); //無(wú)現(xiàn)金獎(jiǎng)品池,過(guò)濾掉類型為現(xiàn)金的獎(jiǎng)品 if(!flag && product.getCategoryId() == ActivityPrizeTypeEnums.XJ.getType()){ continue; } //組裝獎(jiǎng)品池獎(jiǎng)品 PrizePoolBean prizePoolBean = new PrizePoolBean(); prizePoolBean.setId(product.getProductDescriptionId()); prizePoolBean.setBengin(total); total = total + product.getEarnings().multiply(new BigDecimal('10000')).intValue(); prizePoolBean.setEnd(total); poolBeanList.add(prizePoolBean); } PrizePool prizePool = new PrizePool(); prizePool.setTotal(total); prizePool.setPoolBeanList(poolBeanList); return prizePool;}

4 抽獎(jiǎng)算法

整個(gè)抽獎(jiǎng)算法為:

1. 隨機(jī)獎(jiǎng)品池總池值以內(nèi)的整數(shù) 2. 循環(huán)比較獎(jiǎng)品池中的所有獎(jiǎng)品,隨機(jī)數(shù)落到哪個(gè)獎(jiǎng)品的池區(qū)間即為哪個(gè)獎(jiǎng)品中獎(jiǎng)。抽獎(jiǎng)代碼:

public static PrizePoolBean getPrize(PrizePool prizePool){ //獲取總的獎(jiǎng)品池值 int total = prizePool.getTotal(); //獲取隨機(jī)數(shù) Random rand=new Random(); int random=rand.nextInt(total); //循環(huán)比較獎(jiǎng)品池區(qū)間 for(PrizePoolBean prizePoolBean : prizePool.getPoolBeanList()){ if(random >= prizePoolBean.getBengin() && random < prizePoolBean.getEnd()){ return prizePoolBean; } } return null; }

5 獎(jiǎng)品限制

實(shí)際抽獎(jiǎng)中對(duì)一些比較大的獎(jiǎng)品往往有數(shù)量限制,比如:某某獎(jiǎng)品一天最多被抽中5次、某某獎(jiǎng)品每位用戶只能抽中一次。。等等類似的限制,對(duì)于這樣的限制我們分為兩種情況來(lái)區(qū)別對(duì)待:

1. 限制的獎(jiǎng)品比較少,通常不多于3個(gè):這種情況我們可以再組裝獎(jiǎng)品池的時(shí)候就把不符合條件的獎(jiǎng)品過(guò)濾掉,這樣抽中的獎(jiǎng)品都是符合條件的。例如,在上面的超級(jí)大富翁抽獎(jiǎng)代碼中,我們規(guī)定現(xiàn)金獎(jiǎng)品一天只能被抽中5次,那么我們可以根據(jù)判斷條件分別組裝出有現(xiàn)金的獎(jiǎng)品和沒(méi)有現(xiàn)金的獎(jiǎng)品。2. 限制的獎(jiǎng)品比較多,這樣如果要采用第一種方式,就會(huì)導(dǎo)致組裝獎(jiǎng)品非常繁瑣,性能低下,我們可以采用抽中獎(jiǎng)品后校驗(yàn)抽中的獎(jiǎng)品是否符合條件,如果不符合條件則返回一個(gè)固定的獎(jiǎng)品即可。

6 獎(jiǎng)品發(fā)放

獎(jiǎng)品發(fā)放可以采用工廠模式進(jìn)行發(fā)放:不同的獎(jiǎng)品類型走不同的獎(jiǎng)品發(fā)放處理器,示例代碼如下:獎(jiǎng)品發(fā)放:

/** * 異步分發(fā)獎(jiǎng)品 * @param prizeList * @throws Exception */ @Async('myAsync') @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) public Future<Boolean> sendPrize(Long memberId, List<PrizeDto> prizeList){ try { for(PrizeDto prizeDto : prizeList){ //過(guò)濾掉謝謝惠顧的獎(jiǎng)品 if(prizeDto.getType() == PointsLuckDrawTypeEnum.XXHG.getType()){ continue; } //根據(jù)獎(jiǎng)品類型從工廠中獲取獎(jiǎng)品發(fā)放類 SendPrizeProcessor sendPrizeProcessor = sendPrizeProcessorFactory.getSendPrizeProcessor( PointsLuckDrawTypeEnum.getPointsLuckDrawTypeEnumByType(prizeDto.getType())); if(ObjectUtil.isNotNull(sendPrizeProcessor)){ //發(fā)放獎(jiǎng)品 sendPrizeProcessor.send(memberId, prizeDto); } } return new AsyncResult<>(Boolean.TRUE); }catch (Exception e){ //獎(jiǎng)品發(fā)放失敗則記錄日志 saveSendPrizeErrorLog(memberId, prizeList); LOGGER.error('積分抽獎(jiǎng)發(fā)放獎(jiǎng)品出現(xiàn)異常', e); return new AsyncResult<>(Boolean.FALSE); }}

工廠類:

@Componentpublic class SendPrizeProcessorFactory implements ApplicationContextAware{ private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public SendPrizeProcessor getSendPrizeProcessor(PointsLuckDrawTypeEnum typeEnum){ String processorName = typeEnum.getSendPrizeProcessorName(); if(StrUtil.isBlank(processorName)){ return null; } SendPrizeProcessor processor = applicationContext.getBean(processorName, SendPrizeProcessor.class); if(ObjectUtil.isNull(processor)){ throw new RuntimeException('沒(méi)有找到名稱為【' + processorName + '】的發(fā)送獎(jiǎng)品處理器'); } return processor; }}

獎(jiǎng)品發(fā)放類舉例:

/** * 紅包獎(jiǎng)品發(fā)放類 */@Component('sendHbPrizeProcessor')public class SendHbPrizeProcessor implements SendPrizeProcessor{ private Logger LOGGER = LoggerFactory.getLogger(SendHbPrizeProcessor.class); @Resource private CouponService couponService; @Resource private MessageLogService messageLogService; @Override public void send(Long memberId, PrizeDto prizeDto) throws Exception { // 發(fā)放紅包 Coupon coupon = couponService.receiveCoupon(memberId, Long.parseLong(prizeDto.getValue())); //發(fā)送站內(nèi)信 messageLogService.insertActivityMessageLog(memberId, '你參與積分抽大獎(jiǎng)活動(dòng)抽中的' + coupon.getAmount() + '元理財(cái)紅包已到賬,謝謝參與', '積分抽大獎(jiǎng)中獎(jiǎng)通知'); //輸出log日志 LOGGER.info(memberId + '在積分抽獎(jiǎng)中抽中的' + prizeDto.getPrizeName() + '已經(jīng)發(fā)放!'); }}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 一级片高清 | 超碰97在线看 | 国产性精品 | heyzo加勒比jav素人 | 日韩欧美不卡 | 久久久777 | 国产一页| 网址黄色 | 国产99精品 | www.九九热| 日韩免费专区 | 9l蝌蚪porny中文自拍 | 日韩一区在线视频 | 三级黄色短视频 | 精品福利一区 | 四虎中文字幕 | 成人影片在线免费观看 | www.国产精品 | 欧美片一区二区三区 | av在线播放不卡 | 中国妇女裸体交性大片 | 97国产视频 | 国内毛片视频 | 日批在线看 | 好吊妞在线| 国产在线日韩 | 成人自拍小视频 | 精品国产香蕉 | 日本在线精品视频 | 久久七七 | 九色视频在线观看 | 日韩一级黄色 | 免费av网站观看 | 91热在线 | 久久久综合久久 | 成年人在线视频免费观看 | 黄色网址国产 | www日本高清视频 | 精品国产一| 一二三区在线 | 亚洲少妇一区二区三区 |