摘要:在開放時間的基礎上加上類型概率這種方式,也會出現多個用戶相同獎品,但加上限制后,用戶被分散在各個類型中,未中獎概率會比上面的例子低。
本文講解內容
針對兩類發獎需求的四種抽獎邏輯及細節
一般H5抽獎活動的發獎需求分為1.一定中獎(獎品庫存不空的情況下)
2.不一定中獎
1.獎品不超發
2.唯一獎品單次發放
3.對并發有一定的限制
1.根據獎品開放時間進行抽獎
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 []; }
這種方式,多用戶并發情況下,會出現多個用戶相同獎品,由于update語句限制,拿到相同獎品碼的用戶中只有一人能中得獎品。
2.在開放時間的基礎上加上類型概率
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 []; }
這種方式,也會出現多個用戶相同獎品,但加上type限制后,用戶被分散在各個類型中,未中獎概率會比上面的例子低。
3.利用Redis獎品池的概念進行發獎
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 []; }
這種利用預先生成獎品池的方式,獎品池不空的情況下,每個用戶都會取走不同獎品碼,要注意的是 前期生成獎品池及后期操作獎品池時,防止獎品碼復用
4.根據獎品開放時間(類型)進行抽獎,換成用sql語句進行發獎
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 []; }
一定中獎需求下,建議采用Redis獎品池或者sql語句進行update
以上四種方式在多用戶并發的情況下帶來不一樣的結果
除了多用戶并發,還會出現惡刷情況,就是同一用戶并發請求
這種情況應該在真正進入抽獎邏輯之前進行限制
可以根據實際需求搭配以下方式進行限制
public function actionAward() { $openid = "okjkLj7-UL4gXknY9bDkFn0O6Jos"; $redis = Yii::$app->redis->client(); // 用戶單次數 if (!$redis->sAdd(self::USER_LIST_KEY, $openid)) { return []; } return $this->sqlAward($openid); }
也可以限制抽獎人數
public function actionAward() { $openid = CommonTool::randString(32); try { $redis = Yii::$app->redis->client(); // 抽獎用戶數量 $list = $redis->sMembers(self::USER_LIST_KEY); if (count($list) > 1000) { return ; } } catch (Exception $err) { } $award = $this->sqlAward($openid); }寫在最后的最后
H5活動抽獎接口需要注意幾點
1.檢查用戶有效性
2.限制單用戶訪問次數
3.使用概率讓用戶分流,從而控制真正進入抽獎邏輯的請求
4.記錄抽獎領獎等相關操作的時間設備IP等..
5.控制獎品的分布(時間,插空,概率等)
6.做好索引關系
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30763.html
摘要:就是說,當用戶選擇該標簽時,瀏覽器就會自動將焦點轉到和標簽相關的表單控件上。標簽的屬性應當與相關元素的屬性相同。所以在和移動我分別用了兩種方案,傳統布局實現,彈性盒實現。前者是控制彈性盒的內容垂直方向居中,后者控制內容水平方向居中。 之前寫過兩篇開發中遇到的問題和解決方案。當時是CSS 和 JavaScript 分開寫的。現在寫這篇文章的時候感覺很多內容都是有內在聯系的,所以不好分開。...
摘要:就是說,當用戶選擇該標簽時,瀏覽器就會自動將焦點轉到和標簽相關的表單控件上。標簽的屬性應當與相關元素的屬性相同。所以在和移動我分別用了兩種方案,傳統布局實現,彈性盒實現。前者是控制彈性盒的內容垂直方向居中,后者控制內容水平方向居中。 之前寫過兩篇開發中遇到的問題和解決方案。當時是CSS 和 JavaScript 分開寫的。現在寫這篇文章的時候感覺很多內容都是有內在聯系的,所以不好分開。...
摘要:就是說,當用戶選擇該標簽時,瀏覽器就會自動將焦點轉到和標簽相關的表單控件上。標簽的屬性應當與相關元素的屬性相同。所以在和移動我分別用了兩種方案,傳統布局實現,彈性盒實現。前者是控制彈性盒的內容垂直方向居中,后者控制內容水平方向居中。 之前寫過兩篇開發中遇到的問題和解決方案。當時是CSS 和 JavaScript 分開寫的。現在寫這篇文章的時候感覺很多內容都是有內在聯系的,所以不好分開。...
摘要:您已擁有次抽獎機會,點擊立刻抽獎開始抽獎初始次數,由后臺傳入為隨機出來的結果,根據概率后的結果如果在執行就退出標志為在執行先判斷是否登錄未登錄則執行下面的函數請先登錄登錄了就執行下面當抽獎次數為的時候執行沒有次數了還有次 showImg(https://segmentfault.com/img/bVbqAdu); showImg(https://segmentfault.com/img...
閱讀 3456·2021-09-08 09:36
閱讀 2534·2019-08-30 15:54
閱讀 2345·2019-08-30 15:54
閱讀 1762·2019-08-30 15:44
閱讀 2378·2019-08-26 14:04
閱讀 2437·2019-08-26 14:01
閱讀 2869·2019-08-26 13:58
閱讀 1315·2019-08-26 13:47