记录:随机数抽奖

要求:每次生成3个 1 - 10 之间可重复(或不可重复)的随机数,10次为一轮,每轮要求数字5出现6次、数字4出现3次、…。

提炼需求:
1,可设置最小数、最大数、每次抽奖生成随机数的个数、是否允许重复
2,可设置每轮指定数字的出现次数
3,可设置每轮的抽奖次数

注意:设置项发生变化,则重置游戏

效果图示例:
在这里插入图片描述
在这里插入图片描述

Choujianglog 模型

<?php

namespace app\admin\model\choujiang;

use think\Model;


class Choujianglog extends Model
{

    

    

    // 表名
    protected $name = 'choujiang_log';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = false;
    protected $deleteTime = false;

    // 追加属性
    protected $append = [

    ];
   

    // 获取抽奖当前轮次
    public function getLunci($choujiang_id, $yilunchoujiagcishu) {
        $lunci = $this->where(['choujiang_id'=>$choujiang_id])->max('lunci');
        if(!$lunci){
            $lunci = 1;
        }
        return $lunci;
    }

    // 获取抽奖接下来的轮次
    public function getnextLunci($choujiang_id, $yilunchoujiagcishu) {
        $lunci = $this->where(['choujiang_id'=>$choujiang_id])->max('lunci');
        if(!$lunci){
            $lunci = 1;
        }
        $choujiangcishu = $this->where(['choujiang_id'=>$choujiang_id, 'lunci'=>$lunci])->group('sign')->count();
        if($choujiangcishu >= $yilunchoujiagcishu){
            $lunci += 1;
        }
        return $lunci;
    }

    // 生成sign
    public function createSign() {
        $str = '123567890123567890123567890';//34个字符
        $str = str_shuffle($str);   //随机地打乱字符串中的所有字符
        $sign = date('YmdHis').substr($str,0,4); //截取字符串
        if($this->where(['sign'=>$sign])->value('sign')){
            $this->createSign();
        }else{
            return $sign;
        }
    }



}

Choujiang模型

<?php

namespace app\admin\model\choujiang;

use think\Model;


class Choujiang extends Model
{

    

    

    // 表名
    protected $name = 'choujiang';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    // 追加属性
    protected $append = [
        'state_text'
    ];
    

    
    public function getStateList()
    {
        return ['1' => __('State 1'), '2' => __('State 2')];
    }


    public function getStateTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['state']) ? $data['state'] : '');
        $list = $this->getStateList();
        return isset($list[$value]) ? $list[$value] : '';
    }




}

Choujiangset模型

<?php

namespace app\admin\model\choujiang;

use think\Model;


class Choujiangset extends Model
{

    

    

    // 表名
    protected $name = 'choujiang_set';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = false;

    // 定义时间戳字段名
    protected $createTime = false;
    protected $updateTime = false;
    protected $deleteTime = false;

    // 追加属性
    protected $append = [
        'state_text'
    ];
    

    
    public function getStateList()
    {
        return ['1' => __('State 1'), '2' => __('State 2')];
    }


    public function getStateTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['state']) ? $data['state'] : '');
        $list = $this->getStateList();
        return isset($list[$value]) ? $list[$value] : '';
    }




}

代码:

<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Exception;
use think\Validate;
use app\admin\model\choujiang\Choujiang as ChoujiangModel;
use app\admin\model\choujiang\Choujianglog as ChoujianglogModel;
use app\admin\model\choujiang\Choujiangset as ChoujiangsetModel;

/**
 * 随机数接口
 */
