摘要:在開放時(shí)間的基礎(chǔ)上加上類型概率這種方式,也會(huì)出現(xiàn)多個(gè)用戶相同獎(jiǎng)品,但加上限制后,用戶被分散在各個(gè)類型中,未中獎(jiǎng)概率會(huì)比上面的例子低。
本文講解內(nèi)容
針對兩類發(fā)獎(jiǎng)需求的四種抽獎(jiǎng)邏輯及細(xì)節(jié)
一般H5抽獎(jiǎng)活動(dòng)的發(fā)獎(jiǎng)需求分為1.一定中獎(jiǎng)(獎(jiǎng)品庫存不空的情況下)
2.不一定中獎(jiǎng)
1.獎(jiǎng)品不超發(fā)
2.唯一獎(jiǎng)品單次發(fā)放
3.對并發(fā)有一定的限制
1.根據(jù)獎(jiǎng)品開放時(shí)間進(jìn)行抽獎(jiǎng)
public function award($openid) { $award = Award::find()->where(["openid" => ""]) ->andWhere([">", "open_at", 0])->andWhere(["<", "open_at", time()]) ->orderBy("open_at ASC")->limit(1)->one(); if (!empty($award)) { $res = Award::updateAll( [ "openid" => $openid ], "code = :code AND openid = :openid", [ ":code" => $award["code"], ":openid" => "" ] ); if ($res) { return ArrayHelper::toArray($award); } } return []; }
這種方式,多用戶并發(fā)情況下,會(huì)出現(xiàn)多個(gè)用戶相同獎(jiǎng)品,由于update語句限制,拿到相同獎(jiǎng)品碼的用戶中只有一人能中得獎(jiǎng)品。
2.在開放時(shí)間的基礎(chǔ)上加上類型概率
public function randAward($openid) { $number = rand(0, 100); $type = 5; if ($number < 10) { $type = 1; } else if ($number < 30) { $type = 2; } else if ($number < 70) { $type = 3; } else if ($number < 80) { $type = 4; } $award = Award::find()->where(["openid" => ""]) ->andWhere([">", "open_at", 0])->andWhere(["<", "open_at", time()]) ->andWhere(["type" => $type]) ->orderBy("open_at ASC")->limit(1)->one(); if (!empty($award)) { $res = Award::updateAll( [ "openid" => $openid ], "code = :code AND openid = :openid", [ ":code" => $award["code"], ":openid" => "" ] ); if ($res) { return ArrayHelper::toArray($award); } } return []; }
這種方式,也會(huì)出現(xiàn)多個(gè)用戶相同獎(jiǎng)品,但加上type限制后,用戶被分散在各個(gè)類型中,未中獎(jiǎng)概率會(huì)比上面的例子低。
3.利用Redis獎(jiǎng)品池的概念進(jìn)行發(fā)獎(jiǎng)
public function redisAward($openid) { try { $redis = Yii::$app->redis->client(); $code = $redis->LPop(self::AWARD_LIST_KEY); } catch (Exception $err) { return []; } $res = Award::updateAll( [ "openid" => $openid ], "code = :code AND openid = :openid", [ ":code" => $code, ":openid" => "" ] ); if ($res) { $award = Award::find()->where(["code" => $code])->limit(1)->one(); return ArrayHelper::toArray($award); } return []; }
這種利用預(yù)先生成獎(jiǎng)品池的方式,獎(jiǎng)品池不空的情況下,每個(gè)用戶都會(huì)取走不同獎(jiǎng)品碼,要注意的是 前期生成獎(jiǎng)品池及后期操作獎(jiǎng)品池時(shí),防止獎(jiǎng)品碼復(fù)用
4.根據(jù)獎(jiǎng)品開放時(shí)間(類型)進(jìn)行抽獎(jiǎng),換成用sql語句進(jìn)行發(fā)獎(jiǎng)
public function sqlAward($openid) { $sql = "UPDATE award SET openid = :openid WHERE open_at > 0 AND openid = "" AND open_at < :time ORDER BY open_at ASC LIMIT 1"; $res = Yii::$app->db->createCommand($sql, [":time" => time(), ":openid" => $openid])->execute(); if ($res) { return Award::find()->where(["openid" => $openid])->limit(1)->asArray()->one(); } return []; }
一定中獎(jiǎng)需求下,建議采用Redis獎(jiǎng)品池或者sql語句進(jìn)行update
以上四種方式在多用戶并發(fā)的情況下帶來不一樣的結(jié)果
除了多用戶并發(fā),還會(huì)出現(xiàn)惡刷情況,就是同一用戶并發(fā)請求
這種情況應(yīng)該在真正進(jìn)入抽獎(jiǎng)邏輯之前進(jìn)行限制
可以根據(jù)實(shí)際需求搭配以下方式進(jìn)行限制
public function actionAward() { $openid = "okjkLj7-UL4gXknY9bDkFn0O6Jos"; $redis = Yii::$app->redis->client(); // 用戶單次數(shù) if (!$redis->sAdd(self::USER_LIST_KEY, $openid)) { return []; } return $this->sqlAward($openid); }
也可以限制抽獎(jiǎng)人數(shù)
public function actionAward() { $openid = CommonTool::randString(32); try { $redis = Yii::$app->redis->client(); // 抽獎(jiǎng)用戶數(shù)量 $list = $redis->sMembers(self::USER_LIST_KEY); if (count($list) > 1000) { return ; } } catch (Exception $err) { } $award = $this->sqlAward($openid); }寫在最后的最后
H5活動(dòng)抽獎(jiǎng)接口需要注意幾點(diǎn)
1.檢查用戶有效性
2.限制單用戶訪問次數(shù)
3.使用概率讓用戶分流,從而控制真正進(jìn)入抽獎(jiǎng)邏輯的請求
4.記錄抽獎(jiǎng)?lì)I(lǐng)獎(jiǎng)等相關(guān)操作的時(shí)間設(shè)備IP等..
5.控制獎(jiǎng)品的分布(時(shí)間,插空,概率等)
6.做好索引關(guān)系
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/30763.html
摘要:就是說,當(dāng)用戶選擇該標(biāo)簽時(shí),瀏覽器就會(huì)自動(dòng)將焦點(diǎn)轉(zhuǎn)到和標(biāo)簽相關(guān)的表單控件上。標(biāo)簽的屬性應(yīng)當(dāng)與相關(guān)元素的屬性相同。所以在和移動(dòng)我分別用了兩種方案,傳統(tǒng)布局實(shí)現(xiàn),彈性盒實(shí)現(xiàn)。前者是控制彈性盒的內(nèi)容垂直方向居中,后者控制內(nèi)容水平方向居中。 之前寫過兩篇開發(fā)中遇到的問題和解決方案。當(dāng)時(shí)是CSS 和 JavaScript 分開寫的。現(xiàn)在寫這篇文章的時(shí)候感覺很多內(nèi)容都是有內(nèi)在聯(lián)系的,所以不好分開。...
摘要:就是說,當(dāng)用戶選擇該標(biāo)簽時(shí),瀏覽器就會(huì)自動(dòng)將焦點(diǎn)轉(zhuǎn)到和標(biāo)簽相關(guān)的表單控件上。標(biāo)簽的屬性應(yīng)當(dāng)與相關(guān)元素的屬性相同。所以在和移動(dòng)我分別用了兩種方案,傳統(tǒng)布局實(shí)現(xiàn),彈性盒實(shí)現(xiàn)。前者是控制彈性盒的內(nèi)容垂直方向居中,后者控制內(nèi)容水平方向居中。 之前寫過兩篇開發(fā)中遇到的問題和解決方案。當(dāng)時(shí)是CSS 和 JavaScript 分開寫的?,F(xiàn)在寫這篇文章的時(shí)候感覺很多內(nèi)容都是有內(nèi)在聯(lián)系的,所以不好分開。...
摘要:就是說,當(dāng)用戶選擇該標(biāo)簽時(shí),瀏覽器就會(huì)自動(dòng)將焦點(diǎn)轉(zhuǎn)到和標(biāo)簽相關(guān)的表單控件上。標(biāo)簽的屬性應(yīng)當(dāng)與相關(guān)元素的屬性相同。所以在和移動(dòng)我分別用了兩種方案,傳統(tǒng)布局實(shí)現(xiàn),彈性盒實(shí)現(xiàn)。前者是控制彈性盒的內(nèi)容垂直方向居中,后者控制內(nèi)容水平方向居中。 之前寫過兩篇開發(fā)中遇到的問題和解決方案。當(dāng)時(shí)是CSS 和 JavaScript 分開寫的?,F(xiàn)在寫這篇文章的時(shí)候感覺很多內(nèi)容都是有內(nèi)在聯(lián)系的,所以不好分開。...
摘要:您已擁有次抽獎(jiǎng)機(jī)會(huì),點(diǎn)擊立刻抽獎(jiǎng)開始抽獎(jiǎng)初始次數(shù),由后臺傳入為隨機(jī)出來的結(jié)果,根據(jù)概率后的結(jié)果如果在執(zhí)行就退出標(biāo)志為在執(zhí)行先判斷是否登錄未登錄則執(zhí)行下面的函數(shù)請先登錄登錄了就執(zhí)行下面當(dāng)抽獎(jiǎng)次數(shù)為的時(shí)候執(zhí)行沒有次數(shù)了還有次 showImg(https://segmentfault.com/img/bVbqAdu); showImg(https://segmentfault.com/img...
閱讀 3527·2021-09-08 09:36
閱讀 2697·2019-08-30 15:54
閱讀 2414·2019-08-30 15:54
閱讀 1822·2019-08-30 15:44
閱讀 2448·2019-08-26 14:04
閱讀 2493·2019-08-26 14:01
閱讀 2938·2019-08-26 13:58
閱讀 1415·2019-08-26 13:47