承接 lotteryyii/lottery 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

lotteryyii/lottery

Composer 安装命令:

composer require lotteryyii/lottery

包简介

yii2 lottery

README 文档

README

yii2版composer抽奖程序插件,包含服务端和前端html(vue和js版大转盘)

程序流程

  1. 创建活动
  2. 添加活动的奖品
  3. 前端展示
  4. 抽奖
  5. 记录抽奖
  • 这些可以简单在自己的cms系统增加个抽奖模块,管理抽奖模块数据,本插件只涉及抽奖行为业务,数据部分直插数据库表。

运行环境

  • php >= 5.4
  • composer
  • yii2
  • mysql
  • yii2-redis > 2.*

安装

$ composer require lotteryyii/lottery

添加 aliases,在config/web.php中aliases添加

    'aliases' => [
        '@lotteryyii/lottery'   => '@vendor/lotteryyii/lottery/src',
    ],

视图

image

tips:静态资源和yii视图模板放在views下,vue版大转盘前端模板参考:https://100px.net/

抽奖主类 Lottery.php

  • 对外方法
method 描述
lottery 抽奖方法
prizeList 奖品列表
getPrizeRecord 获奖记录
activityInfo 活动详情
/**
 * Lottery  lottery. 抽奖主方法
 * @param $uid int 用户id
 * @param $activityId int 活动id
 * @param $lotteryLimit int 抽奖次数
*/
public static function lottery($activityId,$uid=null,$lotteryLimit=0)
{
	$activityInfo =self::activityInfo($activityId);
	if(!$activityInfo){
	
		return self::returnOut(0,'活动不存在');
	}
	if(!self::checkActivitydate($activityInfo)){
	
		return self::returnOut(0,'今天不在活动时间范围哦');
	}
	$prize = new LotteryPrize;
	$prizeObj = $prize->getAllList($activityId);
	if(!$prizeObj){

		return self::returnOut(0,'奖品不存在');
	}
	//$lotteryLimit == 0时,不限抽奖次数。
	if($uid && $lotteryLimit!=0){
		$redis = \Yii::$app->redis;
		//获取用户已抽奖次数,默认$lotteryTimes为0
		$lotteryTimes = $redis->hget('lotterytimes', 'lotterytimes_'.$activityId.'_'.$uid)?$redis->hget('lotterytimes', 'lotterytimes_'.$activityId.'_'.$uid):0 ;
		if( $lotteryTimes > $lotteryLimit-1){
			return self::returnOut(0,'抽奖次数已用完');
		}
		$redis->hincrby('lotterytimes','lotterytimes_'.$activityId.'_'.$uid,1); //记录用户抽奖次数
		//如果是每日限制$lotteryLimit次,则设置第二天0点过期
		//$redis->expire('lotterytimes','lotterytimes_'.$activityId.'_'.$uid,strtotime(date("Y-m-d",time()))+3600*24-time());
	}
	$proArr = []; //所有奖品概率基数数组
	foreach ($prizeObj as $obj) {
		if( $obj->num != 0 && $obj->basenumber!=0) { //奖品数量有限,概率基数不为0时
			//检查奖品数量是否达到抽取上限,达到则设置该奖项的中奖率为0。
			if(!self::checkPrizeCount($obj)){
				$obj->basenumber = 0;
			}				
		}
		$proArr[] = $obj->basenumber;
	}
	$prizeIndex = self::getRand($proArr); //根据概率获取奖品的索引
	$result = $prizeObj[$prizeIndex]; //中奖奖品
	$record = new LotteryRecord;
	$addData = ['uid'=>$uid,'prizeId'=>$result->id,'prizename'=>$result->name,'activityId'=>$activityInfo->id,'activitytitle'=>$activityInfo->title,'state'=>$result->state,'lotterytime'=>time()];
	if($result->num == 0){ //奖品数量无限制时
		if(!$record->addonly($addData) ){ //中奖纪录写入数据库表,写入失败时,回退中奖次数
			if($uid && $lotteryLimit!=0){			
				$redis->hincrby('lotterytimes','lotterytimes_'.$activityId.'_'.$uid,-1); 
			}
		}
	}else{ //奖品数量有限制时
		$lott_num = $result->lott_num + 1 ;//已中奖数量+1
		if(!$record->addwith($addData,$lott_num) ){ //中奖纪录写入中奖记录表并更新奖品表,失败时,回退中奖次数
			if($uid && $lotteryLimit!=0){			
				$redis->hincrby('lotterytimes','lotterytimes_'.$activityId.'_'.$uid,-1); 
			}
		}		
		
	}
	$data['id'] = $result->id; //中奖奖品id
	$data['name'] = $result->name; //中奖奖品名称
	$data['state'] = $result->state; //是否为空奖谢谢参与
	$data['index'] = $prizeIndex; //中奖奖品的索引
	return self::returnOut(0,'',$data);
}

抽奖算法

/**
* Lottery  getRand. 抽奖算法
* @param array $proArr 所有奖品概率基数数组
*/
protected static function getRand( $proArr ) 
{
	$result = '';
	//$proSum抽奖概率基数之和
	$proSum = array_sum( $proArr ); 

	foreach ($proArr as $k => $v) { 
		//获取当次抽奖概率基数
		$randNum = mt_rand(1, $proSum);
		if ($randNum <= $v) { //$randNum在当前奖品概率基数($v)内,直接返回结果
			$result = $k;
			break;
		} else { //减去当前概率基数,继续寻找,直到满足$randNum在$v内
			$proSum -= $v;
		}
	}
	//删除$proArr,防止影响下次抽奖
	unset($proArr);

	return $result;
}

抽奖数据模型目录Models

  • 所有的数据模型都在Models目录。包含三部分,抽奖活动模型(Activity),抽奖奖品模型(Prize),抽奖记录模型(Record)

业务逻辑举例目录example(LotteryController)

namespace app\controllers;
use Yii;
use lotteryyii\lottery\Lottery;
use yii\web\Controller;

class LotteryController extends Controller
{
	public $layout = false;
	/**
	* Lottery  index. 抽奖方法
	 * @param $uid int 用户id
	 * @param $activityId int 活动id
	 * @param $lotteryLimit int 抽奖次数
	*/
	public function actionIndex()
	{
		$activityId = Yii::$app->request->get('activityId',1);
		$uid =Yii::$app->request->get('uid',1);
		$lotteryLimit = Yii::$app->request->get('lotteryLimit',3);;
		$result = Lottery::lottery($activityId,$uid,$lotteryLimit);
		Yii::$app->response->format =  \yii\web\Response::FORMAT_JSON;
		if($result['result']){
			return ['code'=>0,'data'=>$result['result']];
		}else{
			return ['code'=>0,'message'=>$result['message']];
		}
	
	}
}

备注

  • 这里所有的模型和控制器都给出来了,使用的时候可以不以插件服务提供者方式使用,可将Models和example内代码直接在自己项目的app目录包含应用程序的核心代码内。
  • MYSQL创建语句在sql目录下
  • 交流可发至943826443#qq.com,把#换成@. qq:943826443

lotteryyii/lottery 适用场景与选型建议

lotteryyii/lottery 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 4 次下载、GitHub Stars 达 2, 最近一次更新时间为 2021 年 01 月 23 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「draw」 「lottery」 「turntable」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 lotteryyii/lottery 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 lotteryyii/lottery 我们能提供哪些服务?
定制开发 / 二次开发

基于 lotteryyii/lottery 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 4
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 6
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 2
  • Watchers: 1
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-01-23