class Choujiang extends Api
{
    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];

    protected $yilunchoujiagcishu = 10; //一轮抽奖次数
    protected $default_min_val = 1; //(默认)最小数
    protected $default_max_val = 10; //(默认)最大数
    protected $default_geshu = 3; //(默认)个数
    protected $default_state = 1; //(默认)允许重复:1=是,2=否


    public function _initialize()
    {
        parent::_initialize();

        if(!((new ChoujiangsetModel())->where(['id'=>['>', 0]])->value('id'))){
            (new ChoujiangsetModel())->save([
                'min_val'=>$this->default_min_val,
                'max_val'=>$this->default_max_val,
                'geshu'=>$this->default_geshu,
                'state'=>$this->default_state,
            ]);
        }

        if(!((new ChoujiangModel())->where(['id'=>['>', 0]])->value('id'))){
            $info = (new ChoujiangsetModel())->where(['id'=>['>', 0]])->field('min_val,max_val,geshu,state')->find();
            (new ChoujiangModel())->save([
                'min_val'=>$info['min_val'],
                'max_val'=>$info['max_val'],
                'geshu'=>$info['geshu'],
                'state'=>$info['state'],
            ]);
        }
    }


    /**
     * 生成随机数页面,获取设置
     *
     * @ApiMethod (GET)
     * @ApiHeaders  (name=token, type=string, required=false, description="请求的Token")
     */
    public function getSet()
    {
        try {  
            $info = (new ChoujiangsetModel())->where(['id'=>['>', 0]])->field('min_val,max_val,geshu,state')->find();

            $this->success("OK", [
                'info' => $info,
            ]);

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 生成随机数页面,修改设置
     *
     * @ApiMethod (POST)
     * @ApiHeaders  (name=token, type=string, required=false, description="请求的Token")
    //  * @param string $min_val  最小数
    //  * @param string $max_val  最大数
     * @param string $geshu  个数
    //  * @param string $state  允许重复:1=是,2=否
     */
    public function editSet()
    {
        try {  
            $min_val = $this->request->post('min_val/d',1);
            $max_val = $this->request->post('max_val/d',10);
            $geshu = $this->request->post('geshu/d',3);
            $state = $this->request->post('state',1);
            
            if(!in_array($geshu, [1,2,3])){
                $this->error('个数只能设置为1,2,3');
            }
            if($min_val >= $max_val){
                $this->error('最小数应小于最大数');
            }
            if($min_val <= 0 || $max_val <= 0){
                $this->error('最小数和最大数应>0');
            }
            if(!in_array($state, [1,2])){
                $this->error('允许重复只能设置为1,2');
            }

            $info = (new ChoujiangsetModel())->where(['id'=>['>', 0]])->field('min_val,max_val,geshu,state')->find();
            $data = [
                'min_val' => $min_val,
                'max_val' => $max_val,
                'geshu' => $geshu,
                'state' => $state,
            ];
            $info->save($data);
            
            $choujianginfo = (new ChoujiangModel())->where(['id'=>['>', 0]])->field('min_val,max_val,geshu,state')->order('id desc')->find();
            // 若配置修改则重置游戏
            if($choujianginfo['min_val'] != $data['min_val'] || $choujianginfo['max_val'] != $data['max_val'] || $choujianginfo['geshu'] != $data['geshu'] || $choujianginfo['state'] != $data['state']){
                (new ChoujiangModel())->save([
                    'min_val'=>$data['min_val'],
                    'max_val'=>$data['max_val'],
                    'geshu'=>$data['geshu'],
                    'state'=>$data['state'],
                ]);
            }
                    

            $this->success("保存成功", [
                'info' => $data,
            ]);

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    
    /**
     * 生成随机数页面,生成随机数
     *
     * @ApiMethod (POST)
     * @ApiHeaders  (name=token, type=string, required=false, description="请求的Token")
     */
    public function choujiang()
    {
        try {  
            $newchoujianginfo = (new ChoujiangModel())->where(['id'=>['>', 0]])->field('id,min_val,max_val,geshu,state,neidingcishu,content')->order('id desc')->find();
            $nextlunci = (new ChoujianglogModel)->getnextLunci($newchoujianginfo['id'], $this->yilunchoujiagcishu); //获取抽奖接下来的轮次
            $min = $newchoujianginfo['min_val'];
            $max = $newchoujianginfo['max_val'];
            $geshu = $newchoujianginfo['geshu'];
            $state = $newchoujianginfo['state'];    
            $neidingcishu = $newchoujianginfo['neidingcishu'];    
            
            // 当前轮次抽奖次数
            $choujiangcishu = (new ChoujianglogModel)->where(['choujiang_id'=>$newchoujianginfo['id'], 'lunci'=>$nextlunci])->group('sign')->count();
            if($choujiangcishu == 0){   //开始新一轮
                
                $numbers = [];   // 生成的数字
                $keyArr = [];   //内定数字

                // 优先将内定数字放入数组
                if($neidingcishu){
                    foreach(json_decode($neidingcishu, true) as $key=>$value){
                        // 生成数字$key,并确保满足条件($value次)
                        for ($i = 0; $i < $value; $i++) {
                            $numbers[] = $key;
                        }
                        $keyArr[] = $key;
                    }
                }

                // 除去内定数字之外的数字集
                $shuziArr = array_values(array_diff(range($min, $max), $keyArr));
                
                // 填补,确保没有超出条件限制
                shuffle($shuziArr); // 打乱数组顺序
                $shuziArrwhile = $shuziArr;
                while (count($numbers) < $geshu*$this->yilunchoujiagcishu) {
                    if(count($shuziArrwhile) <= 0){
                        $shuziArrwhile = $shuziArr;
                    }
                    $shuzi = array_shift($shuziArrwhile);
                    $numbers[] = $shuzi;
                }

                // 打乱数组顺序,确保随机性
                shuffle($numbers);

                // 允许重复:1=是,2=否
                if($state == 1){
                    // 分割数组
                    $newNumbers = array_chunk($numbers, $geshu);
                }else{
                    $newNumbers = [];
                    for ($i = 0; $i < count($numbers); $i += $geshu) {
                        $randomarr = array_values(array_unique(array_slice($numbers, $i, $geshu)));
                        if(count($randomarr) != $geshu){
                            $this->error('抱歉,参数配置错误');
                        }
                        $newNumbers[] = $randomarr;
                    }
                }
                
                $firstArr = array_shift($newNumbers);
            }else{
                $newNumbers = json_decode($newchoujianginfo['content'], true);
                $firstArr = array_shift($newNumbers);
            }

            // 保存抽奖记录
            $choujianglogModel = new ChoujianglogModel();
            $sign = $choujianglogModel->createSign();
            $logData = [];
            foreach($firstArr as $k=>$v){
                $logData[] = [
                    'choujiang_id'=>$newchoujianginfo['id'], 
                    'lunci'=>$nextlunci,
                    'number'=>$v,
                    'sign'=>$sign,
                ];
            }
            $choujianglogModel->allowField(true)->saveAll($logData);

            // 保存剩余待抽奖项
            $newchoujianginfo->save(['content'=>json_encode($newNumbers)]);

            $this->success("OK", [
                'data' => $firstArr,
            ]);

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }
   

    /**
     * 内定数字页面,获取数据
     *
     * @ApiMethod (GET)
     * @ApiHeaders  (name=token, type=string, required=false, description="请求的Token")
     */
    public function getChoujiangSet()
    {
        try {  
            $newchoujianginfo = $this->choujiangset();
            $this->success("OK", [
                'info' => $newchoujianginfo,
            ]);

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }
    
    private function choujiangset() {
        $newchoujianginfo = (new ChoujiangModel())->where(['id'=>['>', 0]])->field('id,min_val,max_val,geshu,state,neidingcishu')->order('id desc')->find();
        $lunci = (new ChoujianglogModel)->getLunci($newchoujianginfo['id'], $this->yilunchoujiagcishu); //获取抽奖当前轮次
        $neidingcishu_arr = [];
        if($newchoujianginfo['neidingcishu']){
            foreach(json_decode($newchoujianginfo['neidingcishu'], true) as $k=>$v){
                $neidingcishu_arr[] = [
                    'shuzi'=>$k,
                    'cishu'=>$v,
                    'chouzhongcishu'=>(new ChoujianglogModel)->where(['choujiang_id'=>$newchoujianginfo['id'], 'lunci'=>$lunci, 'number'=>$k])->count(),
                ];
            }
        }
        $newchoujianginfo['neidingcishu_arr'] = $neidingcishu_arr;
        unset($newchoujianginfo['neidingcishu']);
        $newchoujianginfo['choujiangcishu'] = (new ChoujianglogModel)->where(['choujiang_id'=>$newchoujianginfo['id'], 'lunci'=>$lunci])->group('sign')->count();

        return $newchoujianginfo;
    }


    /**
     * 内定数字页面,设置出现次数
     *
     * @ApiMethod (POST)
     * @ApiHeaders  (name=token, type=string, required=false, description="请求的Token")
     * @param json $neidingcishu  json字符串,例如{"1":"5","2":"3"}
     */
    public function editChoujiangSet()
    {
        try {  
            $neidingcishu = htmlspecialchars_decode($this->request->post('neidingcishu/s', ''));
            $neidingcishu = json_decode($neidingcishu, true);
            // $neidingcishu = $this->request->post()['neidingcishu'];

            $choujianginfo = (new ChoujiangModel())->where(['id'=>['>', 0]])->order('id desc')->find();
            if($neidingcishu){
                $arr = [];
                $max_cishu = $this->yilunchoujiagcishu * $choujianginfo['geshu'];
                $cishu = 0;
                foreach($neidingcishu as $key=>$value){
                    if($key < $choujianginfo['min_val'] || $key > $choujianginfo['max_val']){
                        $this->error('数字应在最小数与最大数之间');
                    }
                    if($choujianginfo['state']==1 && $value > $max_cishu){
                        $this->error('单个数字出现总次数应<='.$max_cishu);
                    }
                    if($choujianginfo['state']==2 && $value > $this->yilunchoujiagcishu){
                        $this->error('单个数字出现总次数应<='.$this->yilunchoujiagcishu);
                    }
                    $cishu += $value;
                    if($cishu > $max_cishu){
                        $this->error('数字出现总次数应<='.$max_cishu);
                    }
                    $arr[$key] = $value;
                }
                if($choujianginfo['min_val']+1 == $choujianginfo['max_val'] && count($arr)==2 && $cishu != $max_cishu){
                    $this->error('数字出现总次数应=='.$max_cishu);
                }
                $neidingcishu_str = json_encode($arr);
            }else{
                $neidingcishu_str = '';
            }
            if($choujianginfo['neidingcishu'] != $neidingcishu_str){
                $info = (new ChoujiangsetModel())->where(['id'=>['>', 0]])->field('min_val,max_val,geshu,state')->find();
                (new ChoujiangModel())->save([
                    'min_val'=>$info['min_val'],
                    'max_val'=>$info['max_val'],
                    'geshu'=>$info['geshu'],
                    'state'=>$info['state'],
                    'neidingcishu'=>$neidingcishu_str,
                ]);
            }
           
            $newchoujianginfo = $this->choujiangset();
            $this->success("保存成功", [
                'info' => $newchoujianginfo,
            ]);

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }


}

sql

CREATE TABLE `fa_choujiang_set` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `min_val` int(10) DEFAULT '0' COMMENT '最小数',
  `max_val` int(10) DEFAULT '0' COMMENT '最大数',
  `geshu` int(10) DEFAULT '0' COMMENT '个数',
  `state` enum('1','2') DEFAULT '1' COMMENT '允许重复:1=是,2=否',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='抽奖设置表';

CREATE TABLE `fa_choujiang` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `min_val` int(10) DEFAULT '0' COMMENT '最小数',
  `max_val` int(10) DEFAULT '0' COMMENT '最大数',
  `geshu` int(10) DEFAULT '0' COMMENT '个数',
  `state` enum('1','2') DEFAULT '1' COMMENT '允许重复:1=是,2=否',
  `neidingcishu` text COMMENT '内定次数',
  `content` text COMMENT '内容',
  `createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
  `updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COMMENT='抽奖表';

CREATE TABLE `fa_choujiang_log` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `choujiang_id` int(10) DEFAULT '0' COMMENT '抽奖ID',
  `number` int(10) DEFAULT '0' COMMENT '数字',
  `sign` varchar(100) DEFAULT NULL COMMENT '标识',
  `lunci` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '轮次(第几轮)',
  `createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `choujiang_id` (`choujiang_id`)
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8mb4 COMMENT='抽奖记录表';

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部