<?php
/**
 * Notes:活动类
 * User: wsc
 * Time: 2020/12/3 18:20
 * Class ModelActivitynew
 */
class ModelActivitynew
{
    //活动模板类,及奖励中心对应的是否显示id,及原本对应的固定活动id
    public $act_type = [
        "super_collect" =>          ["tips" => "收集活动", "rcid" => "36", "old_aid" => 0],
//        "collect"=>                 ["tips"=>"收集活动","rcid"=>"5","old_aid"=>0],
//        "steal"=>                   ["tips"=>"偷活动","rcid"=>"8","old_aid"=>0],
//        "attack"=>                  ["tips"=>"打活动","rcid"=>"8","old_aid"=>0],
        "rank" =>                   ["tips" => "排行榜活动", "rcid" => "17", "old_aid" => 0, 'gift_name' => 'valuePack'],
        "rank2" =>                  ["tips" => "排行榜活动-无进度", "rcid" => "50", "old_aid" => 0, 'gift_name' => 'valuePack'],
        "first_pay" =>              ["tips" => "首充活动", "rcid" => "", "old_aid" => 0],//--不显示用户中心
//        "balloon"=>                 ["tips"=>"气球活动","rcid"=>"6","old_aid"=>0],
        "spins_master" =>           ["tips" => "体力大师", "rcid" => "40", "old_aid" => 0],
//        "balloon_tg"=>              ["tips"=>"感恩节气球活动","rcid"=>"7","old_aid"=>0],
//        "holiday"=>                 ["tips"=>"节日收集","rcid"=>"10","old_aid"=>0],//节日收集
//        "jackpot"=>                 ["tips"=>"jackpot","rcid"=>"15","old_aid"=>0],//暂未实现
        "architecture" =>           ["tips" => "建筑大师", "rcid" => "12", "old_aid" => 0],
//        "supper_bet"=>              ["tips"=>"supper_bet活动","rcid"=>"13","old_aid"=>0],
        "speed_spins" =>            ["tips" => "体力加速恢复", "rcid" => "18", "old_aid" => 0],
        "card" =>                   ["tips" => "卡片活动", "rcid" => "14", "old_aid" => 0],
//        "card_exchange"=>           ["tips"=>"卡片交换","rcid"=>"16","old_aid"=>0],
        "behavior" =>               ["tips" => "行为促销", "rcid" => "", "old_aid" => 0],//--不显示用户中心
        "recharge_gift" =>          ["tips" => "限定礼包", "rcid" => "", "old_aid" => 0],//--不显示用户中心
//        "chain_gift"=>              ["tips"=>"连环礼包","rcid"=>"19","old_aid"=>0],
        "treasure" =>               ["tips" => "宝藏活动", "rcid" => "20", "old_aid" => 0],
//        "poster_1"=>                ["tips"=>"海报一","rcid"=>"21","old_aid"=>0],
//        "poster_2"=>                ["tips"=>"海报二","rcid"=>"22","old_aid"=>0],
//        "poster_3"=>                ["tips"=>"海报三","rcid"=>"23","old_aid"=>0],
        "crazy_bet" =>              ["tips" => "crazy_bet活动", "rcid" => "24", "old_aid" => 0],
        "crazy_card_group" =>       ["tips" => "疯狂的卡组", "rcid" => "25", "old_aid" => 0],
        "golden_card_trade" =>      ["tips" => "金卡交换", "rcid" => "26", "old_aid" => 0],
        "time_limit_invite" =>      ["tips" => "限时邀请", "rcid" => "27", "old_aid" => 0],
        "shop_promotion" =>         ["tips" => "优惠券", "rcid" => "28", "old_aid" => 0],
        "accumulated_pay" =>        ["tips" => "累计充值", "rcid" => "29", "old_aid" => 0],
        "traffic_permit" =>         ["tips" => "通行证", "rcid" => "30", "old_aid" => 0],
        "discounts_architecture" => ["tips" => "建筑打折", "rcid" => "31", "old_aid" => 0],
//        "collect_only"=>            ["tips"=>"特殊收集活动","rcid"=>"32","old_aid"=>0],
        "super_serial_pack" =>      ["tips" => "超级连环礼包", "rcid" => "33", "old_aid" => 0],
        "super_serial_pack2" =>     ["tips" => "超级连环礼包2", "rcid" => "48", "old_aid" => 0],
        //"steel_safe"=>              ["tips"=>"保险柜","rcid"=>"34","old_aid"=>0],
        "coin_blast" =>             ["tips" => "金币大爆炸", "rcid" => "35", "old_aid" => 0],
        "premium" =>                ["tips" => "Premium小组", "rcid" => "37", "old_aid" => 0],
        "super_balloon" =>          ["tips" => "超级气球", "rcid" => "38", "old_aid" => 0],
        "traffic_permit_bet" =>     ["tips" => "通行证倍率", "rcid" => "39", "old_aid" => 0],
        "choose_one" =>             ["tips" => "二选一活动", "rcid" => "41", "old_aid" => 0],
//        "fund"=>                    ["tips"=>"基金活动","rcid"=>"42","old_aid"=>0],
        "collect_bet" =>            ["tips" => "收集翻倍", "rcid" => "43", "old_aid" => 0],
        "easter_egg" =>             ["tips" => "四选一活动-帽子戏法", "rcid" => "44", "old_aid" => 0],
        "callback_score" =>         ["tips" => "好友召回", "rcid" => "45", "old_aid" => 0],
        "daily_chest" =>            ["tips" => "每日宝箱", "rcid" => "46", "old_aid" => 0],
//        "change_collect"=>          ["tips"=>"小玩法收集","rcid"=>"47","old_aid"=>0],

//        "spin_safe"=>              ["tips"=>"体力存钱罐","rcid"=>"49","old_aid"=>0],
        "one_plus_gift" =>          ["tips" => "1+1礼包活动", "rcid" => "51", "old_aid" => 0],
        "safe_surprise" =>          ["tips" => "惊喜礼包活动", "rcid" => "52", "old_aid" => 0],
        "collect_jigsw" =>          ["tips" => "拼图活动", "rcid" => "53", "old_aid" => 0],
        "maya_wheel" =>             ["tips" => "玛雅转盘", "rcid" => "54", "old_aid" => 0],
        "choose_you_want" =>        ["tips" => "随心配礼包", "rcid" => "55", "old_aid" => 0],
        "fox_hammer" =>             ["tips" => "狐狸之锤礼包", "rcid" => "56", "old_aid" => 0],
        "super_serial_pack3" =>     ["tips" => "六格连环礼包", "rcid" => "57", "old_aid" => 0],
        "theme_pack" =>             ["tips" => "主题礼包", "rcid" => "58", "old_aid" => 0],
        "theme_pack2" =>            ["tips" => "主题礼包2", "rcid" => "59", "old_aid" => 0],
        "pick_one" =>               ["tips" => "三选一活动", "rcid" => "60", "old_aid" => 0],
        "time_limited_card" =>      ["tips" => "限时卡组", "rcid" => "61", "old_aid" => 0],
        "club_tournament" =>        ["tips" => "公会锦标赛", "rcid" => "62", "old_aid" => 0],
        "lucky_fox" =>              ["tips" => "幸运狐狸", "rcid" => "63", "old_aid" => 0],
        "black_golden_card_trade" =>["tips" => "星光卡交换", "rcid" => "64", "old_aid" => 0],
        "super_serial_pack4" =>     ["tips" => "六格连环礼包2", "rcid" => "65", "old_aid" => 0],
        "crazy_build" =>            ["tips" => "疯狂建造", "rcid" => "66", "old_aid" => 0],
        "super_bomb" =>             ["tips" => "超级攻击", "rcid" => "67", "old_aid" => 0],
        "club_garden" =>            ["tips" => "公会花园", "rcid" => "68", "old_aid" => 0],
        "great_memories" =>         ["tips" => "回归签到", "rcid" => "69", "old_aid" => 0],
        "perfect_steal" =>          ["tips" => "完美偷袭", "rcid" => "70", "old_aid" => 0],
        "super_collect2" =>         ["tips" => "漂流宝藏", "rcid" => "71", "old_aid" => 0],
        "perfect_attack" =>         ["tips" => "完美打", "rcid" => "72", "old_aid" => 0],
        "perfect_chestSpins" =>     ["tips" => "皮肤宝箱最大体力", "rcid" => "73", "old_aid" => 0],
        "perfect_richKing" =>       ["tips" => "richking最大金币", "rcid" => "74", "old_aid" => 0],
        "build_rank" =>             ["tips" => "建筑锦标赛(有进度)", "rcid" => "75", "old_aid" => 0],
        "special_notice" =>         ["tips" => "特殊公告", "rcid" => "76", "old_aid" => 0],
        "super_gashapon" =>         ["tips" => "超级扭蛋", "rcid" => "77", "old_aid" => 0],
        "pinata" =>                 ["tips" => "皮纳塔嘉年华", "rcid" => "78", "old_aid" => 0],
        "super_serial_pack5" =>     ["tips" => "有进度六格连环礼包", "rcid" => "79", "old_aid" => 0],
        "super_collect3" =>         ["tips" => "漂流宝藏2", "rcid" => "80", "old_aid" => 0],
        "super_serial_pack6" =>     ["tips" => "有进度连环礼包1", "rcid" => "81", "old_aid" => 0],
        "super_serial_pack7" =>     ["tips" => "有进度连环礼包2", "rcid" => "82", "old_aid" => 0],
        "surprise_collect" =>       ["tips" => "惊喜付费-偷", "rcid" => "85", "old_aid" => 0],
        "king_of_cards" =>          ["tips" => "卡牌之王", "rcid" => "86", "old_aid" => 0],
        "easter_egg2" =>            ["tips" => "四选一活动-宝藏树屋", "rcid" => "90", "old_aid" => 0],
        "surprise_collect_attack" =>["tips" => "惊喜付费-打", "rcid" => "91", "old_aid" => 0],
        "lucky_journey" =>          ["tips" => "幸运旅途", "rcid" => "92", "old_aid" => 0],
        "one_plus_two" =>           ["tips" => "1+2礼包活动", "rcid" => "93", "old_aid" => 0],
        "one_plus_three" =>         ["tips" => "1+3礼包活动", "rcid" => "94", "old_aid" => 0],
        "surprise_card" =>          ["tips" => "惊喜事件牌", "rcid" => "95", "old_aid" => 0],
        "easter_egg3" =>            ["tips" => "四选一活动-深海宝藏", "rcid" => "96", "old_aid" => 0],
        "serial_missions" =>         ["tips" => "每日成就任务", "rcid" => "97", "old_aid" => 0],

        "crazy_token" =>         ["tips" => "疯狂代币", "rcid" => "98", "old_aid" => 0],

        "tarot" =>                  ["tips" => "塔罗牌", "rcid" => "101", "old_aid" => 0],
        "club_farm" =>              ["tips" => "公会农场", "rcid" => "102", "old_aid" => 0],
        "lucky_dice" =>             ["tips" => "幸运骰子", "rcid" => "103", "old_aid" => 0],
        "coin_push_mania" =>        ["tips" => "推币机活动", "rcid" => "104", "old_aid" => 0],
        "jackpot" =>                ["tips" => "jackpot老虎机", "rcid" => "105", "old_aid" => 0],
        "running_rabbit" =>         ["tips" => "暴走的兔子", "rcid" => "106", "old_aid" => 0],
        "dream_missions" =>         ["tips" => "付费成就活动", "rcid" => "107", "old_aid" => 0],
        "lucky_scratch" =>          ["tips" => "印章卡活动", "rcid" => "108", "old_aid" => 0],
        "super_serial_pack9" =>     ["tips" => "有进度有广告六格连环礼包", "rcid" => "109", "old_aid" => 0],
        "ad_missions" =>     ["tips" => "广告任务", "rcid" => "110", "old_aid" => 0],
        "one_plus_six" =>     ["tips" => "1+6 礼包", "rcid" => "111", "old_aid" => 0],
        "task_express" =>     ["tips" => "多层刷新任务", "rcid" => "112", "old_aid" => 0],
        "starlight_treasure" =>     ["tips" => "点亮星图活动", "rcid" => "113", "old_aid" => 0],
        "multiRound_time_limited_card" =>     ["tips" => "多轮限时卡组", "rcid" => "114", "old_aid" => 0],
        "token_rank" =>                  ["tips" => "代币锦标赛", "rcid" => "115", "old_aid" => 0],
        "tarot2" =>                  ["tips" => "塔罗牌2:西部矿洞", "rcid" => "116", "old_aid" => 0],
    ];
    //特殊道具活动类型列表
    public $specialActTypeList=[
        "architecture"=>["propsId"=>25,"version"=>"1.7.5"],//建筑大师
//        "balloon"=>["propsId"=>26,"version"=>"1.7.5"],//气球
        "speed_spins"=>["propsId"=>27,"version"=>"1.8.5"],//体力加速
        "coin_blast"=>["propsId"=>28,"version"=>"1.7.7"],//金币爆炸
        "crazy_bet"=>["propsId"=>31,"version"=>"1.7.7"],//疯狂倍率
        "discounts_architecture"=>["propsId"=>32,"version"=>"1.7.7"],//建筑打折
        "card"=>["propsId"=>33,"version"=>"1.7.7"],//卡片爆炸
        "shop_promotion"=>["propsId"=>34,"version"=>"1.7.7"],//商场优惠券
        //"super_collect"=>["propsId"=>35,"version"=>"3.0.0"],//道具型超级收集活动
        "super_balloon"=>["propsId"=>36,"version"=>"1.14.1"],//超级气球
        "traffic_permit_bet"=>["propsId"=>39,"version"=>"1.8.1"],//通行证倍率
        "collect_bet"=>["propsId"=>40,"version"=>"1.8.4"],//收集翻倍
        "easter_egg"=>["propsId"=>41,"version"=>"1.8.4"],//四选一活动
        "treasure"=>["propsId"=>43,"version"=>"2.1.5"],//金币老虎机
        "crazy_card_group"=>["propsId"=>46,"version"=>"2.1.6"],//疯狂的卡组
        "crazy_build"=>["propsId"=>52,"version"=>"2.1.6"],//疯狂建造活动
        "super_bomb"=>["propsId"=>53,"version"=>"2.1.6"],//超级炸弹活动
        "great_memories"=>["propsId"=>54,"version"=>"2.1.7"],//回归签到
        "perfect_steal"=>["propsId"=>55,"version"=>"2.1.7"],//完美偷袭活动
        "perfect_attack"=> ["propsId"=>57,"version"=>"2.1.7"],//完美打
        "perfect_chestSpins"=> ["propsId"=>58,"version"=>"2.1.7"],//皮肤宝箱最大体力
        "perfect_richKing"=> ["propsId"=>59,"version"=>"2.1.7"]//richking最大金币
    ];
    //收集子类型[打,打破,偷,完美偷,一连,二连,三连]
    public $collectGroups = [
        1=>[1,1,1,1,0,0,1],//收集
        2=>[0,0,0,0,1,1,1],//特殊收集
        3=>[0,0,1,1,1,1,1],//特殊收集偷
        4=>[1,1,0,0,1,1,1],//特殊收集打
        5=>[0,0,1,1,0,0,0],//偷
        6=>[1,1,0,0,0,0,0],//打
        7=>[1,0,1,0,1,1,1],//特殊收集偷打
    ];
    //菜单必显项:通行证,排行榜,收集,宝藏探索
    public $beOutShow =['traffic_permit','rank','super_collect','treasure','spins_master'];//,'change_collect','rank2'
    //宝藏配置key
    public $treasureCacheKey =[
        "GiftReceiveStatus"=>"1",//入门礼物领奖状态
        "GiftPackBuyStatus"=>"2",//礼包购买状态
        "TaskOverLimit"=>"3",//任务完成次数
        "TaskCurTaskId"=>"4",//当前任务id
        "TaskCurType"=>"5",//当前任务类型
    ];

    public function delActivity($aid){
        $actInfo = $this->getActivity($aid,true);//刷新活动详情
        if($actInfo['type'] == 'fund'){
            $keys[] = okeys::FundRewardList($aid);
            $keys[] = okeys::FundAidUid($aid);
            $uidArr = oo::commonOprRedis("Activity")->hKeys(okeys::FundAidUid($aid));
            foreach ($uidArr as $uid){
                $keys[] = okeys::FundAid($uid);
            }
            $keys[] = okeys::FundReissue($aid);
            oo::commonOprRedis('activity')->delete($keys);
            $this->activityChangeStatus([
                "actId"    =>$this->act_type['fund']["rcid"],
                "status"   =>0,
                "startTime"=>0,
                "actType"  =>'fund',
                "aid"      =>$aid
            ]);
        }
        $tb = otable::activityConf();
        $res = oo::commonOprDb('account')->query("DELETE FROM {$tb} WHERE id={$aid} LIMIT 1");
        return $res;
    }

    /**
     * Notes:保持活动配置
     * User: wsc
     * Time: 2020/7/17 12:00
     * @param $data
     * @return int|mixed
     */
    public function saveActicity($data,$t=0){
        $tb = otable::activityConf();
        if(intval($data['id'])>0){
            $id =intval($data['id']);
            unset($data['id']);
            $w =" id={$id} ";
            $sql = funs::db_updateSQL($tb,$data,$w);
            $rus = oo::commonOprDb('config')->query($sql);
            $res = $rus?$id:0;

        }else{
            $sql = funs::db_insertSQL($tb,$data);
            $data['start'] = $data['start_time'];
            $data['end'] = $data['end_time'];
            $rus = oo::commonOprDb('config')->query($sql);
            $res = $rus?oo::commonOprDb('config')->insertID():0;
        }
        if($res){
            $act = $this->getActivity($res,true);//刷新活动详情
            //刷新在线活动及权重
            if(isset($data['priority'])||isset($data['is_online'])) {
                $this->changeOnlineWeightActList($act['id'],$act['type'],$act['priority'],$act['is_online']);
            }
            if(isset($data['is_online'])){
                # 激活显示卡组关联头像
                $this->activedTimeLimitedCardGroupAvatar($act, $data['is_online']);
                //刷新在线活动
                $this->getAllOnlineActivityByType($act['type'],true);
                //推送上下线
                oo::logs()->commlog(["方式"=>$t>0?'自动':'手动',"aid"=>$res,"type"=>$act['type'],'is_online'=>$data['is_online']],'crontab/activity_online_or_down');//上下线记录
                $this->pushOnlineActivity($res,$act,$t);
            }
        }
        return $res;
    }

    /**
     * Notes:活动设置在线权重状态
     * User: wsc
     * Time: 2022/4/25 20:33
     * @param $aid
     * @param $actType
     * @param $weight
     * @param $status
     * @return bool
     */
    public function changeOnlineWeightActList($aid,$actType,$weight,$status){
        $key = okeys::activityOnlineMultiOpen($actType);
        if($status>0){
            oo::commonOprRedis('common')->zAdd($key,$weight,$aid);
        }else{
            oo::commonOprRedis('common')->zDelete($key,$aid);
        }
        return true;
    }

    /**
     * Notes:活动上线时，激活卡组关联头像框
     * User: xwy
     * Time: 2022/05/19 10:33
     * @param  $act
     */
    public function activedTimeLimitedCardGroupAvatar($act,$isOnline){
        if($act['type'] != 'time_limited_card')return;
        if( $isOnline < 1 )return;
        $time = time();
        $avatarTable = otable::avatarConfig();
        $avatarKey = okeys::avatarConfig();
        $extraData = is_array($act['extraData']) ? $act['extraData'] : json_decode($act['extraData'], true);
        $themeId = intval($extraData['themeId']);
        $sql = "select * from {$avatarTable} where `type`=3 and `theme_id`=".$themeId;
        $avatarConfigs = oo::commonOprDb('common')->getAll($sql);
        foreach ($avatarConfigs as $avatarConfig){
            oo::commonOprDb('common')->query("update {$avatarTable} set `active`=1,`last_online_time`={$time} where `avatar_id`=".$avatarConfig['avatar_id']);
        }
        oo::commonOprRedis('common')->delete($avatarKey);
    }
    /**
     * Notes:获取活动配置
     * User: wsc
     * Time: 2020/7/17 12:07
     * @param $aid
     * @param bool $db
     * @return array
     */
    public function getActivity($aid,$db=false){
        $key = okeys::activityInfo($aid);
        $cache = oo::commonOprRedis('config')->hGetAll($key);
        if(!$cache['id']||$db){
            if(!$db){
                oo::logs()->commlog(["aid"=>$aid,"error"=>"not find actInfo"],'activity/notCfg');
            }
            $tb =otable::activityConf();
            $sql = "SELECT * FROM {$tb} WHERE id={$aid}";
            $data = oo::commonOprDb('common')->getOne($sql,1);
            if(!empty($data)){
                $cache = $data;
                oo::commonOprRedis('config')->hMset($key,$data);
                oo::commonOprRedis('config')->expire($key,oo::redisRandomExpire(31*86400));
            }
        }
        return $cache;
    }

    /**
     * Notes:获取活动列表
     * User: wsc
     * Time: 2020/8/12 18:26
     * @param $w
     * @return array
     */
    public function getActivityList($w){
        $tb = otable::activityConf();
        $sql = "SELECT * FROM {$tb} $w";
        $data = oo::commonOprDb('config')->getAll($sql,1);
        return $data;
    }

    /**
     * Notes:保存活动奖励配置
     * User: wsc
     * Time: 2020/7/17 12:00
     * @param $data
     * @return bool
     */
    public function saveActReward($data){
        $tb = otable::activityStageRewardConf();
        $aid = intval($data['aid']);
        $aReward = $this->getActReward($aid);
        if($aReward){
            $w="aid={$aid}";
            unset($data['aid']);
            $sql = funs::db_updateSQL($tb,$data,$w);
            $rus = oo::commonOprDb('config')->query($sql);
            $res = $rus?$aid:0;
//            oo::logs()->debug3(["update:{$res}",$sql],'activity.txt');
        }else{
            $sql = funs::db_insertSQL($tb,$data);
            $rus = oo::commonOprDb('config')->query($sql);
//            oo::logs()->debug3(['insert'=>$rus,$sql],'activity.txt');
            $res = $rus?$aid:0;
            if($res&& in_array($data['type'],["rank","rank2"])){//创建排行记录表
                $this->createRankLogDB($aid);
            }
            if($res&&in_array($data['type'],['rank','super_collect'])){//创建进度记录表 rank2无进度
                $this->createActStageLog($aid);
                if($data['type'] == "super_collect"){
                    //删除记录
                    oo::commonOprRedis('config')->delete(okeys::getCollectSumNum($aid));
                }
            }
        }
        if($res){
            $this->getActReward($aid,true);
        }
        return true;
    }

    /**
     * Notes:获取奖励配置
     * User: wsc
     * Time: 2020/7/17 12:00
     * @param $aid
     * @param bool $db
     * @return array
     */
    public function getActReward($aid,$db=false){
        $key = okeys::activityReward($aid);
        $djson = oo::commonOprRedis('config')->hGetAll($key);
        $cache = funs::getArrayFromOne($djson);
        if(!$cache['type']||$db){
            if(!$db){
                oo::logs()->commlog(["aid"=>$aid,"error"=>"not find actReward"],'activity/notCfg');
            }
            $tb =otable::activityStageRewardConf();
            $sql = "SELECT * FROM {$tb} WHERE aid={$aid}";
            $data = oo::commonOprDb('common')->getOne($sql,1);
            if(!empty($data)){
                $cache = $data;
                $cache['reward'] = json_decode($data['reward'],true);
                $cache['extra_reward'] = json_decode($data['extra_reward'],true);
                oo::commonOprRedis('config')->hMset($key,$data);
                oo::commonOprRedis('config')->expire($key,oo::redisRandomExpire(31*86400));
            }
        }
        return $cache;
    }

    /**
     * Notes:设置活动公用配置
     * User: wsc
     * Time: 2020/10/21 20:09
     * @param $data
     * @return int|mixed
     */
    public function saveActCommonCfg($data){
        $tb = otable::activityConmmonConf();
        $type = $data['type'];
        $conf = $this->getActCommonCfg($type);
        if($conf){
            $w="type='{$type}'";
            unset($data['type']);
            $sql = funs::db_updateSQL($tb,$data,$w);
            $rus = oo::commonOprDb('config')->query($sql);
            $res = $rus?$type:0;
        }else{
            $sql = funs::db_insertSQL($tb,$data);
            $rus = oo::commonOprDb('config')->query($sql);
            $res = $rus?$type:0;
        }
        if($res){
            $this->getActCommonCfg($type,true);
        }
        return $res;
    }

    /**
     * Notes:获取活动公用配置
     * User: wsc
     * Time: 2020/10/21 20:10
     * @param string $type
     * @param bool $db
     * @return array
     */
    public function getActCommonCfg($type='',$db=false){
        $cache =[];
        $key = okeys::activityCommonCfg();
        $djson = oo::commonOprRedis('config')->hGetAll($key);
        $cache = funs::getArrayFromOne($djson);
        if((!$type&&empty($cache[$type]))||!$cache||$db){
            $tb = otable::activityConmmonConf();
            $sql = "SELECT * FROM {$tb}";
            $datas = oo::commonOprDb('common')->getAll($sql,1);
            if(!empty($datas)){
                foreach ($datas as $v){
                    $data[$v['type']] = $v['config'];
                }
                oo::commonOprRedis('config')->hMset($key,$data);
                oo::commonOprRedis('config')->expire($key,oo::redisRandomExpire(7*86400));
            }
        }
        if(!empty($cache)&&$type){
            $cache = $cache[$type]?$cache[$type]:[];
        }
        return $cache;

    }

    /**
     * Notes:获取不同等级不同类型的金币奖励
     * User: wsc
     * Time: 2020/7/27 10:45
     * @param $type
     * @param $level
     * @param bool $db
     * @return mixed
     */
    public function getCoinRewardByTypeAndLevel($type,$level,$db=false){
        $key= okeys::activityCoinRewardByType($type);
        $value = oo::commonOprRedis('config')->hGet($key,$level);
        if(!$value){
            $value = oo::commonOprRedis('config')->hGet(okeys::activityCoinRewardByType('collect'),$level);
        }
        if(!$value||$db){
            $tb = otable::ActivityCoins();
            $sql = "SELECT * FROM {$tb}";
            $data = oo::commonOprDb('config')->getAll($sql,1);
            if(!empty($data)){

                $fd = $data[0];
                unset($fd['levelId']);
                $fields = array_keys($fd);

                array_push($fields,'collect_only');//附加
                array_push($fields,'super_collect');//附加
                array_push($fields,'spins_master');//附加
                foreach ($data as $k=>$v){
                    $v['collect_only'] = $v['collect'];
                    $v['super_collect'] = $v['collect'];
                    $v['spins_master'] = $v['collect'];
                    foreach ($fields as $field){
                        $reward[$field][$v['levelId']] = $v[$field];
                    }
                    if($level==$v['levelId']){
                        $value = $v[$type];
                    }
                }
                foreach ($fields as $field){
                    oo::commonOprRedis('config')->hMset(okeys::activityCoinRewardByType($field),$reward[$field]);
                }
            }
        }
        return max(1,intval($value));
    }

    /**
     * Notes:获取所有在线活动，根据类型
     * User: wsc
     * Time: 2020/7/22 18:10
     * @param string $type 活动类型
     * @param bool $db 是否跟新在线活动
     * @return array [活动id1,活动id2...]
     */
    public function getAllOnlineActivityByType($type,$db=false){
        $key =  okeys::onlineOpenActivity($type);
        $cache = oo::commonOprRedis('config')->hGetAll($key);
        if($db){
            $time = time();
            $tb = otable::activityConf();
            $sql = "SELECT id FROM {$tb} WHERE is_online=1 and start_time<={$time} and end_time>={$time} and type= '{$type}'";
            $data = oo::commonOprDb('config')->getAll($sql,1);
            oo::commonOprRedis('config')->delete($key);
            if(!empty($data)){
                $cache = array_column($data, 'id');
                oo::commonOprRedis('config')->hMset($key,$cache);
            }else{
                $cache = [];
            }
        }
        return $cache;
    }

    /**
     * Notes:格式化道具格式
     * User: wsc
     * Time: 2020/12/8 21:44
     * @param $uid
     * @param $aid
     * @param $propInfo
     * @param int $bet
     * @return array
     */
    public function getFormattingProps($uid,$aid,$propInfo,$bet=10000,$actType=''){
        $num = $propInfo['num'];
        $value = null;
        switch ($propInfo['type']){
            case 13://金卡处理
                if($propInfo['rtype']==1||$propInfo['rtype']==3){//固定金卡
                    $value = [$this->getRankCard($uid,$aid,true)];
                }
                break;
            case 14://金币处理
                if ($propInfo['rtype'] == 2) {
                    $num = intval($bet * $num);
                }
                break;
            case 18://小丑卡
                $value = time()+86400;
                break;
            case 41:
                //四选一活动
                $value['skin'] = $propInfo['skin'];
            default:
                break;
        }
        $pConf = oo::commonOprModel('props')->getChestData($uid,$propInfo['type'],false,intval($propInfo['skin']));//特殊宝箱道具类过滤装配
        if($pConf){
            $value = $pConf;
        }
        $data = [
            "propsId"=>$propInfo['type'],
            "num"    =>intval($num),
        ];
        if($propInfo['type']==13){
            $data['rtype'] =  $propInfo['rtype'];
        }
        if($value){
            $data["value"] = $value;
        }
        return $data;
    }

//=====================系统任务===================================

    /**
     * Notes:清理用户活动缓存
     * User: wsc
     * Time: 2020/8/6 15:38
     * @param $uid
     * @param $actInfo
     * @return bool
     */
    public function clearUserActLog($uid,$actInfo,$isOpt=false){
        $aid = $actInfo['id'];
        $type = $actInfo['type'];
        $delList = [
//            okeys::userBindActivityRewardCfg($uid,$aid),//绑定的阶段奖励配置(1.8.0后去除)
//            okeys::userBindActAbTest($type,$uid),//AB Test 活动绑定
        ];
        $bindKey = okeys::userBindActivity($type,$uid);
        if($isOpt){//强制手动下线
            $delList[] = $bindKey;//用户绑定活动信息
            if(in_array($type,["rank","rank2"])){//清理结算待领取奖励
                $typ =  $type=='rank'?"":"rank2";
                $kk =okeys::waitRankEndReward($uid,$typ);
                oo::commonOprRedis('common')->hDel($kk,$aid);
            }
        }else{
            // 解绑兜底策略
            $bindAid = oo::commonOprRedis('common')->get($bindKey);
            if($bindAid&&$aid==$bindAid){
                $delList[] = $bindKey;
            }
        }
        if($type=='rank' || $type=='rank2'){//排行榜领奖状态
            if(IS_DEBUF){
                $delList[] = okeys::activityRankRewardStatus($uid, $aid);//排行榜领奖状态
            }
//            $delList[] = okeys::activityUserRankCard($uid,$aid);//用户卡片(已设置自动过期)
        }
        if(in_array($type,['rank','super_collect'])){//进度记录
            $delList[] =okeys::userBindActRid($uid,$aid);//个人绑定的进度奖励方案id
            $k1 = okeys::userActivityStageRate($uid,$aid);//用户阶段进度信息(已设置活动结束时间后一天过期)
            $delList[] = $k1;
            $ts = date('Ymd',$actInfo['end_time']);
            $info = oo::commonOprRedis('activity')->hGetAll($k1);
            $rid =intval(oo::commonOprRedis('activity')->get(okeys::userBindActRid($uid,$aid)));
            $rid = $rid>0?$rid:1;
            //oo::commonOprRedis('Statistics')->lPush(okeys::activityStageLog(),json_encode(["aid"=>$aid,"uid"=>$uid,"stage"=>intval($info['stage']),"rate"=>intval($info['rate']),"type"=>2,"times"=>$ts,"rid"=>$rid]));
        }
        if($type == "rank2"){
            $k1 = okeys::userActivityStageRate($uid,$aid);//用户阶段进度信息(已设置活动结束时间后一天过期)
            $delList[] = $k1;
        }
        if($type=='time_limit_invite'){
            $delList[] = okeys::activityInviteUserList($uid,$aid);//用户邀请记录
            $dalList[] =okeys::activityInviteUserRate($aid,$uid);//完成邀请进度绑定
            $delList[] =okeys::activityInviteRewardStage($aid,$uid);//进度奖励领取情况
        }
        if($type=='accumulated_pay'){
            $delList[] =okeys::activitySumPayNum($aid,$uid);//累充进度
            $delList[] =okeys::activitySumPayReceiveLog($aid,$uid);//阶段阶段领奖记录
        }
        if($type=='spins_master'){//体力大师
            $delList[] = okeys::activityCommonRateSumScore($aid,$uid);
            $delList[] = okeys::activityCommonRateReceiveLog($aid,$uid);
        }
        if($type=='speed_spins'){//体力加速
            $delList[] = okeys::SpeedUpSpins($uid);
        }
        if($type=='daily_chest'){
            $delList[]=okeys::dailyChest($uid);
            $delList[] = okeys::userDailyChest($uid);
            $delList[] = okeys::daliyChestNextTime($uid);
        }
        if($type=='treasure'){
            $delList[] =okeys::TreasureBetCache($aid,$uid);
        }
        if(in_array($type,['super_serial_pack','super_serial_pack2'])){
            $delList[] = okeys::buySuperSerialPackTimes($aid,$uid);//新购买次数
        }
        if(IS_DEBUF){
            if($type=='super_serial_pack'){
                $delList[] = okeys::bindSuperSerialPack($uid);//绑定的活动id
                $delList[] = okeys::buySuperSerialPackTimes($aid,$uid);//新购买次数
            }
            if($type=='super_serial_pack2'){
                $delList[] = okeys::bindSuperSerialPack2($uid);//绑定的活动id
                $delList[] = okeys::buySuperSerialPackTimes($aid,$uid);//新购买次数
            }
            if($type=='callback_score'){
                oo::commonOprModel('callback')->clearUserCache($uid,$aid);
            }
        }
        oo::commonOprRedis('activity')->delete($delList);
        return true;
    }

    /**
     * Notes:清理活动缓存
     * User: wsc
     * Time: 2020/8/13 14:49
     * @param $aid
     * @param $actInfo
     * @param $isOpt //是否是手动下线
     */
    public function clearActCache($aid,$actInfo,$isOpt=false){
        $keys[1] =  okeys::bindActivityList($aid);
        $userlist = oo::commonOprRedis('activity')->sMembers($keys[1]);//所有参加$aid活动的人
        foreach ($userlist as $k=>$uid){
            $this->clearUserActLog($uid,$actInfo,$isOpt);
        }
        if($actInfo['type']=='rank' || $actInfo['type']=='rank2'){
            $keys[2] =  okeys::RankUserSetId($aid);//排行榜默认分块
            $keys[] =  okeys::RankUserSpinsSetId($aid);//排行榜体力分块
            $setIds = [0,1,2,3,4,5,6,7,8,9,10];
            foreach ($setIds as $setId){
                $keys[] = okeys::activityRankRoomList($aid,$setId);//活动分块房间列表
            }
            $roomIdList = oo::commonOprRedis('activity')->hKeys(okeys::activityRankRoomList($aid));
            oo::commonOprRedis('activity')->expire(okeys::activityRankRoomList($aid),oo::redisRandomExpire(86400));//活动房间列表
            foreach ($roomIdList as $roomId){
                oo::commonOprRedis('activity')->expire(okeys::activityRoomUserList($aid,$roomId),oo::redisRandomExpire(86400));//排行榜活动-房间内用户列表(真人和机器人)
                oo::commonOprRedis('activity')->expire(okeys::activityUserRankList($aid,$roomId),oo::redisRandomExpire(86400*3));//排行榜活动-房间用户排行，保留三天
            }
//            $roomIdList = oo::commonOprRedis('activity')->hKeys(okeys::RankUserSpinsSetId($aid));
//            foreach ($roomIdList as $roomId){
//                $keys[] = okeys::activityRoomUserList($aid,$roomId);//排行榜活动-房间内用户列表
//                oo::commonOprRedis('activity')->expire(okeys::activityUserRankList($aid,$roomId),oo::redisRandomExpire(86400*3));//排行榜活动-房间用户排行，保留三天
//            }
//        $keys[] = okeys::activityUserRankBindRoomId($aid);//排行榜活动用户与房间绑定关系 aid:uid=>roomId
            $keys[] = okeys::activityUserRankList($aid,0);//排行榜活动-未加入房间的用户分数
            $keys[] = okeys::ActivityBuyGoods($aid);//排行榜活动-活动期间支付
            $keys[] = okeys::UserRankSpendSpins($aid);//排行榜活动-活动期间体力开销
            oo::commonOprRedis('activity')->expire(okeys::activityUserRankBindRoomId($aid),oo::redisRandomExpire(86400*3));
        }
        if($actInfo['type']=='architecture'){
            $keys[] =okeys::BuildMaster($aid);//建筑大师待领奖记录
        }
        if(in_array($actInfo['type'],['time_limit_invite','shop_promotion'])){
            $keys[] = okeys::activityApply($aid);//报名记录
            $keys[] = okeys::activityInviteRank($aid);//邀请排行榜
        }

        if($actInfo['type']=='treasure'){//清理连环礼包次数记录
            $keys[] = okeys::TreasureTaskId($aid);
//            $keys[] = okeys::TreasureTaskId($aid, '2'); //1.14版本新版本宝藏活动key
            $keys[] = okeys::TreasureTaskNum($aid);
            $keys[] = okeys::TreasureTaskGift($aid);
            $keys[] = okeys::TreasureCurTaskType($aid);
            $keys[] = okeys::TreasureSpend($aid);
            $keys[] = okeys::treasureQuestGiftLog($aid);
        }

        if($actInfo['type']=='traffic_permit'){//清理连环礼包次数记录
            $keys[] = okeys::TrafficPermitCurNum($aid);
            $keys[] = okeys::TrafficPermitReward($aid);
            $keys[] = okeys::TrafficPermitTaskCurNum($aid);
        }
        if($actInfo['type']=='shop_promotion'){//清理购买记录
            $keys[] = okeys::ShopPromotionBuyNumber();
        }
        if($actInfo['type']=='super_serial_pack'||$actInfo['type']=='super_serial_pack2'){
            $keys[] = okeys::buySuperSerialPackLimit($aid);//超级连环礼包次数
        }
        if($actInfo['type']=='spin_safe'){//清理体力存钱罐记录
            $keys[] = okeys::SteelSafeCurNum($aid);
            $keys[] = okeys::SteelSafeCurProgress($aid);
        }
        if($actInfo['type']=='choose_one'){//清理二选一活动
            $keys[] = okeys::ChooseOneStatus($aid);
        }
        if($actInfo['type']=='one_plus_gift'){//清理1+1礼包
            $keys[] = okeys::onePlusGiftBuyNum($aid);
            $keys[] = okeys::onePlusGiftBuyStatus($aid);
        }
        if($actInfo['type']=='safe_surprise'){//清理1+1礼包
            $keys[] = okeys::safeSurpriseBuyStatus($aid);
        }
        if($actInfo['type']=='super_collect'){
            $keys[] = okeys::getCollectActSpins($aid);
            $keys[] = okeys::getCollectActAdd($aid);
            $keys[] = okeys::getCollectSumNum($aid);
        }
        oo::commonOprRedis('activity')->delete($keys);//清理所有参加$aid活动的人
        $res = $this->saveActicity(["id"=>$aid,"joinNum"=>count($userlist)]);//记录活动参与人数
        oo::logs()->commlog(["方式"=>$isOpt?'手动':'自动',"aid"=>$aid,"type"=>$actInfo['type'],'joinNum'=>count($userlist),"saveRes"=>$res],'crontab/clearAct');
    }

    /**
     * Notes:推活动上下线
     * User: wsc
     * Time: 2020/7/27 10:46
     * @param $aid
     * @param $type
     * @param $online
     */
    public function pushOnlineActivity($aid,$actInfo,$t){
        $type= $actInfo['type'];
        $online =intval($actInfo['is_online']);
        if(intval($actInfo['uc_type'])==1){//道具型排期不推送
            return true;
        }
        $data = [
            "actId"=>$this->act_type[$type]["rcid"],
            "status"=>$online,
            "startTime"=>0,
            "actType"=>$type,
            "aid"=>$aid
        ];
        //新活动上线,添加活动资源md5信息
//        $jsonStr = $online==1 ? oo::commonOprRedis('activity')->get(okeys::activityM5Json($aid)) : '';
//        if($jsonStr){
//            $data['ActivityMd5'] = (array)json_decode($jsonStr, true);
//        }
        // 通知golang 业务活动上下线 nsq 推送
        $this->activityChangeStatus($data,$actInfo);
        if($online==1){//上线
            //设置过期活动用户绑定列表过期时间
            $keyA =okeys::bindActivityList($aid);
            oo::commonOprRedis('activity')->sAdd($keyA,4806046);
            oo::commonOprRedis('activity')->expireAt($keyA,$actInfo['end_time']+3600*2);
            //活动上线firebase推送任务
            $this->joinPushTask($aid,1);
            if(in_array($type,['time_limit_invite','shop_promotion'])){
                //设置报名记录过期时间
                oo::commonOprRedis('activity')->hSet(okeys::activityApply($aid),100001,1);
                oo::commonOprRedis('activity')->expireAt(okeys::activityApply($aid),oo::redisRandomExpire($actInfo['end_time']));
//                if($type=='time_limit_invite'){
//                    oo::commonOprRedis('activity')->expireAt(okeys::activityInviteRank($aid),oo::redisRandomExpire($actInfo['end_time']));//邀请排行榜过期
//                }
            }
        }else{//下线
            $isOpt = $t>0?false:true;
            $this->clearActCache($aid,$actInfo,$isOpt);
        }
    }

    /**
     * Notes:活动推送任务
     * User: wsc
     * Time: 2020/11/9 21:45
     * @param $aid
     * @param int $do
     * @return bool
     */
    public function joinPushTask($aid,$do=1){
        $actInfo = oo::commonOprModel('activitynew')->getActivity($aid);
        $pushCfg = oo::commonOprModel('push')->getPushConf();
        $passArr = [];
        foreach ($pushCfg as $v){
            if(in_array($v['class'],['activityOnline','activityReward'])&&$v['status']==1){
                array_push($passArr,$v['type']);
            }
        }
        if(!in_array($actInfo['type'],$passArr)||$actInfo['openPush']!=1){
            return false;
        }

        $type =$actInfo['type'];
        $data =[
            "actId"=>$this->act_type[$type]["rcid"],
            "status"=>0,
            "startTime"=>0,
            "actType"=>$type,
            "aid"=>$aid,
        ];;
        funs::SendNsqMsg(ocmd::TopicActOnlineFirebase,[],$data);

        if($do==1){//新增活动上线异步任务
            $arg[0] =$aid;
        }else if($do==2){//排行榜活动发奖推送异步任务
            $arg[0] =$aid;
            $arg[1] =14;
        }
//        $task = json_encode(["do"=>$do,"arg"=>$arg]);
//        oo::commonOprRedis('statistics')->lPush(okeys::longTimeTask(),$task);
        return true;
    }


    /**
     * Notes:发送活动上下线推送消息
     * User: wsc
     * Time: 2020/8/6 14:15
     * @param $data
     * @return bool
     */
    public function activityChangeStatus($data,$actInfo=[]){
        //告知golang活动服务 活动上线下通知
        funs::SendNsqMsg(ocmd::TopicActOnlineOff,[],["aid"=>$data["aid"],"actType"=>$data["actType"],"status"=>$data["status"]]);
//        关闭workman推送
//        if($data['status'] == 0){
//            oo::commonOprModel('Workerman')->pushAll(ocmd::$send['ActivityChangeStatus_New'],$data);
//        }else{
//            //消息队列通知每台服务器上的在线玩家活动切换
//            oo::commonOprModel('Workerman')->pushFun('activitynew', 'activityCircleChangeStatus', [$data]);
//        }
        return true;
    }

    /**
     * 通知当前服务器节点的在线玩家活动切换
     * @param array $data
     */
    public function activityCircleChangeStatus($data) {
        $online = oo::commonOprModel('Workerman')->getCurAllUidList();
        $i = 0;
        foreach ($online as $uid){
            $i++;
            //直接推送当前节点
            oo::commonOprModel('Workerman')->pushCur($uid,ocmd::$send['ActivityChangeStatus_New'],$data);
            if($i == 200){
                //$data['startTime'] += 2;
                usleep(50000);
                $i = 0;
            }
        }
    }

    /**
     * Notes:公用活动推送
     * User: wsc
     * Time: 2020/12/3 11:22
     * @param $type
     * @param $do
     * @param array $uidList
     * @return bool
     */
    public function activityCommonPush($type,$do,$uidList=[],$aid=0,$actType=""){
        $data =[
            "aid"=>$aid,
            "actType"=>$actType,
            "status"=>$do
        ];
        if($type=='collect'){
            $data['ts'] = $do==1?intval(oo::commonOprRedis('config')->ttl(okeys::timeLimitAct($aid)))+time():0;
            $data['do'] = $do==1?"start":"stop";
            $data['cmd'] = ocmd::$send['Activity_timeCollect'];
        }else if($type=='collect_bet'){
            $data['ts'] = $do==1?intval(oo::commonOprRedis('config')->ttl(okeys::timeLimitBetAct($aid)))+time():0;
            $data['do'] = $do==1?"start":"stop";
            $data['cmd'] = ocmd::$send['Activity_timeCollectBet'];
        }
        funs::SendNsqMsg(ocmd::TopicActTimeLimit,[],$data);
        oo::commonOprModel('workerman')->pushFun('activitynew', 'activityCircleCommonPush', [$type, $do, $uidList,$aid,$actType]);
    }
//    public function activityCommonPush($type,$do,$uidList=[],$aid=0){
//        oo::commonOprModel('workerman')->pushFun('activitynew', 'activityCircleCommonPush', [$type, $do, $uidList,$aid]);
//    }

    /**
     * 通知当前服务器节点的在线玩家公用活动推送
     * @param $type
     * @param $do
     * @param $uidList array
     * @param $aid
     */
    public function activityCircleCommonPush($type,$do,$uidList=[],$aid,$actType=""){
        $data['status']  = $do;
        $data['actType'] = $actType;
        $online = oo::commonOprModel('Workerman')->getCurAllUidList();
        if($type=='collect'){
            $ocmd = ocmd::$send['Activity_timeCollect'];
            $data['ts'] = $do==1?intval(oo::commonOprRedis('config')->ttl(okeys::timeLimitAct($aid)))+time():0;
            $data['do'] = $do==1?"start":"stop";
            $pushList = $online;
        }
        if($type=='collect_bet'){
            $ocmd = ocmd::$send['Activity_timeCollectBet'];
            $data['ts'] = $do==1?intval(oo::commonOprRedis('config')->ttl(okeys::timeLimitBetAct($aid)))+time():0;
            $data['do'] = $do==1?"start":"stop";
            $pushList = $online;
        }
        if($type=='rank'){
            $ocmd = ocmd::$send['Act_overCheckRank'];
            $data['ts'] =0;
            $data['do'] = 'overCheckRank';
            $pushList = !empty($uidList)?array_intersect($uidList,$online):$online;
        }
        $i = 0;
        foreach ($pushList as $uid){
            $i++;
            oo::commonOprModel('Workerman')->pushCur($uid,$ocmd,$data);
            if($i == 200){
                usleep(50000);
                $i = 0;
            }
        }
        return true;
    }

    /**
     * Notes:定时器排期，发奖
     * User: wsc
     * Time: 2020/8/12 13:41
     */
    public function cronToActivity($now){
        //定时排期上下线活动
        $ts = intval(strtotime(date('YmdHi',$now)));
        $res['ts']  =$ts;
        $w = " where end_time={$ts} or start_time={$ts}";
        $outOnlineList =$this->getActivityList($w);
        if(!empty($outOnlineList)){
            foreach ($outOnlineList as $k=>$v){
                $d['id']=$v['id'];
                $d['is_online'] = $v['is_online']>0?0:1;
                if($v['end_time']==$ts){//结束时间强制下线
                    $d['is_online'] = 0;
                }
                $res1 = $this->saveActicity($d,1);
                $res['actOnline'][$v['id']] = ["res"=>$res1,"actInfo"=>$v,"online"=>"{$v['is_online']} => {$d['is_online']}"];
                if ($d['is_online']==0&&$v['type']=="time_limit_invite"){//NSQ 推送限时邀请异步发奖
                    funs::SendNsqMsg(ocmd::TopicActTimeLimitInviteReward,[],["aid"=>$v['id']]);
                }
            }
        }
        if(IS_DEBUF){//强制下线不在活动期内,却又在线的活动
            $w2 = " where is_online=1 and (end_time<{$ts} or start_time>{$ts})";
            $needOutAct = $this->getActivityList($w2);
            if(!empty($needOutAct)){
                foreach ($needOutAct as $k=>$v){
                    $d['id']=$v['id'];
                    $d['is_online']=0;
                    $res2 = $this->saveActicity($d,1);
                    $res['forceActOnline'][$v['id']] = ["res"=>$res2,"actInfo"=>$v,"online"=>"{$v['is_online']} => {$d['is_online']}","sn_ts"=>date('Ymd H:i',$v['start_time']).'到'.date('Ymd H:i',$v['end_time']),"downOnline"=>date('Ymd H:i',$ts)];
                }
            }
        }

        //定期开启限时收集
        $this->setNewCollectTimeLimit($now);
//        $this->setCollectTimeLimit($now);

        //定期开启邀请榜机器人
//        $aids2 = $this->getAllOnlineActivityByType('time_limit_invite');
//        if($aids2[0]){
//            $actInfo = $this->getActivity($aids2[0]);
//            if(date('YmdHi',($actInfo['start_time']+30*60))==date('YmdHi',$now)){
//                $this->addRobotInviteRank($aids2[0]);//邀请排行榜加机器人
//            }
//        }
        return $res;
    }

    /**
     * Notes:定时发排行榜奖励
     * User: wsc
     * Time: 2020/11/25 15:02
     * @param $now
     */
    public function cronToCheckRankReward($now){
        //结算排行榜奖励
        $aids1 =  $this->getAllOnlineActivityByType('rank',true);
        $aids2 =  $this->getAllOnlineActivityByType('rank2',true);
        $aids = array_unique(array_merge($aids1,$aids2));
        foreach ($aids as $aid){
            $actInfo = $this->getActivity($aid);
            $time = date('YmdHi',$actInfo['reward_time']);
            if(date('YmdHi',$now)==$time){
                $data =[
                    "aid"=>$aid,
                    "actType"=>$actInfo["type"]
                ];;
                funs::SendNsqMsg(ocmd::TopicActRankEndReward,[],$data);
            }
        }
//        if($aids[0]){
//            $aid = $aids[0];
//            $actInfo = $this->getActivity($aid);
//            $time = date('YmdHi',$actInfo['reward_time']);
//            if(date('YmdHi',$now)==$time){
//                $data =[
//                    "aid"=>$aid,
//                ];;
//                funs::SendNsqMsg(ocmd::TopicActRankEndReward,[],$data);
//
////                $ts1 = oo::getMsectime();
////                $res['checkUidList'] =  $this->checkRankRewardRobot($aid);//增加机器人排行榜记录落地
////                $ts2 = oo::getMsectime();
////                oo::logs()->commlog(["aid"=>$aid,"ts"=>$ts2-$ts1,"num"=>count($res['checkUidList'])],'crontab/rankSendReward.log');
//
//            }
//        }
        return true;
    }
    public function cronToCheckRank2Reward($now){
        $res = true;
        //结算无进度排行榜奖励
        $aids =  $this->getAllOnlineActivityByType('rank2',true);
        if($aids[0]){
            $aid = $aids[0];
            $actInfo = $this->getActivity($aid);
            $time = date('YmdHi',$actInfo['reward_time']);
            if(date('YmdHi',$now)==$time){
                $data =[
                    "aid"=>$aid,
                    "actType"=>'rank2'
                ];;
                funs::SendNsqMsg(ocmd::TopicActRankEndReward,[],$data);

//                $ts1 = oo::getMsectime();
//                $res['checkUidListNoPro'] =  $this->checkRankRewardRobotNoPro($aid);//增加机器人排行榜记录落地
//                $ts2 = oo::getMsectime();
                oo::logs()->commlog(["aid"=>$aid,"type"=>"rank2","content"=>ocmd::TopicActRankEndReward],'crontab/rankSendReward.log');
//                $this->joinPushTask($aid,2);//结算异步推送离线
            }
        }
        return $res;
    }

    /**
     * Notes:活动上线fasebase推送入队
     * User: wsc
     * Time: 2020/11/6 17:48
     * @param int $aid 要推送的活动
     * @param int $do 推送内容 1活动上线
     * @return boolean
     */
    public function actOnlneFasebasePush($aid){
        $actInfo = oo::commonOprModel('activitynew')->getActivity($aid);
        $pushCfg = oo::commonOprModel('push')->getPushConf();
        foreach ($pushCfg as $v){
            if($v['class']=='activityOnline'&&$v['status']==1&&$actInfo['type']==$v['type']){
                $nid = $v['id'];
                break;
            }
        }
        if(!isset($nid)){
            return false;
        }
        $ts1 = oo::getMsectime();
        $dates = [date('Ymd',time()-86400),date('Ymd',time()-86400*2),date('Ymd',time()-86400*3)];
        $uList = oo::commonOprModel('statistics')->getAllPlayer($dates,2);
        $canSendUserList =[];
        if(!empty($uList)){
            foreach ($uList as $uid){
                $userInfo = oo::commonOprModel('member')->getUserBasic($uid);
                if(!empty($actInfo['user_level_section'])&&$actInfo['user_level_section']!='0-0'&&$actInfo['user_level_section']!='-'){
                    $user_level_section = explode('-',$actInfo['user_level_section']);
                    $maxLv = intval($user_level_section[1]);
                    $minLv = intval($user_level_section[0]);
                    if(($maxLv>=$minLv&&$userInfo['levelId']>$maxLv)||$userInfo['levelId']<$minLv){//用户等级不满足用户等级组
                        continue;
                    }
                }
                if(!empty(json_decode($actInfo['act_version'],true))){//版本不满足时
                    $act_version= json_decode($actInfo['act_version'],true);
                    $dversion =implode('.',array_slice(explode('.',$userInfo['version']),0,3));
                    foreach ($act_version as $v){
                        $str = implode('.',array_slice(explode('.',$v),0,3));
                        $versions[] = $str;
                    }
                    if(!in_array($dversion,$versions)){
                        continue;
                    }
                }

                ///////////////////////////////////////////////
                ///////////////////////////////////////////////
                //ios过审处理,1.11.1以上版本暂时不给活动
                //$sid = (int)oo::commonOprRedis('Userinfo')->hGet(okeys::userDefinedInfo($uid), 'sid');
                //if($sid == 2 && oo::compareVersion(oo::commonOprModel('user')->getUserVersion($uid), '1.11.1')){
                //    continue;
                //}
                ///////////////////////////////////////////////
                ///////////////////////////////////////////////

                array_push($canSendUserList,$uid);
            }
            ////nsq广播通知服务器节点收活动上线fasebase推送入队
            //oo::commonOprModel('Workerman')->pushFun(
            //    'activitynew', 'actOnlneCircleFasebasePush', [$aid, $nid, $canSendUserList]
            //);
            $this->actOnlneCircleFasebasePush($aid, $nid, $canSendUserList);
        }
        $ts2 = oo::getMsectime();
        oo::logs()->commlog(["ts"=>$ts2-$ts1,"aid"=>$aid,"count"=>count($canSendUserList),"nid"=>$nid],'async/joinActFasebasePushList.log');
        return true;
    }

    /**
     * 通知当前节点消息队列接收活动上线fasebase推送入队
     * @param int $aid
     * @param int $nid
     * @param array $canSendUserList
     */
    public function actOnlneCircleFasebasePush($aid, $nid, $canSendUserList){
        $ts1 = oo::getMsectime();
        $onlineList = oo::commonOprModel('Workerman')->getAllUidList();
        $canSendUserList = array_diff($canSendUserList,$onlineList);//驱除在线玩家
        $isBindActUserList = oo::commonOprRedis('activity')->sMembers(okeys::bindActivityList($aid));
        $canSendUserList = array_diff($canSendUserList,$isBindActUserList);//驱除已绑定活动的玩家
        oo::commonOprModel('push')->pushNewsByNid($nid,$canSendUserList);
        $ts2 = oo::getMsectime();
        oo::logs()->commlog(["ts"=>$ts2-$ts1,"aid"=>$aid,"count"=>count($canSendUserList),"nid"=>$nid],'async/joinActFasebaseNsqPushList.log');
    }

    /**
     * Notes:排行榜发奖推送入队
     * User: wsc
     * Time: 2020/11/10 14:33
     * @param $aid
     * @param int $nid
     */
    public function sendRankRewardFasebasePush($aid,$nid=0){
        $key =  okeys::activityUserRankBindRoomId($aid);
        $uidRoomList =  oo::commonOprRedis('activity')->hGetAll($key);
        $robotList = oo::commonOprModel('robot')->getAllRobot();
        $canSendUserList = array_diff(array_keys($uidRoomList),$robotList);//驱除机器人
        //$onlineList = oo::commonOprModel('Workerman')->getAllUidList();
        //广播通知服务器节点通行购买信息
//        oo::commonOprModel('Workerman')->pushFun('activitynew', 'sendCircleRankRewardFasebasePush', [$aid, $nid, $canSendUserList]);
        $this->sendCircleRankRewardFasebasePush($aid, $nid, $canSendUserList);
        return true;
    }

    /**
     * 通知当前节点消息队列接收玩家通行证购买消息
     * @param int $aid
     * @param int $nid
     * @param array $canSendUserList
     */
    public function sendCircleRankRewardFasebasePush($aid, $nid, $canSendUserList) {
        $ts1 = oo::getMsectime();
        $onlineList = oo::commonOprModel('Workerman')->getCurAllUidList();
        $canSendUserList = array_diff($canSendUserList,$onlineList);//驱除在线玩家
        oo::commonOprModel('push')->pushNewsByNid($nid,$canSendUserList);
        $ts2 = oo::getMsectime();
        oo::logs()->commlog(["ts"=>$ts2-$ts1,"aid"=>$aid,"count"=>count($canSendUserList),"nid"=>$nid],'async/joinActFasebasePushList.log');
    }

//=====================奖励记录流水=========================
    /**
     * Notes:排行榜奖励记录入库
     * User: wsc
     * Time: 2020/8/14 14:21
     * @return bool
     */
    public function joinRankLogDB(){
        while (true){
            $datas =[];
            if(oo::commonOprRedis('Statistics')->lLen(okeys::activityRankLog(1))){
                for($i=1000;$i--;){
                    $one =  oo::commonOprRedis('Statistics')->rPop(okeys::activityRankLog(1));
                    if(!$one){
                        break;
                    }
                    $data = json_decode($one,true);
                    if(!$data||$data=='null'){
                        oo::logs()->debug3($one,'joinRankLogDB_err.txt');
                        break;
                    }
                    $data['reward'] =  json_encode($data['reward']);
                    $value = "(";
                    foreach ($data as $key=>$val){
                        $value .="'{$val}',";
                    }
                    $value = trim($value,',');
                    $value .=")";
                    $datas[$data['aid']][] = $value;
                }
                if(!empty($datas)){
                    $fieldArr = ["ranking","num","time","aid","roomId","uid","status","reward"];
                    $keys = array_values($fieldArr);
                    $fields = '(`'.implode('`, `',$keys).'`)';
                    foreach ($datas as $aid=>$rinfo){
                        $values = implode(',',$rinfo);
                        $tb = otable::rankActLog($aid,1);
                        $sql= "INSERT INTO {$tb} {$fields} VALUE {$values}";
                        oo::commonOprDb('crazygod_log')->query($sql);
                    }
                    sleep(1);
                }
            }else{
                break;
            }
        }
        return true;
    }

    /**
     * Notes:排行榜领奖记录入库
     * User: wsc
     * Time: 2020/8/14 15:08
     * @return bool
     */
    public function joinRankReceiveLogDB(){
        while (true){
            $datas =[];
            if(oo::commonOprRedis('Statistics')->lLen(okeys::activityRankLog(2))){
                for($i=1000;$i--;){
                    $one =  oo::commonOprRedis('Statistics')->rPop(okeys::activityRankLog(2));
                    if(!$one){
                        break;
                    }
                    $data = json_decode($one,true);
                    $value = "({$data['aid']},{$data['uid']},1,{$data['time']})";
                    $datas[$data['aid']][] = $value;
                }
                if(!empty($datas)){
                    $fieldArr = ["aid","uid","status","rtime"];
                    $keys = array_values($fieldArr);
                    $fields = '(`'.implode('`, `',$keys).'`)';
                    foreach ($datas as $aid=>$rinfo){
                        $values = implode(',',$rinfo);
                        $tb = otable::rankActLog($aid,2);
                        $sql= "INSERT INTO {$tb} {$fields} VALUE {$values}";
                        oo::commonOprDb('crazygod_log')->query($sql);
                    }
                    sleep(1);
                }
            }else{
                break;
            }
        }
        return true;
    }

    /**
     * Notes:创建排行榜结算记录表
     * User: wsc
     * Time: 2020/8/6 17:35
     * @param $aid
     * @return bool
     */
    public function createRankLogDB($aid){
        $sql = oo::cfg('sql')['rank_log'];
        $tb = otable::rankActLog($aid,1);
        $query = str_replace('#table#', "rank_log_{$aid}", $sql);
        $res1  = funs::createTable($tb,$query);

        $sql2 = oo::cfg('sql')['rank_receive_log'];
        $tb2 = otable::rankActLog($aid,2);
        $query2 = str_replace('#table#', "rank_receive_log_{$aid}", $sql2);
        $res2  = funs::createTable($tb2,$query2);

        return true;
    }

    /**
     * Notes:创建活动进度记录表
     * User: wsc
     * Time: 2020/8/20 15:36
     * @param $aid
     * @return bool
     */
    public function createActStageLog($aid){
        $sql = oo::cfg('sql')['act_stage_log'];
        $tb = "log.act_stage_log_{$aid}";
        $query = str_replace('#table#', "act_stage_log_{$aid}", $sql);
        $res  = funs::createTable($tb,$query);
        return $res;
    }

    /**
     * Notes:进度记录入库
     * User: wsc
     * Time: 2020/8/20 16:31
     * @return bool
     */
    public function joinStageLogDB(){
        oo::commonOprRedis('Statistics')->delete(okeys::activityStageLog());
        return ;
        while (true){
            $datas =[];
            if(oo::commonOprRedis('Statistics')->lLen(okeys::activityStageLog())){
                for($i=1000;$i--;){
                    $one =  oo::commonOprRedis('Statistics')->rPop(okeys::activityStageLog());
                    if(!$one){
                        break;
                    }
                    $data = json_decode($one,true);
                    $value = "(";
                    foreach ($data as $key=>$val){
                        $value .="'{$val}',";
                    }
                    $value = trim($value,',');
                    $value .=")";
                    $datas[$data['aid']][] = $value;
                }
                if(!empty($datas)){
                    $fieldArr = ["aid","uid","stage","rate","type","times","rid"];
                    $keys = array_values($fieldArr);
                    $fields = '(`'.implode('`, `',$keys).'`)';
                    foreach ($datas as $aid=>$rinfo){
                        $values = implode(',',$rinfo);
                        $tb = otable::actStageLog($aid);
                        $sql= "INSERT INTO {$tb} {$fields} VALUE {$values}";
                        oo::commonOprDb('log')->query($sql);
                    }
                    sleep(1);
                }
            }else{
                break;
            }
        }
        return true;
    }

    /**
     * Notes:每日进度入队
     * User: wsc
     * Time: 2020/8/24 16:55
     * @return array
     */
    public function todayStageLog(){
        $aids1 =  [];//$this->getAllOnlineActivityByType('collect');
        $aids2 =  [];//$this->getAllOnlineActivityByType('steal');
        $aids3 =  [];//$this->getAllOnlineActivityByType('attack');
        $aids4 =  $this->getAllOnlineActivityByType('rank');
        $aids5 =  [];//$this->getAllOnlineActivityByType('collect_only');
        $aids6 =  $this->getAllOnlineActivityByType('super_collect');
        $ts = date('Ymd');
        $aids = array_merge($aids1,$aids2,$aids3,$aids4,$aids5,$aids6);
        if(!empty($aids)){
            foreach ($aids as $k=>$aid){
                $userlist = oo::commonOprRedis('activity')->sMembers(okeys::bindActivityList($aid));
                if(!empty($userlist)){
                    foreach ($userlist as $uid){
                        $info = oo::commonOprRedis('activity')->hGetAll(okeys::userActivityStageRate($uid,$aid));
                        $rid  = intval(oo::commonOprRedis('activity')->get(okeys::userBindActRid($uid,$aid)));
                        $rid = $rid?$rid:1;
                        //oo::commonOprRedis('Statistics')->lPush(okeys::activityStageLog(),json_encode(["aid"=>$aid,"uid"=>$uid,"stage"=>intval($info['stage']),"rate"=>intval($info['rate']),"type"=>1,"times"=>$ts,"rid"=>$rid]));
                    }
                }
            }
        }
        return $aids;
    }

    /**
     * Notes:彩蛋游戏记录入库
     * User: wsc
     * Time: 2021/3/27 18:56
     */
    public function joinEasterEggLogDB(){
        if(oo::commonOprRedis('Statistics')->lLen(okeys::easterEggGameLog())) {
            $datas =[];
            for ($i = 1000; $i--;) {
                $one = oo::commonOprRedis('Statistics')->rPop(okeys::easterEggGameLog());
                if (!$one) {
                    break;
                }
                $one = json_decode($one,1);
                $data = [$one['aid'],$one['uid'],$one['thisLv'],$one['easterLimit'],$one['lastEasterLv'],$one['easterLog']?json_encode($one['easterLog']):'',$one['getReward']?json_encode($one['getReward']):'',$one['status'],$one['ts']];
                $value = "(";
                foreach ($data as $key=>$val){
                    $value .="'{$val}',";
                }
                $value = trim($value,',');
                $value .=")";
                $datas[] = $value;
            }
            if(!empty($datas)){
                $fieldArr = ["aid","uid","thisLv","easterLimit","lastEasterLv","easterLog","getReward","status","ts"];
                $keys = array_values($fieldArr);
                $fields = '(`'.implode('`, `',$keys).'`)';
                $values = implode(',',$datas);
                $tb = otable::gamelog_easterEgg();
                $sql= "INSERT INTO {$tb} {$fields} VALUE {$values}";
                $ret= oo::commonOprDb('log')->query($sql);
                return $ret;
            }
        }
        return true;
    }
//=======================奖励领取=============================

    /**
     * Notes:用户活动领取奖励
     * User: wsc
     * Time: 2020/7/27 11:00
     * @param $uid
     * @param $type  -活动类型
     * @param $rtype -领奖类型
     * @return array
     */
    public function receiveReward($uid,$type){
        $data = [];
        $actInfo = $this->getBindActivity($uid,$type,true);
        if(empty($actInfo)){
            return ['code'=>0,'msg'=>"活动已过期"];
        }
        $aid = $actInfo['id'];
        $rewards =[];
        if(in_array($type,["rank","super_collect"])){
            $stageInfo = $this->getUserActStageInfo($uid,$aid);
            $rewardConf = $this->getBindActivityRewardCfg($uid,$aid);//奖励配置
            $this_reward = $rewardConf['list'][$stageInfo['stage']];//当前阶段配置
            if(!empty($this_reward)){
                if($stageInfo['rate']<$this_reward['stepnum']){
                    return ['code'=>0,'msg'=>"未达领奖条件",'data'=>['maxNum'=>$this_reward['stepnum'],'num'=>$stageInfo['rate'],'stage'=>$stageInfo['stage']]];
                }
                $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
                $prize = $this_reward['prize'];//奖品
                $bet =$this->getCoinRewardByTypeAndLevel($type,$lv);
                $skey = okeys::userActivityStageRate($uid,$aid);
                oo::commonOprRedis('activity')->hIncrBy($skey,'rate',-$this_reward['stepnum']);//减进度值
                oo::commonOprRedis('activity')->hIncrBy($skey,'stage',1);//加阶段
                if($type=='rank'){
                    oo::commonOprRedis('activity')->hIncrBy($skey,'progress_'.$this_reward['progressBarId'],$this_reward['stepnum']);//进度条值
                }else{
                    $version = oo::commonOprModel('user')->getUserVersion($uid);
                    if(oo::compareVersion($version,'1.8.1')){//修正对应最后一次旋转结果体力累计消耗调整
                        if(is_array($this_reward['stagePro'])){
                            //数组
                            //获取用户分组
                            $userDynamicsData = oo::commonOprModel('member')->getUserDynamicsData($uid);
                            $curGroupId = explode(',',$userDynamicsData['groupId3']);
                            if($curGroupId && $userDynamicsData['groupId3'] !== "" && $userDynamicsData['groupId3'] !== NULL){
                                //有数数分组的用户
                                foreach($this_reward['stagePro'] as $row){
                                    if(in_array($row['groupId'],$curGroupId) && (intval($row['stagePro'])>1||intval($row['stagePro'])<0)){
                                        $gid = $this->getCollectGroupType($uid,1);
                                        oo::commonOprModel('slotresult')->activityAddResSpinsLost($uid,$lv,intval($row['stagePro']),$gid);
                                        break;
                                    }
                                }
                            }else{
                                //没有数数分组的用户但是配置有 单数值配置过度
                                foreach($this_reward['stagePro'] as $row){
                                    if($row['groupId'] == 0 && (intval($row['stagePro'])>1||intval($row['stagePro'])<0)){
                                        $gid = $this->getCollectGroupType($uid,1);
                                        oo::commonOprModel('slotresult')->activityAddResSpinsLost($uid,$lv,intval($row['stagePro']),$gid);
                                        break;
                                    }
                                }
                            }
                        }else{
                            //单数值
                            if(intval($this_reward['stagePro'])>1||intval($this_reward['stagePro'])<0){
                                $gid = $this->getCollectGroupType($uid,1);
                                oo::commonOprModel('slotresult')->activityAddResSpinsLost($uid,$lv,intval($this_reward['stagePro']),$gid);
                            }
                        }
                    }
                    $this->trySendCrazyBetAct($uid);//尝试触发crazy_bet活动
                }
                $isNew =1;
                $ts = oo::commonOprRedis('config')->ttl(okeys::timeLimitAct($aid));
                foreach ($prize as $k=>$v){//发奖
                    if((intval($ts)<=0||!$isNew)&&$v['is_ts']==1){
                        continue;
                    }
                    $isx = $v['is_ts']?'限时进度':"进度";
                    $prop = $this->getFormattingProps($uid,$aid,$v,$bet);
                    $result = oo::commonOprModel('member')->sendReward($uid,$v['type'],$prop['num'],205,"活动{$isx}:{$type}:{$aid}：{$stageInfo['stage']}:{$stageInfo['rate']}-{$this_reward['stepnum']}",$prop['value'],$prop);
                    $one=$prop;
                    if(in_array($v['type'],[13,18,19,20,21,29,30])){
                        $one['value'] = $result;
                    }
                    $rewards[] = $one;
                    //体力达标跑马灯
                    if($type=='super_collect'&&$v['type']==15){
                        $maxSpins = intval(oo::commonOprModel('notice')->getAgesCfg('getMaxSpins')['maxSpins']);
                        if($prop['num']>=$maxSpins){
                            $show_title = json_decode($actInfo['show_title'],true);
                            if(is_array($show_title)&&$show_title['zh']&&$show_title['tw']&&$show_title['en']&&$show_title['fr']&&$show_title['de']){
                                $scenelangArr = [
                                    'ZH'=>$show_title['zh'],
                                    'TW'=>$show_title['tw'],
                                    'EN'=>$show_title['en'],
                                    'FR'=>$show_title['fr'],
                                    'DE'=> $show_title['de'],
                                ];
                                oo::async()->add('oo::commonOprModel("notice")->sendNoticeMsg',[$uid,"getMaxSpins",[intval($prop['num']),$scenelangArr]]);//获得大体力卡跑马灯消息
                            }
                        }
                    }
                }
                $cur  = $this->getUserActData($uid,$type,$aid);
                $data = [
                    'code'=>1,
                    'msg'=>'领奖成功',
                    'data'=>[
                        'reward'=>$rewards,
                        'cur'=>$cur,
                        'stage'=>$stageInfo['stage']
                    ]
                ];
                if($type == "super_collect"){
                    oo::commonOprModel('ta')->setCommonEventProperty($uid,"collect",[
                        "activity_collect_layer"            => intval($cur['stage']),
                        "activity_collect_symbol_current"   => intval($cur['num']),
                        "activity_collect_symbol_need"      => intval($cur['maxNum']),
                    ]);
                    $eventType = 'activity_collect_reward';
                }else if($type == "rank"){
                    oo::commonOprModel('ta')->setCommonEventProperty($uid,"rank",[
                        "activity_rank_ranking"             => intval($cur['curRankId']),
                        "activity_rank_layer"               => intval($cur['curRankProgressId']),
                        "activity_rank_symbol"              => intval($cur['curRankNum']),
                    ]);
                    $eventType = 'activity_rank_reward_layer';
                }
                $fields = oo::commonOprModel('ta')->events[$eventType];
                unset($fields["activity_collect_reward_layer"],$fields["activity_rank_ranking_reward_card_joker"]);
                $eventData =oo::commonOprModel('ta')->getPropsSSEventData($rewards,$fields);
                if($type == "super_collect"){
                    $eventData["activity_collect_reward_layer"] = $stageInfo['stage'];
                }else if($type == "rank"){
                    $eventData["activity_rank_layer_reward_layer"] = $stageInfo['stage'];
                }
                oo::commonOprModel('ta')->setEventData($uid,$eventType,$eventData);
            }
        }
        return $data;
    }

    /**
     * Notes:建筑大师领奖
     * User: wsc
     * Time: 2020/8/28 11:41
     * @param $uid
     * @param $aid
     * @return array
     */
    public function receiveBuildMasterReward($uid,$aid){
        $key = okeys::BuildMaster($aid);
        $lvData = oo::commonOprRedis('activity')->hGet($key,$uid);
        $lvData = json_decode($lvData,true);
        if(empty($lvData)){
            return ['code'=>0,'msg'=>"不满足领奖条件"];
        }
        sort($lvData);
        $lv = $lvData[0];
        $prize = $this->getBuildReward($uid,$aid,$lv);
        $rewards =[];
        foreach ($prize as $k=>$v){
            $result = oo::commonOprModel('member')->sendReward($uid,$v['propsId'],$v['num'],203,"活动:{$aid}：{$lv}",$v['value'],$v);
            $one=$v;
            if(in_array($v['propsId'],[13,18,19,20,21,29,30])){
                $one['value'] = $result;
            }
            $rewards[] = $one;
        }
        $lvData = array_diff($lvData,[$lv]);
        if(count($lvData)>0){
            oo::commonOprRedis('common')->hSet($key,$uid,json_encode($lvData));
        }else{
            oo::commonOprRedis('common')->hDel($key,$uid);
        }
        if($lv==2){//新手活动特殊处理-清除绑定
            if($aid){
                oo::commonOprRedis('activity')->hDel($key,$uid);
                $this->clearBindActivity($uid,'architecture',$aid);
            }
        }
        $data = [
            'code'=>1,
            'msg'=>'领奖成功',
            'data'=>[
                'reward'=>$rewards,
                'cur'=>$this->getUserActData($uid,'architecture')
            ]
        ];
        return $data;
    }

    /**
     * Notes:领取排行榜结算奖励
     * User: wsc
     * Time: 2020/8/12 12:56
     * @param $uid
     * @param $aid
     * @return array
     */
    public function receiveRankReward($uid,$aid){
        $actInfo = $this->getActivity($aid);
        $res = oo::commonOprRedis('activity')->get(okeys::activityRankRewardStatus($uid, $aid));//领奖锁
        if (!$res) {
            $now = time();
            $retime = intval($actInfo['reward_time']);
            if($now<$retime-5){
//                oo::commonOprRedis('activity')->delete(okeys::activityRankRewardStatus($uid, $aid));
                return ["code" => -4, "msg" => "未到领取时间"];
            }
            if($retime+3*86400<=$now){
//                oo::commonOprRedis('activity')->delete(okeys::activityRankRewardStatus($uid, $aid));
                return ["code" => -4, "msg" => "已过领奖时间"];
            }
            if($actInfo["type"] == "rank") {
                $rData = $this->getUserCheckRankReward($uid, $aid);//获取用户待领取的排行最终奖励(加aid主动结算测试)
            }else{
                $rData = $this->getUserCheckRankReward($uid, $aid, "rank2");//获取用户待领取的排行最终奖励(加aid主动结算测试)
            }
            if ($rData) {
                oo::commonOprRedis('activity')->set(okeys::activityRankRewardStatus($uid, $aid),1);
                oo::commonOprRedis('activity')->expireAt(okeys::activityRankRewardStatus($uid, $aid), $actInfo['end_time'] + oo::redisRandomExpire(86400*3));
                foreach ($rData['reward'] as $k => $v) {
                    $ret = oo::commonOprModel('member')->sendReward($uid, $v['propsId'], $v['num'],208, "活动:rank:{$aid}", $v['value'],$v);
                    if(in_array($v['propsId'],[13,18,19,20,21,29,30])){
                        $rData['reward'][$k]['value'] =$ret;
                    }
                }
                if($actInfo["type"] == "rank"){
                    oo::commonOprRedis('activity')->delete(okeys::activityUserRankEndReward($uid));
                }else{
                    oo::commonOprRedis('activity')->delete(okeys::activityUserRankEndReward($uid,$actInfo["type"]));
                }

                $updateData = ["aid" => $aid, "uid" => $uid, "status" => 1, "rtime" => time()];
                oo::commonOprRedis('Statistics')->lPush(okeys::activityRankLog(2), json_encode($updateData));//排行榜结算流水记录
                //数数事件-排行榜结算领奖
                $fields = oo::commonOprModel('ta')->events['activity_rank_reward_ranking'];
                $eventData=oo::commonOprModel('ta')->getPropsSSEventData($rData['reward'],$fields);
                oo::commonOprModel('ta')->setEventData($uid,'activity_rank_reward_ranking',$eventData);
                $data = ["code" => 1,"data"=>$rData];
            } else {
                $data = ["code" => -3, "msg" => "未进入排行榜"];
            }
        } else {
            $data = ["code" => -2, "msg" => "奖励已领取过"];
        }
        return $data;
    }


//=======================活动详情============================
    /**
     * Notes:获取用户活动，根据类型
     * User: wsc
     * Time: 2020/7/22 19:24
     * @param $uid
     * @param $type
     * @param $abTest
     * @param $setAid
     * @return array
     */
    public function getUserActivity($uid,$type,$abTest = 0,$setAid = 0){
        $aidList = $this->getAllOnlineActivityByType($type);
        if(!empty($aidList)){
            $userInfo = oo::commonOprModel('member')->getUserBasic($uid);
            $userType = $userInfo['isFb']?1:2;//1FB 2游客
            $nowTime = time();
            $version = oo::commonOprModel('user')->getUserVersion($uid);
            $userDynamicsData = oo::commonOprModel('member')->getUserDynamicsData($uid);
            foreach ($aidList as $aid){
                if($setAid && $aid != $setAid){
                    continue;
                }
                $actInfo = $this->getActivity($aid);
                if($this->isInSpecialAct($uid,$type)&&intval($actInfo['uc_type'])==1){//如果有常驻道具活动,且个人已开启,则无视所有条件
                    return $actInfo;
                }
                if(intval($actInfo['uc_type'])!=0&&!$this->isInSpecialAct($uid,$type)){//常驻的道具活动
                    continue;
                }
                $serverAbTest = max(0,$actInfo['abTest']);

                if(!empty($actInfo['abType']) && $actInfo['abType'] == 2){ //ab数数分群
                    $taTest = empty($actInfo['taTest'])?0:$actInfo['taTest'];
                    $userinfo['userSSGroup'] = $userDynamicsData['groupId3'] ?? "";//用户数数分组
                    //数数默认分群表示所有玩家
                    $userSSGroup = explode(',', $userinfo['userSSGroup']);
                    if(!empty($taTest) && !in_array($taTest, $userSSGroup)){
                        continue;
                    }
                    $mod = $uid % 2;
                    //不在A(双)或B(单)组
                    if(($serverAbTest == 2 && !$mod) || ($serverAbTest == 1 && $mod)){
                        continue;
                    }
                }elseif(!empty($actInfo['abType']) && $serverAbTest){
                    if(in_array($serverAbTest,[1,2,3]) && $serverAbTest != $abTest){ //firebase ab分组
                        continue;
                    }else if($serverAbTest == 4 && $abTest == 2){
                        continue;
                    }else if($serverAbTest == 5 && in_array($abTest,[2,3])){
                        continue;
                    }else if($serverAbTest == 6 && in_array($abTest,[1,2])){
                        continue;
                    }
                }
                if($nowTime>=$actInfo['end_time']){//超时了
                    continue;
                }
                if($actInfo['user_type']!=0&&$actInfo['user_type']!=$userType){//当前用户不满足活动用户类型组
                    continue;
                }
                if($actInfo['client']!=0&&$actInfo['client']!=$userInfo['login_plat']){//当前用户平台不满足活动用户平台组
                    continue;
                }
                if(!empty(json_decode($actInfo['act_version'],true))){//版本不满足时
                    $act_version= json_decode($actInfo['act_version'],true);
                    $dversion =implode('.',array_slice(explode('.',$version),0,3));
                    foreach ($act_version as $v){
                        $str = implode('.',array_slice(explode('.',$v),0,3));
                        $versions[] = $str;
                    }
                    if(!in_array($dversion,$versions)){//用户版本不在选中版本内
                        if(!$actInfo['isComVersion']&&funs::compareVersionArr($dversion,$versions)){//是向下兼容版本模式,且大于选中版本内最大版本

                        }else{
                            continue;
                        }
                    }
                }
                if(!empty($actInfo['user_level_section'])&&$actInfo['user_level_section']!='0-0'&&$actInfo['user_level_section']!='-'){
                    $user_level_section = explode('-',$actInfo['user_level_section']);
                    $maxLv = intval($user_level_section[1]);
                    $minLv = intval($user_level_section[0]);
                    if(($maxLv>=$minLv&&$userInfo['levelId']>$maxLv)||$userInfo['levelId']<$minLv){//用户等级不满足用户等级组
                        continue;
                    }
                }
                if(!empty($actInfo['user_vip_section'])&&$actInfo['user_vip_section']!='0-0'&&$actInfo['user_vip_section']!='-'){
                    $user_vip_section = explode('-',$actInfo['user_vip_section']);
                    $maxvip = intval($user_vip_section[1]);
                    $minvip = intval($user_vip_section[0]);
                    if(($maxvip>=$minvip&&$userInfo['vipLv']>$maxvip)||$userInfo['vipLv']<$minvip){//不满足所在vip区间
                        continue;
                    }
                }
                if(!empty($actInfo['user_score_section'])&&$actInfo['user_score_section']!='0-0'&&$actInfo['user_score_section']!='-'){
                    $user_score_section = explode('-',$actInfo['user_score_section']);
                    $maxscore = intval($user_score_section[1]);
                    $minscore = intval($user_score_section[0]);
                    if(($maxscore>=$minscore&&$userInfo['vipPoint']>$maxscore)||$userInfo['vipPoint']<$minscore){//不满足所在vip积分区间
                        continue;
                    }
                }
                return $actInfo;
            }
        }
        return [];
    }

    /**
     * Notes:获取用户当前绑定的活动，根据类型
     * User: wsc
     * Time: 2020/7/22 19:45
     * @param $uid
     * @param $type
     * @param $info boolean true返回详情，否则返回活动id;
     * @param $setAid 设置活动ID
     * @return array|int|boolean
     */
    public function getBindActivity($uid,$type,$info=false,$setAid = 0){
        $actInfo =[];
        $key = okeys::userBindActivity($type,$uid);
        $aid = oo::commonOprRedis('activity')->get($key);
        $isbind = $aid?true:false;//是否绑定活动
        if($aid){
            if($info){
                $actInfo = $this->getActivity($aid);
            }
        }else{
            $userAbTest  = intval(oo::commonOprRedis('common')->get(okeys::UserAbTest($uid)));
            $actInfo = $this->getUserActivity($uid,$type,$userAbTest,$setAid);
            if(!empty($actInfo)&&intval($actInfo['id'])>0){
                $aid = $actInfo['id'];
                $ts = $actInfo['end_time']-time();
                $ts2 = intval(oo::commonOprRedis('activity')->ttl(okeys::userSpecialAct($uid,$type)));//特殊个人临时开启活动
                $ts = $ts2>0?$ts2:$ts;
                $isLongAct = false;
                if($ts>86400*33){//永久活动保留最多32天
                    $ts = 86400*7;
                    $isLongAct = true;
                }
                if($ts2<=0&&$actInfo['uc_type']==1){//防止长期活动异常绑定
                    return false;
                }
                oo::commonOprRedis('activity')->setex($key,$aid,$ts+5);//到期自动删除绑定
                //参加aid该活动的用户列表
                if($actInfo['uc_type']!=1||$isLongAct){//不记录道具型和长期固定型活动
                    $keys = okeys::bindActivityList($aid);
                    oo::commonOprRedis('activity')->sAdd($keys,$uid);
                }

                if(!$isbind){//绑定用户态
                    $userinfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
                    $userinfo['vipPoint']  = oo::commonOprModel('member')->getUserInfo($uid)['vipPoint'];
                    $userDynamicsData = oo::commonOprModel('member')->getUserDynamicsData($uid);
                    $userinfo['userGroup'] = $userDynamicsData['groupId2'] ?? "";
                    $userinfo['userSSGroup'] = $userDynamicsData['groupId3'] ?? "";//数数用户分组
                    $userinfo['bind_ts']=time();
                    oo::commonOprRedis('activity')->hMset(okeys::activityBindUserAttr($uid,$aid),$userinfo);
                    if(in_array($type,['super_collect','rank','rank2'])){
                        $reward = $this->getActReward($aid);
                        $spins = intval($userinfo['spins']);
                        $rid=1;
                    }
                    if($type=='super_serial_pack'||$type=='super_serial_pack2'){//保留3天补发的可能性
                        $ts += 3*86400;
                    }
                    if($type=='rank'){//保留三天领奖的可能性 有进度 rank2无进度
                        $ts += 3*86400;
                        if(!empty($reward['reward'][1]['list'])){
                            foreach ($reward['reward'] as $k=>$v){
                                $v['end'] = $v['end']?$v['end']:100000000;
                                if($spins>=$v['star']&&$spins<=$v['end']){
                                    $rid = $k;
                                    break;
                                }
                            }
                        }
                        oo::commonOprRedis('activity')->setex(okeys::userBindActRid($uid,$aid),$rid,$ts+80);//绑定活动奖励方案id
                        oo::commonOprModel('ta')->makeRankInfo($uid);
                    }
                    if($type=='super_collect'){//防止活动改变结束时间导致重置
                        $ts +=86400;
                        if(!empty($reward['extra_reward'][1]['list'])){
                            foreach ($reward['extra_reward'] as $k=>$v){
                                $v['end'] = $v['end']?$v['end']:100000000;
                                if($spins>=$v['star']&&$spins<=$v['end']){
                                    $rid = $k;
                                    break;
                                }
                            }
                        }
                        oo::commonOprRedis('activity')->setex(okeys::ridRefreshStatus($uid,$aid), 1,$ts+80);//设置 rid 刷新状态为2 已刷新
                        oo::commonOprRedis('activity')->setex(okeys::userBindActRid($uid,$aid),$rid,$ts+80);//绑定活动奖励方案id
                        oo::commonOprModel('ta')->makeCollectInfo($uid);
                    }
                    if($type=='easter_egg'){//首次,初始化部分个人数据
                        $infos=[
                            "lockLv"=>0,
                            "thisLv"=>1,
                            "easterLimit"=>0
                        ];
                        oo::commonOprRedis('activity')->hMset(okeys::easterEggInfo($uid,$aid),$infos);
                        oo::commonOprRedis('activity')->expire(okeys::easterEggInfo($uid,$aid),$ts+60);
                    }
                    if($type=='speed_spins'){//体力加速翻倍
                        $this->addSpeedSpins($uid,$aid);
                    }
                    if($type=='change_collect'){//小玩法收集
                        $reward_conf = json_decode($actInfo['reward_conf'],true);
                        $ckey = okeys::activityUserCollectChangeInfo($uid,$aid);
                        $infos=["place"=>0,"levelId"=>$userinfo['levelId'],"itemType"=>$reward_conf['item']];
                        oo::commonOprRedis('activity')->hMset($ckey,$infos);
                        oo::commonOprRedis('activity')->expire($ckey,$ts+60);
                    }
                    if($type=='crazy_bet'){
                        $cfgJson = oo::commonOprModel('readconfig')->getCon('Game',"crazyBetCfg");
                        if($cfgJson){
                            $cfg = json_decode($cfgJson,true);
                            oo::commonOprRedis('activity')->setex(okeys::lastBindActCrazyBet($uid),time(),$cfg['ts']*60);
                        }
                    }
                    if($type=='treasure'){//宝藏探索
                        $this->setUserTreasureCacheLog($aid,$uid,'TaskCurTaskId',1);
                        oo::commonOprRedis('activity')->expire(okeys::TreasureGameLog($aid,$uid),$ts+60);
                    }
                    oo::commonOprRedis('activity')->expire(okeys::activityBindUserAttr($uid,$aid),$ts+60);
                }
            }
        }
        return $info?$actInfo:$aid;
    }

    /**
     * Notes:获取绑定的活动奖励
     * User: wsc
     * Time: 2020/9/12 17:28
     * @param $uid
     * @param $aid
     * @return array|mixed
     */
    public function getBindActivityRewardCfg($uid,$aid){
        $ret=[];
        $reward = $this->getActReward($aid);
        if($reward['type']=='super_collect'){
            if(!empty($reward['extra_reward'][1])){
                $rid = intval(oo::commonOprRedis('activity')->get(okeys::userBindActRid($uid,$aid)));
                $rid = max(1,$rid);
                $ret = $reward['extra_reward'][$rid];
            }
        }
        if($reward['type']=='rank'){
            if(isset($reward['reward'][1])){
                $rid = intval(oo::commonOprRedis('activity')->get(okeys::userBindActRid($uid,$aid)));
                if($rid==0){//1.7.9 到1.8.0过度,(由于1.7.9之前未曾绑定,用绑定体力来从新计算,并缓存计算结果),---之后可删除
                    $bindSpin =intval(oo::commonOprRedis('activity')->hGet(okeys::activityBindUserAttr($uid,$aid),'spins'));
                    $ts = oo::commonOprRedis('activity')->ttl(okeys::activityBindUserAttr($uid,$aid));//绑定的用户属性过期时间
                    foreach ($reward['reward'] as $k=>$v){
                        $v['end'] = $v['end']?$v['end']:100000000;
                        if($bindSpin>=$v['star']&&$bindSpin<=$v['end']){
                            $rid = $k;
                            break;
                        }
                    }
                    $rid =max(1,$rid);
                    oo::commonOprRedis('activity')->setex(okeys::userBindActRid($uid,$aid),$rid,$ts);
                }
                $ret = $reward['reward'][$rid];
            }
        }
        return $ret;
    }

    /**
     * Notes:获取用户态
     * User: wsc
     * Time: 2020/12/9 10:13
     * @param $uid
     * @param $aid
     * @return array ["money","spins","star","shield","diamond","levelId","vipPoint"]
     */
    public function getUserBindAttr($uid,$aid){
        $userAttr = oo::commonOprRedis('activity')->hGetAll(okeys::activityBindUserAttr($uid,$aid));
        if(empty($userAttr)){
            $userAttr = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $userAttr['vipPoint'] = oo::commonOprModel('member')->getUserInfo($uid)['vipPoint'];
            $userDynamicsData = oo::commonOprModel('member')->getUserDynamicsData($uid);
            $userAttr['userGroup'] = $userDynamicsData['groupId2'] ?? "";
            $userAttr['userSSGroup'] = $userDynamicsData['groupId3'] ?? "";//数数用户分组
            $userAttr['bind_ts']=time();
            oo::commonOprRedis('activity')->hMset(okeys::activityBindUserAttr($uid,$aid),$userAttr);
            oo::commonOprRedis('activity')->expire(okeys::activityBindUserAttr($uid,$aid),86400*3+60);
        }
        return $userAttr;
    }

    /**
     * Notes:清理的绑定活动
     * User: wsc
     * Time: 2020/8/25 19:58
     * @param $uid
     * @param $type
     */
    public function clearBindActivity($uid,$type,$aid){
        $key = okeys::userBindActivity($type,$uid);
        $aid = $aid?$aid:oo::commonOprRedis('activity')->get($key);
        if($aid){
            oo::commonOprRedis('activity')->delete($key);
            $key2 = okeys::bindActivityList($aid);
            oo::commonOprRedis('activity')->sRemove($key2,$uid);//绑定活动组中移除此用户
            oo::commonOprRedis('activity')->delete(okeys::userBindActAbTest($type,$uid));//删除abtest
            oo::commonOprRedis('activity')->delete(okeys::activityBindUserAttr($uid,$aid));//删除用户态
            if($type=='super_collect'){
                oo::commonOprRedis('activity')->delete(okeys::userActivityStageRate($uid,$aid));//删除个人进度信息
                oo::commonOprRedis('activity')->delete(okeys::userBindActRid($uid,$aid));//删除个人绑定的阶段奖励方案
                oo::commonOprRedis('activity')->delete(okeys::userSpecialAct($uid,$type));//删除道具活动时长
                //通知活动下线
                $data =[
                    "actId"=>$this->act_type[$type]["rcid"],
                    "status"=>0,
                    "startTime"=>0,
                    "actType"=>$type,
                    "aid"=>$aid,
                ];
                $nsqData =["type" => "user","uid"=>$uid,"flag" =>$uid, "cmd" => ocmd::$send['ActivityChangeStatus_New'], "data" => $data];
                funs::SendNsqMsg(ocmd::TopicPHPPush,[],$nsqData);
                oo::commonOprModel('Workerman')->push($uid,ocmd::$send['ActivityChangeStatus_New'],$data);
            }
        }

    }

    /**
     * Notes:清理长期特殊道具活动内的绑定的个人uid
     * User: wsc
     * Time: 2020/12/3 17:12
     * @return int
     */
    public function clearSpecialActCache(){
        $num = 0;
        $time = time()+86400*33;
        $w = "is_online = 1 and uc_type=1 and end_time>={$time}";
        $outOnlineList =$this->getActivityList($w);
        foreach ($outOnlineList as $info){
            $delList =[];
            $aid = $info['id'];
            $key = okeys::bindActivityList($aid);
            $uidList = oo::commonOprRedis('activity')->hGetAll($key);
            foreach ($uidList as $uid){
                if(oo::commonOprRedis('activity')->exists(okeys::userSpecialAct($uid,$info['type']))){
                    $needList[$uid] =1;
                }
            }
            oo::commonOprRedis('activity')->delete($key);
            if($needList){
                oo::commonOprRedis('activity')->hMset($key,$needList);
            }
            $arr[$aid] = count($delList);
        }
        return $num;
    }

    /**
     * Notes:第一次转动老虎机时根据用户当前体力重置rid
     * User: xwy
     * Time: 2020/7/22 12:23
     * @param $uid  -用户id
     * @param $type -活动类型
     * @param $info -是否显示活动详情
     * @return array|bool
     */
    public function refreshRid($uid, $actInfo, $spins){
        if(time() < strtotime('2021-09-29') && !IS_DEBUF)return;
        $aid = $actInfo['id'];

        //rid 刷新状态
        $refreshStatus = oo::commonOprRedis('activity')->get(okeys::ridRefreshStatus($uid,$aid));
        if($refreshStatus != 1)return;//第一次转动刷新之后 不再刷新rid
        $ts = $actInfo['end_time']-time();
        $ts +=86400;
        #计算rid
        $rid =1;
        $reward = $this->getActReward($aid);
        if(!empty($reward['extra_reward'][1]['list'])){
            foreach ($reward['extra_reward'] as $k=>$v){
                $v['end'] = $v['end']?$v['end']:100000000;
                if($spins>=$v['star']&&$spins<=$v['end']){
                    $rid = $k;
                    break;
                }
            }
        }
        #重置rid
        oo::commonOprRedis('activity')->setex(okeys::userBindActRid($uid,$aid),$rid,$ts+80);//刷新 rid
        oo::commonOprRedis('activity')->setex(okeys::ridRefreshStatus($uid,$aid), 2,$ts+80);//设置 rid 刷新状态为2 已刷新
        oo::commonOprRedis('activity')->hset(okeys::activityBindUserAttr($uid,$aid),'spins', $spins);//刷新 绑定活动时的体力值
    }

    //>>>>>>>>>>>>>>>>>>>>>>特例活动(道具活动)>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:个体开启道具活动
     * User: wsc
     * Time: 2020/12/3 15:41
     * @param $uid
     * @param $type
     * @param $time int 开启时长 单位秒/s
     * @param $setAid int 设置活动ID
     * @return bool
     */
    public function openSpecialAct($uid,$type,$time,$setAid = 0){
        if($this->getBindActivity($uid,$type)&&$setAid==0){//已经有绑定同类型活动则不再开启
            return false;
        }
        if(!in_array($type,array_keys($this->specialActTypeList))){//是否属于道具活动范围
            return false;
        }
        if($setAid>0){//新道具型推送，不初初始化数据
            $key = okeys::userSpecialActNew($uid,$setAid,$type);
            oo::commonOprRedis('activity')->setex($key,1,$time);
            $aid = $setAid;
        }else{
            $key = okeys::userSpecialAct($uid,$type);
            oo::commonOprRedis('activity')->setex($key,1,$time);
            $aid = $this->getBindActivity($uid,$type,false,$setAid);//给个人绑定活动
            if(!$aid){//没有可用的活动作为模板时
                oo::commonOprRedis('activity')->delete($key);
                return false;
            }
        }
        $data =[
            "actId"=>$this->act_type[$type]["rcid"],
            "status"=>1,
            "startTime"=>0,
            "actType"=>$type,
            "aid"=>$aid,
        ];
        if($type=='speed_spins'){
            $this->addSpeedSpins($uid,$aid,$time);
//            $this->doubleSpins($uid,0,0,$time);
        }
        $nsqData =["type" => "user","uid"=>$uid,"flag" =>$uid, "cmd" => ocmd::$send['ActivityChangeStatus_New'], "data" => $data];
        funs::SendNsqMsg(ocmd::TopicPHPPush,[],$nsqData);
//        oo::commonOprModel('Workerman')->push($uid,ocmd::$send['ActivityChangeStatus_New'],$data);
        return true;
    }

    /**
     * Notes:是否开启特例活动
     * User: wsc
     * Time: 2020/8/11 15:50
     * @param $uid
     * @param $type -活动类型
     * @return boolean
     */
    public function isInSpecialAct($uid,$type){
        $key = okeys::userSpecialAct($uid,$type);
        $res = oo::commonOprRedis('activity')->exists($key);
        return $res;
    }

    /**
     * Notes:清理个人特殊道具活动
     * User: wsc
     * Time: 2020/12/3 18:10
     * @param $uid
     * @param $aid
     */
    public function clearUserSpeciaAct($uid,$aid=0,$propsId=0, $notice = 1){
        if($aid){
            $key = okeys::bindActivityList($aid);
            $info = $this->getActivity($aid);
        }else if($propsId){
            $actProp = oo::commonOprModel('activitynew')->specialActTypeList;
            $propArr = funs::array_column_ext($actProp,'propsId',-1);
            $propArr = array_flip($propArr);
            $aid = $this->getBindActivity($uid,$propArr[$propsId]);
            if(empty($aid)){
                return false;
            }
            $key = okeys::bindActivityList($aid);
            $info = $this->getActivity($aid);
        }

        $type = $info['type'];
        oo::commonOprRedis('activity')->hDel($key,$uid);
        oo::commonOprRedis('activity')->delete(okeys::userSpecialAct($uid,$type));
        oo::commonOprRedis('activity')->delete(okeys::userBindActivity($type,$uid));
        //推送下线通知
        $data =[
            "actId"=>$this->act_type[$type]["rcid"],
            "status"=>0,
            "startTime"=>0,
            "actType"=>$type,
            "aid"=>$aid,
        ];
        if($notice){
            $nsqData =["type" => "user","uid"=>$uid,"flag" =>$uid, "cmd" => ocmd::$send['ActivityChangeStatus_New'], "data" => $data];
            funs::SendNsqMsg(ocmd::TopicPHPPush,[],$nsqData);
            oo::commonOprModel('Workerman')->push($uid,ocmd::$send['ActivityChangeStatus_New'],$data);
        }
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//======================设置用户活动状态进度===================
    /**
     * Notes:行为触发进度变化
     * User: wsc
     * Time: 2020/8/4 10:41
     * @param $uid
     * @param $do
     * @param $t
     * @param $bet
     * @return mixed
     */
    public function setRateByDo($uid,$do,$t,$bet){
        $retData = false;
        $isHaveCollect = false;
        $rankInfo =$info= $this->getBindActivity($uid,'rank',true);
        if($rankInfo){
            $progress = $this->getUserActStageInfo($uid,$rankInfo['id']);
        }
        if($do=='steal'){
            if($info){
                $reward_conf = json_decode($info['reward_conf'],true);
                $baseCount=$num = $t==1?$reward_conf['steal_break']:$reward_conf['steal_success'];//$t=1完美偷 $t=2不完美偷
                $num = $num * $bet;
                $retData['rank'] = $this->setUserActRate($uid,$info['id'],$num,'rank');
                if($info['reward_time']>time()){//到达领奖时间不再加进度
                    $retData['rankSum'] = self::setUserRankNum($uid,$info['id'],$num);
                    oo::commonOprModel('currency')->actlog($info['id'],$uid,'rank_rate','+',$num,$retData['rankSum'],1,"基础值:{$baseCount},倍率:{$bet},当前阶进度值:{$retData['rank']}");//活动流水
                    //数数事件-公共属性
                    oo::commonOprModel('ta')->setCommonEventProperty($uid,'rank',['activity_rank_symbol'=>$retData['rankSum'],'activity_rank_layer'=>$progress['stage']-1]);
                    $retData['rankCollectNum'] = $num;
                }
            }
        }
        if($do=='attack'){
            if($info){
                $reward_conf = json_decode($info['reward_conf'],true);
                $baseCount=$num = $t==2?$reward_conf['attack_break']:$reward_conf['attack_success'];//$t=2打盾 $t=1打破建筑
                $num = $num * $bet;
                $retData['rank'] = $this->setUserActRate($uid,$info['id'],$num,'rank');
                if($info['reward_time']>time()){//到达领奖时间不再加进度
                    $retData['rankSum'] = self::setUserRankNum($uid,$info['id'],$num);
                    oo::commonOprModel('currency')->actlog($info['id'],$uid,'rank_rate','+',$num,$retData['rankSum'],2,"基础值:{$baseCount},倍率:{$bet},当前阶进度值:{$retData['rank']}");//活动流水
                    //数数事件-公共属性
                    oo::commonOprModel('ta')->setCommonEventProperty($uid,'rank',['activity_rank_symbol'=>$retData['rankSum'],'activity_rank_layer'=>$progress['stage']-1]);
                    $retData['rankCollectNum'] = $num;
                }
            }
        }

        //排行榜 无进度 开始
        $rankInfo =$info= $this->getBindActivity($uid,'rank2',true);
        if($rankInfo){
            $progress = 1;
        }
        if($do=='steal'){
            if($info){
                $reward_conf = json_decode($info['reward_conf'],true);
                $baseCount=$num = $t==1?$reward_conf['steal_break']:$reward_conf['steal_success'];//$t=1完美偷 $t=2不完美偷
                $num = $num * $bet;
                $retData['rank'] = $this->setUserActRate($uid,$info['id'],$num,'rank');
                if($info['reward_time']>time()){//到达领奖时间不再加进度
                    $retData['rankSum'] = self::setUserRankNum($uid,$info['id'],$num);
                    oo::commonOprModel('currency')->actlog($info['id'],$uid,'rank2_rate','+',$num,$retData['rankSum'],1,"基础值:{$baseCount},倍率:{$bet},当前阶进度值:{$retData['rank']}");//活动流水
                    //数数事件-公共属性
                    //oo::commonOprModel('ta')->setCommonEventProperty($uid,'rank',['activity_rank_symbol'=>$retData['rankSum'],'activity_rank_layer'=>$progress['stage']-1]);
                    $retData['rankCollectNum'] = $num;
                }
            }
        }
        if($do=='attack'){
            if($info){
                $reward_conf = json_decode($info['reward_conf'],true);
                $baseCount=$num = $t==2?$reward_conf['attack_break']:$reward_conf['attack_success'];//$t=2打盾 $t=1打破建筑
                $num = $num * $bet;
                $retData['rank'] = $this->setUserActRate($uid,$info['id'],$num,'rank');
                if($info['reward_time']>time()){//到达领奖时间不再加进度
                    $retData['rankSum'] = self::setUserRankNum($uid,$info['id'],$num);
                    oo::commonOprModel('currency')->actlog($info['id'],$uid,'rank2_rate','+',$num,$retData['rankSum'],2,"基础值:{$baseCount},倍率:{$bet},当前阶进度值:{$retData['rank']}");//活动流水
                    //数数事件-公共属性
                    //oo::commonOprModel('ta')->setCommonEventProperty($uid,'rank',['activity_rank_symbol'=>$retData['rankSum'],'activity_rank_layer'=>$progress['stage']-1]);
                    $retData['rankCollectNum'] = $num;
                }
            }
        }
        //排行榜 无进度 结束
        $type='super_collect';
        $actInfo = $this->getBindActivity($uid,$type,true);
        if($actInfo){
            $reward_conf = json_decode($actInfo['reward_conf'],true);
            $groupId = intval($reward_conf['groupId']);
            $num = 0;
            switch ($do){
                case 'steal':
                    if(in_array($groupId,[1,3,5,7,8])) $num = $t==1?$reward_conf['steal_break']:$reward_conf['steal_success'];
                    break;
                case 'attack':
                    if(in_array($groupId,[1,4,6,7,9])) $num = $t==2?$reward_conf['attack_break']:$reward_conf['attack_success'];
                    break;
                case 'super_collect':
                    $twoHit = $reward_conf['two_hit']?$reward_conf['two_hit']:$reward_conf['tow_hit'];//过度错误字母
                    $numh = $t==1?$reward_conf['one_hit']:($t==2?$twoHit:$reward_conf['three_hit']);
                    if(in_array($groupId,[1,2,3,4,7])){
                        $num = $numh;
                        $isHaveCollect=true;
                    }
                    break;
                case 'steal_item':
                    if($groupId==8) $num = $t==2?$reward_conf['two_steal']:$reward_conf['one_steal'];
                    break;
                case 'attack_item':
                    if($groupId==9) $num = $t==2?$reward_conf['two_attack']:$reward_conf['one_attack'];
                    break;
                default:
                    break;
            }
            $baseCount = $num;
            if(intval($num)>0){
                $num = intval($num) * $bet;
                $be='';
                //新收集加倍活动
                $haveBet = $this->isInSpecialAct($uid,'collect_bet');
                if($haveBet){
                    $betInfo = $this->getBindActivity($uid,'collect_bet',true);
                    $betCfg = json_decode($betInfo['reward_conf'],true);
                    $bet2 = $betCfg['bet']?intval($betCfg['bet']):2;
                    $num = $num*$bet2;
                    $be="-限时bet值:{$bet2}";
                }
                $retData[$do] = $this->setUserActRate($uid,$actInfo['id'],$num,$type);
                $retData['groupId'] = $groupId;
                oo::commonOprModel('currency')->actlog($actInfo['id'],$uid,'collect_rate','+',$num,$retData[$do],2,"收集类型{$groupId},基础值:{$baseCount},倍率:{$bet}{$be},当前阶进度值:{$retData[$do]}");//活动流水
                //数数事件-公共属性
                $stageInfo = $this->getUserActStageInfo($uid,$actInfo['id']);
                oo::commonOprModel('ta')->setCommonEventProperty($uid,'collect',['activity_collect_symbol_current'=>$retData[$do],'activity_collect_layer'=>$stageInfo['stage']]);
            }
            $retData['collectNum'] = $num;
        }
        if(in_array($do,['super_collect'])&&!$isHaveCollect&&$t=3){
            if($rankInfo){
                $reward_conf = json_decode($rankInfo['reward_conf'],true);
                $num = $reward_conf['three_hit'];
                $num = $num * $bet;
                if($num>0&&$rankInfo['reward_time']>time()){//到达领奖时间不再加进度
                    $retData['rank'] = $this->setUserActRate($uid,$rankInfo['id'],$num,'rank');//进度条加值
                    $retData['rankSum'] = self::setUserRankNum($uid,$rankInfo['id'],$num);//排行榜排名加值
                    oo::commonOprModel('currency')->actlog($rankInfo['id'],$uid,'rank_rate','+',$num,$retData['rankSum'],3,"基础值:{$reward_conf['three_hit']},倍率:{$bet},当前阶进度值:{$retData['rank']}");//活动流水
                    //数数事件-公共属性
                    oo::commonOprModel('ta')->setCommonEventProperty($uid,'rank',['activity_rank_symbol'=>$retData['rankSum'],'activity_rank_layer'=>$progress['stage']-1]);
                    $retData['rankCollectNum'] = $num;
                }
            }
        }
        return $retData;
    }

    /**
     * Notes:设置用户活动阶段进度信息
     * User: wsc
     * Time: 2020/7/31 18:31
     * @param $uid
     * @param $type
     * @param $num
     * @return int
     */
    public function setUserActRate($uid,$aid,$num,$type=''){
        $key =okeys::userActivityStageRate($uid,$aid);
        $resNum=oo::commonOprRedis('activity')->hIncrBy($key,'rate',$num);
        if($type == 'super_collect') oo::commonOprRedis('activity')->hIncrBy(okeys::getCollectActAdd($aid),$uid,$num);
        return intval($resNum);
    }

    /**
     * Notes:获取用户活动进度信息
     * User: wsc
     * Time: 2020/7/27 10:52
     * @param $uid
     * @param $aid
     * @return array
     */
    public function getUserActStageInfo($uid,$aid){
        $key =okeys::userActivityStageRate($uid,$aid);
        $info = oo::commonOprRedis('activity')->hGetAll($key);
        if(!isset($info['stage'])){//初始化进度
            $info['stage']=1;
            oo::commonOprRedis('activity')->hSet($key,'stage',1);
            $actInfo = $this->getActivity($aid);
            oo::commonOprRedis('activity')->expireAt($key,$actInfo['end_time']+oo::redisRandomExpire(86400));//个人进度保存多加一天,防止临时修改结算时间进度被清理
        }
        !isset($info['rate'])?$info['rate']=0:true;
        return $info;
    }

    /**
     * Notes:报名及报名状态
     * User: wsc
     * Time: 2020/9/12 17:40
     * @param $uid
     * @param $aid
     * @param int $get
     * @return int|mixed
     */
    public function applyActivity($uid,$aid,$get=0){
        $res = 0;
        $key = okeys::activityApply($aid);
        if($get){
            $res =  oo::commonOprRedis('activity')->hGet($key,$uid);
            $res = $res?1:0;
        }else{
            oo::commonOprRedis('activity')->hSet($key,$uid,1);
            $res =1;
        }
        return $res;
    }

    /**
     * Notes:获取收集物类型
     * User: wsc
     * Time: 2021/2/25 15:37
     * @param $uid
     * @return int
     */
    public function getCollectGroupType($uid,$t=0){
        $type='super_collect';
        $actInfo = $this->getBindActivity($uid,$type,true);
        if($actInfo) {
            $reward_conf = json_decode($actInfo['reward_conf'], true);
            $groupId = intval($reward_conf['groupId']);
            if($t==1){
                return $groupId;
            }
            if($groupId==1){//普通收集 (收集物3)
                return 1;
            }else if(in_array($groupId,[2,3,4,7])){//特殊收集,特殊收集偷,特殊收集打 (收集物1,2,3)
                return 2;
            }else if($groupId==8){//偷收集
                return 4;
            }else if($groupId==9){//打收集
                return 5;
            }else{//偷,打(无收集物)
                return 0;
            }
        }
        return 0;
    }
//============================================================
//===================客户端获取活动============================
    //>>>>>>>>>>>>>>>>>>>>>>crazy_bet>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:自动触发crazy_bet
     * User: wsc
     * Time: 2021/4/7 19:44
     * @param $uid
     * @return bool
     */
    public function trySendCrazyBetAct($uid){
        if(oo::commonOprRedis('activity')->get(okeys::lastBindActCrazyBet($uid))){
            return false;
        }
        if($this->activityLock($uid,'crazy_bet')){
            return false;
        }
        $cfgJson = oo::commonOprModel('readconfig')->getCon('Game',"crazyBetCfg");
        if($cfgJson){
            $cfg = json_decode($cfgJson,true);
            $uInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            if($uInfo['spins']<$cfg['spins']){
                return false;
            }else{
                oo::commonOprModel('member')->sendReward($uid,31,$cfg['rewardTime'],122,"超过{$cfg['ts']}分钟未crazybet,体力{$uInfo['spins']}");
            }
        }
        return true;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>体力加速>>>>>>>>>>>>>>>>>>>>>>>>
    public function addSpeedSpins($uid,$aid='',$time=0){
        $cacheKey = okeys::SpeedUpSpins($uid);
        $aid = $aid?$aid:$this->getBindActivity($uid,'speed_spins');
        if(!$aid){
            return false;
        }
        $actInfo = $this->getActivity($aid);
        if(!$time){
            if($actInfo['uc_type']){//道具活动不加时长
                return false;
            }
            $time = $actInfo['end_time'] -$actInfo['start_time'];
        }
        $reward_conf = json_decode($actInfo['reward_conf'],1);
        $configBet = $reward_conf['bet']?$reward_conf['bet']:2;
        oo::commonOprRedis('common')->setex($cacheKey,$configBet,$time);

        $lastTime = $time+time();
        $keys = okeys::userRestoreTime($uid);
        $spinsKey = oo::commonOprRedis('common')->get($keys);
        if($spinsKey){
            $spinsCache = explode("*",$spinsKey);
            if(count($spinsCache) > 2){
                $spinsCache[2] = $lastTime;
                $spinsCache[3] = $configBet;
                oo::commonOprRedis('common')->set($keys,implode("*",$spinsCache));
            }else{
                oo::commonOprRedis('common')->set($keys,$spinsKey."*{$lastTime}*{$configBet}");
            }
        }

        $refreshSpinsTime = max(oo::commonOprModel('user')->refreshSpins($uid,0),0);
        $spinNextTime = $refreshSpinsTime +time();
        oo::commonOprModel('Workerman')->push($uid,ocmd::$send['Activity_doubleSpins'],[
            'bet'     =>$configBet,
            'lastTime'=>$time,
            'spinNextTime'=>$spinNextTime
        ]);
        return $configBet;
    }
    /**
     * Notes:巡逻体力加速活动
     * User: wsc
     * Time: 2020/8/3 17:17
     * @param $uid
     * @param int $maxBet
     * @param int $autoSpins
     * @return bool|int
     */
    public function doubleSpins($uid,$maxBet = 0,$autoSpins = 0,$time=0){
        $cacheKey = okeys::SpeedUpSpins($uid);
        $cache    = oo::commonOprRedis('common')->get($cacheKey);
        if($cache){
            return intval($cache);
        }
        $aid = $this->getBindActivity($uid,'speed_spins');
        if(!$aid){
            return false;
        }
        $config = $this->getActReward($aid)['reward'];
        $action      = false;
        $configBet   = 0;
        $configEffecteTime = 0;
        foreach ($config as $row){
            $id = $row['id'];
            if($id == 1 && $maxBet){
                $count = intval(oo::commonOprRedis('common')->get(okeys::SpeedUpSpins($uid,$id)));
                if($count < $row['max']&&$row['open']==1){
                    $action = true;
                }
            }else if($id == 2 && $autoSpins){
                $count = intval(oo::commonOprRedis('common')->get(okeys::SpeedUpSpins($uid,$id)));
                if($count < $row['max']&&$row['open']==1){
                    $action = true;
                }
            }else if($id == 3){
                $count = intval(oo::commonOprRedis('common')->get(okeys::SpeedUpSpins($uid,$id)));
                $advertisementCount = intval(oo::commonOprRedis('common')->hGet(okeys::advertisementRemainCount(),$uid));
                if($advertisementCount >=3 &&  $count < $row['max']&&$row['open']==1){
                    $action = true;
                }
            }else if($id == 4){
                $cache = oo::commonOprRedis('common')->get(okeys::TodayBuyGoods($uid,1));
                $count = intval(oo::commonOprRedis('common')->get(okeys::SpeedUpSpins($uid,$id)));
                if($count < $row['max'] && $cache&&$row['open']==1){
                    $action = true;
                }
            }else if($id == 5){
                $res = oo::limit($uid,$id,1);
                $count = intval(oo::commonOprRedis('common')->get(okeys::SpeedUpSpins($uid,$id)));
                if($count < $row['max']&&$res&&$row['open']==1){
                    $action = true;
                }
            }
            if($action){
                $configBet   = $row['bet'];
                $configEffecteTime = $row['effecteTime'];
                oo::commonOprRedis('common')->setex(okeys::SpeedUpSpins($uid,$id),$count+1,oo::todayDeadline());
                break;
            }
        }
        $configEffecteTime = $time?$time:$configEffecteTime;
        if($action){
            oo::commonOprModel('user')->refreshSpins($uid,0);
            oo::commonOprRedis('common')->setex($cacheKey,$configBet,$configEffecteTime);
            $lastTime = time() + $configEffecteTime;
            $keys = okeys::userRestoreTime($uid);
            $spinsKey = oo::commonOprRedis('common')->get($keys);
            if($spinsKey){
                $spinsCache = explode("*",$spinsKey);
                if(count($spinsCache) > 2){
                    $spinsCache[2] = time() + $configEffecteTime;
                    $spinsCache[3] = $configBet;
                    oo::commonOprRedis('common')->set($keys,implode("*",$spinsCache));
                }else{
                    oo::commonOprRedis('common')->set($keys,$spinsKey."*{$lastTime}*{$configBet}");
                }
            }
            $refreshSpinsTime = max(oo::commonOprModel('user')->refreshSpins($uid,0),0);
            $dts = $configEffecteTime;
            if($refreshSpinsTime<$dts){
                $dts = $refreshSpinsTime/2;
            }
            $spinNextTime = $refreshSpinsTime +time()-$dts;
            oo::commonOprModel('Workerman')->push($uid,ocmd::$send['Activity_doubleSpins'],[
                'bet'     =>$configBet,
                'lastTime'=>$configEffecteTime,
                'spinNextTime'=>$spinNextTime
            ]);
            return $configBet;
        }
        return false;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>连环礼包>>>>>>>>>>>>>>>>>>>>>>>>
    public function getChainGiftBindConf($aid,$uid){
        $reward_conf = [];
        $key = okeys::activityChainGiftBindCfg($aid,$uid);
        $json = oo::commonOprRedis('activity')->get($key);
        if($json){
            $reward_conf = json_decode($json,true);
        }else{
            $rewardList =$this->getActReward($aid)['extra_reward'];
            if(!empty($rewardList)){
                $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
                foreach ($rewardList as $k=>$v){
                    if($v['score_end']>=$userInfo['vipPoint']&&$userInfo['vipPoint']>=$v['score_star']){
                        $reward_conf = $v['giftList'];
                        break;
                    }
                }
            }else{
                $reward_conf = $this->getActReward($aid)['reward'];
            }
            if($reward_conf){
                $actInfo = $this->getActivity($aid);
                oo::commonOprRedis('activity')->set($key,json_encode($reward_conf));
                if($actInfo['end_time']<time()){
                    $ts = time()+3600;
                }else{
                    $ts = $actInfo['end_time']+oo::redisRandomExpire(3600);
                }
                oo::commonOprRedis('activity')->expireAt($key,$ts);
            }
        }
        return $reward_conf;
    }
    /**
     * Notes:获取连环礼包配置
     * User: wsc
     * Time: 2020/8/24 18:26
     * @param $uid
     * @param $aid
     * @param $gid
     * @return array
     */
    public function getChainGiftConf($uid,$aid,$gid){
        $row = [];
        $reward_conf = $this->getChainGiftBindConf($aid,$uid);
        $row = $reward_conf[$gid];
        if(strpos($row['gsku'],'com.sa') !== false || strpos($row['gsku'],'newsky.cc') !== false||strpos($row['gsku'],'com.gworld') !== false||strpos($row['gsku'],'gworld.cc') !== false){
            $gsku = $row['gsku'];
            $price   = '$'.$row['gprice'];
            $priceNum= (string)$row['gprice'];
        }else{
            $gsku = "";
            $price= $row['gsku1'];
            $price= intval(oo::commonOprModel('goods')->getGoodCoins($uid,$price['coins'])) * intval($price['bet']);//价格
            $priceNum= (string)$price;
        }
        $coin   = oo::commonOprModel('goods')->getGoodCoins($uid,$row['gbaseReward']['coins']['coins']) * intval($row['gbaseReward']['coins']['bet']);
        $props = isset($row['gbaseReward']['props'])&&is_array($row['gbaseReward']['props'])?$row['gbaseReward']['props']:[];
        $spans = intval($row['gbaseReward']['spins']);
        if(!empty($props)){
            foreach ($props as $v){
                if($v['propsId']==15&&intval($v['num'])>0){
                    $spans = intval($v['num']);
                    break;
                }
            }
        }
        $out = [
            'id'         =>1,
            'gid'        =>$row['gid'],
            'coin'       =>intval($coin),
            'spin'       =>$spans,
            'props'      =>$props,
            'price'      =>$price,
            'priceNum'   =>$priceNum,
            'sku'        =>$gsku,
            'ggameid'    =>1,//商品对应游戏
            'gdiscount'  =>1,//商品折扣
            'addRatio'   =>0,//加成比
            'giftType'   =>1,
            'gMax'       =>$row['gMax'],
            'gdesc'      =>$row['gdesc'],
            'gbaseReward'=>$row['gbaseReward']
        ];
        return $out;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>超级连环礼包>>>>>>>>>>>>>>>>>>
    public function getCGReward($uid,$aid){
        $bindUserAttr = $this->getUserBindAttr($uid,$aid);
        $rewardConf = $this->getActReward($aid);
        $type = $rewardConf['type'];
        $scoreCGType= $rewardConf['reward']['scoreCGType'] ?? 1;
        $bindVP = intval($bindUserAttr['vipPoint']);
        $bindLv = intval($bindUserAttr['levelId']);
        $reward = [];//初始化reward，不然下面条件都不满足的时候，会给客户端返回null，不是[]，导致客户端报错
        if(in_array($scoreCGType,[2,3])){
            $reward = $rewardConf['extra_reward'][1]['list'];
            if($scoreCGType==2){
                if(!empty($bindUserAttr['userGroup'])){
                    $groupId = funs::ArrayFilter(explode(',',$bindUserAttr['userGroup']));
                }
                $confArr = oo::commonOprModel('config')->getUserGroupConfigByCid(2);
                array_multisort(array_column($confArr,'sort'),SORT_DESC,$confArr);
            }else{
                if(!empty($bindUserAttr['userSSGroup'])){
                    $groupId = funs::ArrayFilter(explode(',',$bindUserAttr['userSSGroup']));
                }
                $confArr= oo::commonOprModel('config')->getUserGroupConfigByCid(5);
                $default =[
                    "id"=>0,
                    "name"=>"默认分组",
                ];
                array_push($confArr,$default);
            }
            $groupId = isset($groupId)&&$groupId?$groupId:[0];
            foreach ($confArr as $row){
                if(in_array($row['id'],$groupId)){
                    $actionFlag = false;
                    foreach ($rewardConf['extra_reward'] as $k=>$v){
                        $temp = funs::ArrayFilter(explode(',',$v['gid']));
                        if(in_array($row['id'],$temp)){
                            $actionFlag = true;
                            $reward = $v['list'];
                            break;
                        }
                    }
                    if($actionFlag){
                        break;
                    }
                }
            }
        }else{
            foreach ($rewardConf['extra_reward'] as $k=>$v){
                $v['end'] = $v['end']?$v['end']:100000000;
                if($bindVP>=$v['star']&&$bindVP<=$v['end']){
                    $reward = $v['list'];
                    break;
                }
            }
        }
        $bet =$this->getCoinRewardByTypeAndLevel('super_serial_pack',$bindLv);
        $startGid = $type=='super_serial_pack'?720:760;
        foreach ($reward as $k=>$v){
            $reward[$k]['gid'] = intval($reward[$k]['stage'])+$startGid;
            $reward[$k]['priceDollar'] = "$";
            $reward[$k]['priceCurrencyCode'] = "USD";
            $sgsid = oo::getDefinedSid($uid);
            $reward[$k]['sku']= ($sgsid == 1) ? oo::commonOprModel('goods')->googleSkuToAndroid($v['sku']) : oo::commonOprModel('goods')->googleSkuToIosSku($v['sku']);
            if($v['mtype']==1){
                $reward[$k]['price']= intval(oo::commonOprModel('goods')->getGoodCoins($uid,$v['coin'])) * intval($v['bet']);//价格
                $reward[$k]['priceNum'] = (string)$reward[$k]['price'];
            }else{
                $price = $reward[$k]['price'];
                $reward[$k]['price']= '$'.$price;//价格
                $reward[$k]['priceNum'] = (string)$price;
            }
            foreach ($v['prize'] as $val){
                $prop = $this->getFormattingProps($uid,$aid,$val,$bet);
                $prop['reward'] = $prop['value'];
                $reward[$k]['props'][] = $prop;
            }
            unset($reward[$k]['prize'],$reward[$k]['coin'],$reward[$k]['bet']);
        }
        return $reward;
    }
    public function getCGRewardByGid($uid,$aid,$gid){
        $rewards = $this->getCGReward($uid,$aid);
        $rewards =array_column($rewards,null,'gid');
        $reward = $rewards[$gid];
        return $reward;
    }
    public function getCGGoodList($uid,$type){
        $aid = $this->getBindActivity($uid,$type);
        if($aid){
            $key = $type=='super_serial_pack'?okeys::bindSuperSerialPack($uid):okeys::bindSuperSerialPack2($uid);
            oo::commonOprRedis('activity')->setex($key,$aid,86400*3);
            $list = $this->getCGReward($uid,$aid);
        }else{
            $list = [];
        }
        return $list;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>建筑大师>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:根据活动及等级获取建筑大师过关奖励
     * User: wsc
     * Time: 2020/8/25 15:42
     * @param $aid
     * @param $lv
     * @return array
     */
    public function getBuildReward($uid,$aid,$lv){
        $rewards = [];
        $rewardConf = $this->getActReward($aid)['reward'];//奖励配置
        $bet =$this->getCoinRewardByTypeAndLevel('architecture',$lv);
        foreach ($rewardConf as $k=>$v){
            if($v['lv']>=$lv){
                $prize = $v['prize'];
                break;
            }
        }
        if(!empty($prize)&&is_array($prize)){
            foreach ($prize as $k=>$v) {
                $reward = $this->getFormattingProps($uid,$aid,$v,$bet);
                array_push($rewards,$reward);
            }
        }
        return $rewards;
    }
    public function getUserBuildConf($uid,$aid){
        $key = okeys::BuildMaster($aid);
        $lvData = oo::commonOprRedis('activity')->hGet($key,$uid);
        $lvData = json_decode($lvData,true);
        $ret['buildReward']=$ret['buildMaster']=[];
        if(!empty($lvData)){//当前有奖励
            sort($lvData);
            $ret['buildReward'] =  $this->getBuildReward($uid,$aid,$lvData[0]);
            $ret['buildMaster'] =   $lvData;
        }else{//当前无奖励
            $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
            $ret['buildReward'] = $this->getBuildReward($uid,$aid,$lv);
        }
        return $ret;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>疯狂卡组>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:疯狂卡组活动加成比
     * User: wsc
     * Time: 2020/9/2 16:21
     * @param $uid
     * @param $aid
     * @return array
     */
    public function getCrazyCardGroupBet($uid,$aid){
        $config = [];
        $rewardCfg = $this->getActReward($aid)['reward'];
        $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        foreach ($rewardCfg as $v){
            if($v['slv']<=$lv&&$v['elv']>$lv){
                $config['rate'] = $v['num'];
            }
        }
        return $config;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>限时收集>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:
     * User: wsc
     * Time: 2020/12/18 20:31
     * @param $now
     * @param int $do 1手动开2手动关
     * @param int $ts 开启时间
     * @return bool
     */
    public function setNewCollectTimeLimit($now,$do=0,$ts=0){
//        $aidList1 = $this->getAllOnlineActivityByType('collect');
//        $aidList2 = $this->getAllOnlineActivityByType('super_collect');
        $aidList = $this->getAllOnlineActivityByType('super_collect');//array_merge($aidList1?$aidList1:[],$aidList2?$aidList2:[]);
        if(empty($aidList)) return false;
        foreach ($aidList as $aid){
            $actInfo = $this->getActivity($aid);
            $extraData =!empty($actInfo['extraData'])?json_decode($actInfo['extraData'],true):[];
            //限时奖励
            if(isset($extraData['open'])&&intval($extraData['open'])!=0&&!empty($extraData['ts'])&&is_array($extraData['ts'])){
                foreach ($extraData['ts'] as $v){
                    if(date('YmdHi',$now)==date('YmdHi',strtotime($v['s']))){//开
                        $ts =  intval(strtotime($v['e']))-intval(strtotime($v['s']));
                        if($ts>0){
                            oo::commonOprRedis('activity')->setex(okeys::timeLimitAct($aid),1,$ts);
                            $this->activityCommonPush('collect',1,[],$aid,$actInfo["type"]);
                        }
                    }else if(date('YmdHi',$now)==date('YmdHi',strtotime($v['e']))){//关
                        oo::commonOprRedis('activity')->exists(okeys::timeLimitAct($aid))&&oo::commonOprRedis('config')->delete(okeys::timeLimitAct($aid));
                        $this->activityCommonPush('collect',0,[],$aid,$actInfo["type"]);
                    }
                }
            }
            //限时bet(已经弃用,分裂到单独活动)
            if(isset($extraData['open_bet'])&&intval($extraData['open_bet'])!=0&&!empty($extraData['bet_ts'])&&is_array($extraData['bet_ts'])&&intval($extraData['bet'])>1){
                foreach ($extraData['bet_ts'] as $v){
                    if(date('YmdHi',$now)==date('YmdHi',strtotime($v['s']))){//开
                        $ts =  intval(strtotime($v['e']))-intval(strtotime($v['s']));
                        if($ts>0){
                            oo::commonOprRedis('activity')->setex(okeys::timeLimitBetAct($aid),1,$ts);
                            $this->activityCommonPush('collect_bet',1,[],$aid);
                        }
                    }else if(date('YmdHi',$now)==date('YmdHi',strtotime($v['e']))){//关
                        oo::commonOprRedis('activity')->exists(okeys::timeLimitBetAct($aid))&&oo::commonOprRedis('config')->delete(okeys::timeLimitBetAct($aid));
                        $this->activityCommonPush('collect_bet',0,[],$aid,$actInfo["type"]);
                    }
                }
            }
        }
//        if($do==1){
//            $ts = $ts?$ts:600;
//            $aidList[0]&&oo::commonOprRedis('config')->setex(okeys::timeLimitAct($aidList[0]),1,$ts);
//            $this->activityCommonPush('collect',1,[],$aid);
//        }else if($do==2){
//            $aidList[0]&&oo::commonOprRedis('config')->delete(okeys::timeLimitAct($aidList[0]));
//            $this->activityCommonPush('collect',0,[],$aid);
//        }
    }
    /**
     * Notes:自动手动设置开启关闭限时收集
     * User: wsc
     * Time: 2020/9/7 10:29
     * @param $now
     * @param int $do
     * @return bool
     */
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>限时邀请>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:获取邀请奖励
     * User: wsc
     * Time: 2020/9/14 12:28
     * @param $uid
     * @param $aid
     * @return mixed
     */
    public function getInviteReward($uid,$aid){
        $reward = $this->getActReward($aid)['reward'];
        $datas =[];
        $list = oo::commonOprRedis('activity')->hGetAll(okeys::activityInviteUserList($uid,$aid));
        $overNum =0;
        foreach ($list as $k=>$v){
            if($v>=1){
                $overNum++;
            }
        }
        $lv = oo::commonOprModel('member')->getUserAssetsInfo($uid)['levelId'];
        $bet = $this->getCoinRewardByTypeAndLevel('architecture',$lv);
        foreach ($reward as $k=>$v){
            $data['stage'] =$v['stage'];
            $data['num'] = $v['stepnum'];
            $data['props'] = [];
            foreach ($v['prize'] as $val){
                $data['props'][] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
            $data['status'] =0;
            if($overNum>=$data['num']){
                $data['status'] =1;
            }
            $stage_status = intval(oo::commonOprRedis('activity')->hGet(okeys::activityInviteRewardStage($aid,$uid),$data['stage']));
            if($stage_status==2){
                $data['status'] =2;
            }
            $datas['config'][] = $data;
        }
        return $datas;
    }

    /**
     * Notes:尝试推送邀请活动阶段奖励
     * User: wsc
     * Time: 2020/10/21 20:12
     * @param $aid
     * @param $uid
     * @return bool
     */
    public function tryPushFinshInvite($aid,$uid){
        $list = oo::commonOprRedis('activity')->hGetAll(okeys::activityInviteUserList($uid,$aid));
        $overNum =0;
        foreach ($list as $k=>$v){
            if($v>=1){
                $overNum++;
            }
        }
        $reward = $this->getActReward($aid)['reward'];

        $isSend = oo::commonOprRedis('common')->get(okeys::ActivityFlushMsgLock($aid,$uid));
        if(!$isSend){
            foreach ($reward as $k=>$v){
                if($overNum==$v['stepnum']){
                    oo::commonOprRedis('activity')->hSet(okeys::activityInviteRewardStage($aid,$uid),$v['stage'],1);//设置领奖状态为可领取
                    $data =[
                        "actId"  =>27,
                        "aid"    =>$aid,
                    ];
                    oo::commonOprRedis('common')->setex(okeys::ActivityFlushMsgLock($aid,$uid),1,2*3600);
                    oo::commonOprModel('Workerman')->push($uid,ocmd::$send['ActivityFlush'],$data); //推送可领奖
                    break;
                }
            }
        }
        return true;
    }
    /**
     * Notes:写每个进度里完成绑定的用户
     * User: wsc
     * Time: 2020/9/17 18:21
     * @param $aid
     * @param $uid
     * @param $fuid
     */
    public function writeInviteRate($aid,$uid,$fuid){
        $reward = $this->getActReward($aid)['reward'];
        $key = okeys::activityInviteUserRate($aid,$uid);
        $list = oo::commonOprRedis('activity')->hGetAll($key);
        if(empty($list)){
            for($i=1;$i<=count($reward);$i++){
                $list[$i] = '[]';
            }
            oo::commonOprRedis('activity')->hMset($key,$list);
        }
        $overList =[];//当前所有被记录用户
        ksort($list);
        $stage =0;;
        //找到当前未满的进度 $stage
        foreach ($list as $k=>$v){
            $uList = json_decode($v,true);
            $nums = $reward[$k]['stepnum'];
            $overList = array_merge($overList,$uList);
            if($uList[$nums-1]){
                continue;
            }else{
                $stage =$k;
                break;
            }
        }
        if($stage>count($reward)) return -1;//达到上限
        if(in_array($fuid,$overList)) return -2;//已被记录
        $overList = array_unique($overList);
//        $uList = json_decode($list[$stage],true);
        $uList = $overList;
        $uList[] = $fuid;
        oo::commonOprRedis('activity')->hSet($key,$stage,json_encode($uList));
        if($nums==count($uList)){//达到当前进度领奖标准
            oo::commonOprRedis('activity')->hSet(okeys::activityInviteRewardStage($aid,$uid),$stage,1);//设置领奖状态为可领取
            $data =[
                "actId"  =>27,
                "aid"    =>$aid,
            ];
            oo::commonOprModel('Workerman')->push($uid,ocmd::$send['ActivityFlush'],$data); //推送可领奖
            return 2;
        }
        return 1;
    }
    /**
     * Notes:领取邀请奖励
     * User: wsc
     * Time: 2020/9/14 20:48
     * @param $uid
     * @param $aid
     * @param $stage
     * @return array
     */
    public function receiveInviteReward($uid,$aid,$stage){
        $key = okeys::activityInviteRank($aid);
        $rewards = [];
        $rewardInfo = $this->getInviteReward($uid,$aid);
        $reward = array_column($rewardInfo['config'],null,'stage');
        if(empty($reward[$stage])){
            return ["code"=>-1,"msg"=>"没有可领取的奖励","data"=>[]];
        }
        if($reward[$stage]['status']==2){
            return ["code"=>-3,"msg"=>"已领过该阶段奖励","data"=>[]];
        }
        if($reward[$stage]['status']!=1){
            return ["code"=>-2,"msg"=>"未达领奖条件","data"=>[]];
        }
//        $ulist = json_decode(oo::commonOprRedis('activity')->hGet(okeys::activityInviteUserRate($aid,$uid),$stage),true);
//        if(empty($ulist)){
//            return ["code"=>-4,"msg"=>"阶段内用户数据异常","data"=>[]];
//        }
        $needChangeNum = $reward[$stage]['num'] -$reward[$stage-1]['num'];
        $list = oo::commonOprRedis('activity')->hGetAll(okeys::activityInviteUserList($uid,$aid));
        foreach ($list as $k=>$v){
            if($v==1) $uArr[]=$k;
        }
        $ulist = array_slice($uArr,$needChangeNum);

        foreach ($reward[$stage]['props'] as $k=>$v){
            $result = oo::commonOprModel('member')->sendReward($uid,$v['propsId'],$v['num'],204,"活动:time_limit_invite:{$aid}：".$stage,$v['value'],$v);
            if($v['propsId']==15){
                oo::commonOprRedis('activity')->zIncrBy($key,$v['num'],$uid);
            }
            $one=$v;
            if(in_array($v['propsId'],[13,18,19,20,21,29,30])){
                $one['value'] = $result;
            }
            $rewards[] = $one;
        }
        oo::commonOprRedis('activity')->hSet(okeys::activityInviteRewardStage($aid,$uid),$stage,2);//设置领奖记录
        foreach ($ulist as $fuid){
            $this->setInviteLog($aid,$uid,$fuid,2);
        }
        $ret = [
            "code"=>1,
            "data"=>[
                "rank"=>$this->getInviteRank($aid),
                "reward"=>$rewards,//$this->getInviteReward($uid,$aid),
                'inviteList'=>$this->getUserInviteActData($uid,$aid)
            ],
            "msg"=>"领取成功"
        ];
        oo::commonOprRedis('common')->delete(okeys::ActivityFlushMsgLock($aid,$uid));
        return $ret;
    }

    /**
     * Notes:尝试完成邀请活动
     * User: wsc
     * Time: 2020/9/15 10:40
     * @param $aid
     * @param $uid  -完成活动的人
     * @param $fuid -被邀请人
     * @param $type
     * @return bool
     */
    public function tryFinishIntivityAct($aid,$uid,$fuid,$type,$createtime=0){
        $actInfo = $this->getActivity($aid);
        $rewardCfg = json_decode($actInfo['reward_conf'],true);
        if($createtime<$actInfo['start_time']||$createtime>$actInfo['end_time']){
            return 0;
        }
        if($type!=$rewardCfg['type']){//当前完成非活动模式
            return -1;
        }
        if($actInfo['reward_time']<time()){//进度收集已停止
            return -2;
        }
        $res = oo::commonOprRedis('activity')->hGet(okeys::activityInviteUserList($uid,$aid),$fuid);
        if($res!=0){//被邀请的对象状态异常
            return -3;
        }
        if($type==3){
            $lv = oo::commonOprModel('member')->getUserLevel($fuid)['levelId'];
            if($lv<$rewardCfg['ext_num']){//未到指定等级
                return -4;
            }
        }
        $this->setInviteLog($aid,$uid,$fuid,1);//完成-加进度值
        $nums = oo::commonOprRedis('activity')->hLen(okeys::activityInviteUserList($uid,$aid));
        oo::commonOprModel('currency')->actlog($actInfo['id'],$uid,'intivity_rate','+',1,$nums,1,"来自{$fuid}");//活动流水
        return true;
    }
    /**
     * Notes:设置邀请记录
     * User: wsc
     * Time: 2020/9/12 18:55
     * @param $aid
     * @param $uid
     * @param $fuid
     * @param int $status
     */
    public function setInviteLog($aid,$uid,$fuid,$status=0){
        $key =  okeys::activityInviteUserList($uid,$aid);
        $res['setList'] = oo::commonOprRedis('activity')->hSet($key,$fuid,$status);
        if($status==1){
            $res['writeRate'] =$this->tryPushFinshInvite($aid,$uid);
        }
        return $res;
    }

    /**
     * Notes:获取邀请列表
     * User: wsc
     * Time: 2020/9/12 18:55
     * @param $uid
     * @param $aid
     * @return array
     */
    public function getUserInviteActData($uid,$aid){
        $key =  okeys::activityInviteUserList($uid,$aid);
        $uList = oo::commonOprRedis('activity')->hGetAll($key);
        $data = $list = [];
        if(!empty($uList)){
            foreach ($uList as $k=>$v){
                $info = oo::commonOprModel('member')->getUserInfo($k);
                $list = [
                    'uid'       =>$k,
                    "nick"      =>oo::commonOprModel('member')->getUserFirstName($info['nick']),
                    "s_picture" =>$info['s_picture'],
                    "vip"       =>$info['vip'],
                    "vipLv"     =>$info['vipLv'],
                    "vipExpire" =>$info['vipExpire'],
                    "avatar"    =>$info['avatar'],
                    'status'    =>$v
                ];
                $data[] = $list;
            }
        }
        return $data;
    }

    /**
     * Notes:获取邀请排行
     * User: wsc
     * Time: 2020/9/14 14:07
     * @param $aid
     * @return array
     */
    public function getInviteRank($aid){
        $key = okeys::activityInviteRank($aid);
        $list = oo::commonOprRedis('activity')->zRevRange($key,0,49,true);
        $rlist = [];
        if(!empty($list)){
            foreach ($list as $uid=>$v){
                $info = oo::commonOprModel('member')->getUserInfo($uid);
                $rlist[] = [
                    'uid'       =>$uid,
                    "nick"      =>oo::commonOprModel('member')->getUserFirstName($info['nick']),
                    "s_picture" =>$info['s_picture'],
                    "vip"       =>$info['vip'],
                    "vipLv"     =>$info['vipLv'],
                    "vipExpire" =>$info['vipExpire'],
                    "avatar"    =>$info['avatar'],
                    'getSpins'    =>$v
                ];
            }
        }
        return $rlist;
    }

    /**
     * Notes:添加邀请排行机器人
     * User: wsc
     * Time: 2020/10/29 15:04
     * @param $aid
     */
    public function addRobotInviteRank($aid){
        $rList = oo::commonOprModel('robot')->getAllRobot();
        $robots = array_rand($rList,20);
        $nums =[50,150];
        foreach ($robots as $index){
            $uid =$rList[$index];
            $num = $nums[array_rand($nums,1)];
            oo::commonOprRedis('activity')->zAdd(okeys::activityInviteRank($aid),$num,$uid);
        }
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>累充活动>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:累加充值金额
     * User: wsc
     * Time: 2020/10/13 10:38
     * @param $uid
     * @param $num
     * @return bool|float
     */
    public function addSumPayNum($uid,$num){
        $aid = $this->activityLock($uid,'accumulated_pay');
        if(!$aid) return true;
        $key = okeys::activitySumPayNum($aid,$uid);
        $num = number_format($num)*1000;
        $lastNum = oo::commonOprRedis('activity')->incrBy($key,$num);
        oo::commonOprModel('currency')->actlog($aid,$uid,'pay_score','+',$num,$lastNum,1,"");//活动记录流水

        if(!oo::commonOprRedis('common')->get(okeys::ActivityFlushMsgLock($aid,$uid))){
            $reward = $this->getActReward($aid)['reward'];
            foreach ($reward as $k=>$v){
                $isReceive = intval(oo::commonOprRedis('activity')->hGet(okeys::activitySumPayReceiveLog($aid,$uid),$v['stage']));
                if($v['stepnum']*1000<=$lastNum&&$isReceive==0){//存在达标的
                    $data =[
                        "actId"  =>29,
                        "aid"    =>$aid,
                    ];
                    oo::commonOprRedis('common')->setex(okeys::ActivityFlushMsgLock($aid,$uid),1,2*3600);
                    oo::commonOprModel('Workerman')->push($uid,ocmd::$send['ActivityFlush'],$data); //推送可领奖
                    return true;
                }
            }
        }
        return round($lastNum/1000,2);
    }

    /**
     * Notes:获取累充奖励配置
     * User: wsc
     * Time: 2020/10/13 10:38
     * @param $uid
     * @param $aid
     * @return array
     */
    public function getSumPayActReward($uid,$aid){
        $reward = $this->getActReward($aid)['reward'];
        $overNum =oo::commonOprRedis('activity')->get(okeys::activitySumPayNum($aid,$uid));
        $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        $bet =$this->getCoinRewardByTypeAndLevel('accumulated_pay',$lv);
        foreach ($reward as $k=>$v){
            $data['stage'] =$v['stage'];
            $data['stepnum'] = intval($v['stepnum']);
            $data['props'] = [];
            foreach ($v['prize'] as $val){
                $data['props'][] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
            $data['status'] =0;
            if($overNum>=$data['stepnum']*1000){
                $data['status'] =1;
            }
            $stage_status = intval(oo::commonOprRedis('activity')->hGet(okeys::activitySumPayReceiveLog($aid,$uid),$data['stage']));
            if($stage_status>0){
                $data['status'] =2;
            }
            $datas[] = $data;
        }
        return $datas;
    }

    /**
     * Notes:领取累充活动奖励
     * User: wsc
     * Time: 2020/10/13 11:04
     * @param $uid
     * @param $aid
     * @param $stage
     * @return array
     */
    public function receiveSumPayActReward($uid,$aid,$stage){
        $key = okeys::activitySumPayReceiveLog($aid,$uid);
        $rewardInfo = $this->getSumPayActReward($uid,$aid);
        $reward = array_column($rewardInfo,null,'stage');
        if(empty($reward[$stage])){
            return ["code"=>-1,"msg"=>"没有可领取的奖励","data"=>[]];
        }
        if($reward[$stage]['status']==2){
            return ["code"=>-3,"msg"=>"已领过该阶段奖励","data"=>[]];
        }
        if($reward[$stage]['status']!=1){
            return ["code"=>-2,"msg"=>"未达领奖条件","data"=>[]];
        }
        foreach ($reward[$stage]['props'] as $k=>$v){
            $result = oo::commonOprModel('member')->sendReward($uid,$v['propsId'],$v['num'],204,"活动:accumulated_pay:{$aid}：".$stage,$v['value'],$v);
            $reward[$stage]['props'][$k]['value'] = $result;
        }
        oo::commonOprRedis('activity')->hSet($key,$stage,time());
        oo::commonOprRedis('common')->delete(okeys::ActivityFlushMsgLock($aid,$uid));
        return ["code"=>1,"msg"=>"领取成功","data"=>$reward[$stage]['props']];
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>公共进度类活动>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:加公共类
     * User: wsc
     * Time: 2021/2/4 19:07
     * @param $uid
     * @param $type
     * @param $num
     * @return bool|int
     */
    public function addCommonScore($uid,$type,$num){
        $aid = $this->activityLock($uid,$type);
        if(!$aid) return true;
        $actInfo = $this->getActivity($aid);
        $now = time();
        if($now>=$actInfo['end_time']){
            return true;
        }
        $key = okeys::activityCommonRateSumScore($aid,$uid);
        $num =abs(intval($num));
        $lastNum = oo::commonOprRedis('activity')->incrBy($key,$num);
        oo::commonOprModel('currency')->actlog($aid,$uid,$type,'+',$num,$lastNum,1,"");//活动记录流水
        if(!oo::commonOprRedis('common')->get(okeys::ActivityFlushMsgLock($aid,$uid))){
            $reward = $this->getActReward($aid)['reward'];
            foreach ($reward as $k=>$v){
                $isReceive = intval(oo::commonOprRedis('activity')->hGet(okeys::activityCommonRateReceiveLog($aid,$uid),$v['stage']));
                if($v['stepnum']<=$lastNum&&$isReceive==0){//存在达标的
                    $data =[
                        "actId"  =>$this->act_type[$type]['rcid'],
                        "aid"    =>$aid,
                    ];
                    oo::commonOprRedis('common')->setex(okeys::ActivityFlushMsgLock($aid,$uid),1,2*3600);
                    oo::commonOprModel('Workerman')->push($uid,ocmd::$send['ActivityFlush'],$data); //推送可领奖
                    return true;
                }
            }
        }
        return intval($lastNum);
    }

    /**
     * Notes:获取公共进度类奖励配置
     * User: wsc
     * Time: 2021/2/4 19:06
     * @param $uid
     * @param $aid
     * @param $type
     * @return array
     */
    public function getCommonRateReward($uid,$aid,$type){
        $reward = $this->getActReward($aid)['reward'];
        $overNum =oo::commonOprRedis('activity')->get(okeys::activityCommonRateSumScore($aid,$uid));
        $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        $bet =$this->getCoinRewardByTypeAndLevel($type,$lv);
        foreach ($reward as $k=>$v){
            $data['stage'] =$v['stage'];
            $data['stepnum'] = intval($v['stepnum']);
            $data['props'] = [];
            foreach ($v['prize'] as $val){
                $data['props'][] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
            $data['status'] =0;
            if($overNum>=$data['stepnum']){
                $data['status'] =1;
            }
            $stage_status = intval(oo::commonOprRedis('activity')->hGet(okeys::activityCommonRateReceiveLog($aid,$uid),$data['stage']));
            if($stage_status>0){
                $data['status'] =2;
            }
            $datas[] = $data;
        }
        return $datas;
    }

    /**
     * Notes:领取公共奖励进度奖励
     * User: wsc
     * Time: 2021/4/14 10:30
     * @param $uid
     * @param $aid
     * @param $type
     * @param $stage
     * @return array
     */
    public function receiveCommonRateReward($uid,$aid,$type,$stage){
        $key = okeys::activityCommonRateReceiveLog($aid,$uid);
        $rewardInfo = $this->getCommonRateReward($uid,$aid,$type);
        $reward = array_column($rewardInfo,null,'stage');
        if(empty($reward[$stage])){
            return ["code"=>errorCode::CONDITION_NOT_RNOUGH,"msg"=>"没有可领取的奖励","data"=>[]];
        }
        if($reward[$stage]['status']==2){
            return ["code"=>errorCode::OVER_RECEIVE_REWARD,"msg"=>"已领过该阶段奖励","data"=>[]];
        }
        if($reward[$stage]['status']!=1){
            return ["code"=>errorCode::CONDITION_NOT_RNOUGH,"msg"=>"未达领奖条件","data"=>[]];
        }
        foreach ($reward[$stage]['props'] as $k=>$v){
            $result = oo::commonOprModel('member')->sendReward($uid,$v['propsId'],$v['num'],204,"活动:{$type}:{$aid}：".$stage,$v['value'],$v);
            $reward[$stage]['props'][$k]['value'] = $result;
        }
        oo::commonOprRedis('activity')->hSet($key,$stage,time());
        oo::commonOprRedis('common')->delete(okeys::ActivityFlushMsgLock($aid,$uid));
        return ["code"=>1,"msg"=>"领取成功","data"=>$reward[$stage]['props']];
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>建筑打折>>>>>>>>>>>>>>>>>>>>
    public function discountsArch($aid,$optLevelNum,$uid=0){
        $confArr =  $this->getActReward($aid)['reward'];
        $conf = array_column($confArr,null,'level');
        $bfb = intval($conf[$optLevelNum+1]['disNum']);
        $b = 1;
        if($bfb>0){
            $b = (100-$bfb)*0.01;
        }
        return $b;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    //>>>>>>>>>>>>>>>>>>>>>排行榜>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:排行榜最终排行奖励自动结算
     * User: wsc
     * Time: 2020/8/6 15:43
     * @param $aid
     */
//    public function checkRankReward($aid){
//        $key =  okeys::activityUserRankBindRoomId($aid);
//        $uidRoomList =  oo::commonOprRedis('activity')->hGetAll($key);
//        foreach ($uidRoomList as $uid=>$roomId){
//            $key2 = okeys::activityUserRankList($aid,$roomId);
//            $ranking  = intval(oo::commonOprRedis('activity')->zRevRank($key2,$uid))+1;//排名
//            $num =  intval(oo::commonOprRedis('activity')->zScore($key2,$uid));//分数
////                $uType = oo::commonOprRedis('activity')->hGet(okeys::activityRoomUserList($aid,$roomId),$uid);//用户类型
//            $reward = $this->getRankRewardByLimit($uid,$aid,$ranking);//获取当前排行奖励
//            $data = ["ranking"=>$ranking,"num"=>$num,"time"=>time(),"aid"=>$aid,"roomId"=>$roomId,"uid"=>$uid,"status"=>0,'reward'=>$reward];
//            if(oo::commonOprRedis('statistics')->sContains(okeys::activityCheckLock($aid),$uid)){//若已主动结算，则不参与自动结算
//                continue;
//            }
//            oo::commonOprRedis('statistics')->sAdd(okeys::activityCheckLock($aid),$uid);//结算锁
//            oo::commonOprRedis('activity')->setex(okeys::activityUserRankEndReward($uid),json_encode($data),86400*3);//设置用户排行最终奖励
//            oo::commonOprRedis('Statistics')->lPush(okeys::activityRankLog(1),json_encode($data));//排行榜结算流水记录
//        }
//        oo::commonOprRedis('statistics')->expire(okeys::activityCheckLock($aid),3600);
//        return array_keys($uidRoomList);
//    }

    /**
     * Notes:排行榜最终排行奖励自动结算 加上结算机器人
     * User: hss
     * Time: 2021/3/6 15:36
     * @param $aid
     */
    public function checkRankRewardRobot($aid){
        $key =  okeys::activityUserRankBindRoomId($aid);
        $uidRoomList =  oo::commonOprRedis('activity')->hGetAll($key);

        $keys = okeys::activityRankRoomList($aid);//活动房间列表
        $ret = oo::commonOprRedis('activity')->hGetAll($keys);
        foreach($ret as $roomId => $row){
            $keys = okeys::activityRoomUserList($aid,$roomId);
            $uidList = oo::commonOprRedis('activity')->hGetAll($keys);
            foreach ($uidList as $uid => $userType){
                $key2 = okeys::activityUserRankList($aid,$roomId);
                $ranking  = intval(oo::commonOprRedis('activity')->zRevRank($key2,$uid))+1;//排名
                $num =  intval(oo::commonOprRedis('activity')->zScore($key2,$uid));//分数
//                $uType = oo::commonOprRedis('activity')->hGet(okeys::activityRoomUserList($aid,$roomId),$uid);//用户类型
                $reward = $this->getRankRewardByLimit($uid,$aid,$ranking);//获取当前排行奖励

                $data = ["ranking"=>$ranking,"num"=>$num,"time"=>time(),"aid"=>$aid,"roomId"=>$roomId,"uid"=>$uid,"status"=>0,'reward'=>$reward];
                if(!$userType){
                    //0真人 1机器人
                    if(oo::commonOprRedis('activity')->get(okeys::activityCheckLock($aid,$uid))){//若已主动结算，则不参与自动结算
                        continue;
                    }
                    oo::commonOprRedis('activity')->setex(okeys::activityCheckLock($aid,$uid),1,3600);//新结算锁
//                    oo::commonOprRedis('statistics')->sAdd(okeys::activityCheckLock($aid),$uid);//结算锁
                    oo::commonOprRedis('activity')->setex(okeys::activityUserRankEndReward($uid),json_encode($data),86400*3);//设置用户排行最终奖励
                }

                oo::commonOprRedis('Statistics')->lPush(okeys::activityRankLog(1),json_encode($data));//排行榜结算流水记录
            }
        }

//        oo::commonOprRedis('statistics')->expire(okeys::activityCheckLock($aid),3600);
        return array_keys($uidRoomList);
    }

    /**
     * Notes:排行榜无进度最终排行奖励自动结算 加上结算机器人
     * User: hss
     * Time: 2021/7/26 14:47
     * @param $aid
     */
    public function checkRankRewardRobotNoPro($aid){
        $key =  okeys::activityUserRankBindRoomId($aid);
        $uidRoomList =  oo::commonOprRedis('activity')->hGetAll($key);

        $keys = okeys::activityRankRoomList($aid);//活动房间列表
        $ret = oo::commonOprRedis('activity')->hGetAll($keys);
        foreach($ret as $roomId => $row){
            $keys = okeys::activityRoomUserList($aid,$roomId);
            $uidList = oo::commonOprRedis('activity')->hGetAll($keys);
            foreach ($uidList as $uid => $userType){
                $key2 = okeys::activityUserRankList($aid,$roomId);
                $ranking  = intval(oo::commonOprRedis('activity')->zRevRank($key2,$uid))+1;//排名
                $num =  intval(oo::commonOprRedis('activity')->zScore($key2,$uid));//分数
                $reward = $this->getRankRewardByLimit($uid,$aid,$ranking);//获取当前排行奖励

                $data = ["ranking"=>$ranking,"num"=>$num,"time"=>time(),"aid"=>$aid,"roomId"=>$roomId,"uid"=>$uid,"status"=>0,'reward'=>$reward];
                if(!$userType){
                    //0真人 1机器人
                    if(oo::commonOprRedis('activity')->get(okeys::activityCheckLock($aid,$uid))){//若已主动结算，则不参与自动结算
                        continue;
                    }
                    oo::commonOprRedis('activity')->setex(okeys::activityCheckLock($aid,$uid),1,3600);//新结算锁
                    oo::commonOprRedis('activity')->setex(okeys::activityUserRankEndReward($uid,'rank2'),json_encode($data),86400*3);//设置用户排行最终奖励
                }

                oo::commonOprRedis('Statistics')->lPush(okeys::activityRankLog(1),json_encode($data));//排行榜结算流水记录
            }
        }

        return array_keys($uidRoomList);
    }

    /**
     * Notes:获取用户排行榜结算奖励
     * User: wsc
     * Time: 2020/8/12 12:30
     * @param $uid
     * @param $aid
     * @param $type
     * @return array|mixed
     */
    public function getUserCheckRankReward($uid,$aid=0,$type = "rank"){
        $data =[];
        if($type == "rank"){
            $keys= okeys::activityUserRankEndReward($uid);
        }else{
            $keys= okeys::activityUserRankEndReward($uid,$type);
        }

        $rDataJson = oo::commonOprRedis('activity')->get($keys);
        if(!empty($rDataJson)&&$aid){
            $rDara = json_decode($rDataJson,true);
            if($rDara['aid']!=$aid){//存在上次未可领取的奖励时,继续主动结算覆盖上次内容
                $rDataJson = '';
            }
        }
        if(!$rDataJson&&$aid){//主动结算(暂未启用)
            $roomId = $this->getUserRankRoomId($uid,$aid);
            $key = okeys::activityUserRankList($aid,$roomId);
            $ranking  = intval(oo::commonOprRedis('activity')->zRevRank($key,$uid))+1;//排名
            $num =  intval(oo::commonOprRedis('activity')->zScore($key,$uid));//分数
            if(!$roomId||$num<5){
                return false;
            }
            if(oo::commonOprRedis('statistics')->get(okeys::activityCheckLock($aid,$uid))){//若已自动结算，则不参与主动结算
                return false;
            }
            $reward = $this->getRankRewardByLimit($uid,$aid,$ranking);//获取当前排行奖励
            if(!empty($reward)){
                $data = ["ranking"=>$ranking,"num"=>$num,"time"=>time(),"aid"=>intval($aid),"roomId"=>$roomId,"uid"=>$uid,"status"=>-1,'reward'=>$reward];
                if($type == "rank") {
                    oo::commonOprRedis('activity')->setex(okeys::activityUserRankEndReward($uid), json_encode($data), 86400 * 3);//设置用户排行最终奖励
                }else{
                    oo::commonOprRedis('activity')->setex(okeys::activityUserRankEndReward($uid,$type), json_encode($data), 86400 * 3);//设置用户排行最终奖励
                }
                oo::commonOprRedis('Statistics')->lPush(okeys::activityRankLog(1),json_encode($data));//排行榜结算流水记录

                oo::commonOprRedis('activity')->setex(okeys::activityCheckLock($aid,$uid),1,3600);//新结算锁
//                oo::commonOprRedis('statistics')->sAdd(okeys::activityCheckLock($aid),$uid);//结算锁
//                oo::commonOprRedis('statistics')->expire(okeys::activityCheckLock($aid),3600);
            }
        }else{
            $data = json_decode($rDataJson,true);
        }
        return $data;
    }

    /**
     * 排行榜参数
     * @param $aid
     * @return int
     * Created by: Owen
     * Created on: 2020/10/19 17:43
     */
    public function getRankExtraData($aid){
        $activityData = self::getActivity($aid);
        return json_decode($activityData['extraData'],true);
    }

    /**
     * 获取分区体力开销停止体力
     * @param $aid
     * @param $setType
     * @param $id
     * @return mixed
     * Created by: Owen
     * Created on: 2020/10/19 20:17
     */
    public function getRankMaxSpins($aid,$setType,$id){
        $activityData = self::getActivity($aid);
        $extraData = json_decode($activityData['extraData'],true);
        if($setType == 1){
            $set = $extraData['vipSetSpins'];
        }else{
            $set = $extraData['spinsSetSpins'];
        }
        return max(0,$set[$id]);
    }


    /**
     * 获取排行榜用户分块 -- VIP
     * @param $uid
     * @param $aid
     * @return int|mixed|string
     * Created by: Owen
     * Created on: 2020/8/6 16:42
     */
    public function getRankUserVipSetId($uid,$aid,$extraData,$all = false){
        $vipSet    = $extraData['vipSet'];
        rsort($vipSet);
        if($all){
            $arrId  = [];
            foreach($vipSet as $key=>$row){
                $arrId[] = $key + 1;
            }
            return $arrId;
        }
        $cacheKey = okeys::RankUserSetId($aid);
        $cache    = oo::commonOprRedis('activity')->hGet($cacheKey,$uid);
        if(!$cache){
            $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
            $vipPoint = $userInfo['vipPoint'];
            $cache = 6;
            foreach($vipSet as $key=>$row){
                if($vipPoint >= $row){
                    $cache = $key+1;
                    break;
                }
            }
            oo::commonOprRedis('activity')->hSet($cacheKey,$uid,$cache);
        }
        return $cache;
    }

    /**
     * 获取排行榜用户分块 -- 过去4天体力消耗值
     * @param $uid
     * @param $aid
     * @return int|mixed|string
     * Created by: Richard
     * Created on: 2021/6/17 14:34
     */
    public function getRankUserDaysSpinsSetId($uid,$aid,$extraData,$all = false){
        $spinsSet  = $extraData['spinsSet'];
        rsort($spinsSet);
        if($all){
            $arrId  = [];
            foreach($spinsSet as $key=>$row){
                $arrId[] = $key + 1;
            }
            return $arrId;
        }
        $cacheKey = okeys::RankUserSpinsSetId($aid);
        $cache    = oo::commonOprRedis('activity')->hGet($cacheKey, $uid);
        if(!$cache){ //过去4天的体力消耗总数
            $consumeKeys = [
                okeys::userspinconsume($uid, date('Ymd', strtotime('-1 days'))),
                okeys::userspinconsume($uid, date('Ymd', strtotime('-2 days'))),
                okeys::userspinconsume($uid, date('Ymd', strtotime('-3 days'))),
                okeys::userspinconsume($uid, date('Ymd', strtotime('-4 days'))),
            ];
            $spinsArr = array_filter(oo::commonOprRedis('usercache')->mGet($consumeKeys));
            $spins = $spinsArr ? array_sum($spinsArr) : 0;

            $cache = 9;
            foreach($spinsSet as $key=>$row){
                if($spins >= $row){
                    $cache = $key+1;
                    break;
                }
            }
            oo::commonOprRedis('activity')->hSet($cacheKey,$uid,$cache);
        }
        return $cache;
    }

    /**
     * 获取排行榜用户分块 -- 体力
     * @param $uid
     * @param $aid
     * @return int|mixed|string
     * Created by: Owen
     * Created on: 2020/8/6 16:42
     */
    public function getRankUserSpinsSetId($uid,$aid,$extraData,$all = false){
        $spinsSet  = $extraData['spinsSet'];
        rsort($spinsSet);
        if($all){
            $arrId  = [];
            foreach($spinsSet as $key=>$row){
                $arrId[] = $key + 1;
            }
            return $arrId;
        }
        $cacheKey = okeys::RankUserSpinsSetId($aid);
        $cache    = oo::commonOprRedis('activity')->hGet($cacheKey,$uid);
        if(!$cache){
            $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $spins = $userInfo['spins'];
            $cache = 9;
            foreach($spinsSet as $key=>$row){
                if($spins >= $row){
                    $cache = $key+1;
                    break;
                }
            }
            oo::commonOprRedis('activity')->hSet($cacheKey,$uid,$cache);
        }
        return $cache;
    }


    /**
     * Notes:设置活动排行积分
     * User: wsc
     * Time: 2020/8/3 9:27
     * @param $uid
     * @param $aid
     * @param $num
     * @return int
     */
    public function setUserRankNum($uid,$aid,$num){
        $roomId = $this->getUserRankRoomId($uid,$aid);
        $key    = okeys::activityUserRankList($aid,$roomId);
        $rNum   = oo::commonOprRedis('activity')->zIncrBy($key,$num,$uid);
        return intval($rNum);
    }

    /**
     * 获取活动排行积分
     * @param $uid
     * @param $aid
     * @param $roomId
     * @return int
     * Created by: Owen
     * Created on: 2020/8/6 19:18
     */
    public function getUserRankNum($uid,$aid,$roomId){
        $key    = okeys::activityUserRankList($aid,$roomId);
        return intval(oo::commonOprRedis('Activity')->zScore($key,$uid));
    }

    /**
     * 用户加入房间
     * @param $uid
     * @param $aid
     * @return bool|int|mixed
     * Created by: Owen
     * Created on: 2020/8/3 9:34
     */
    public function addToRankRoom($uid,$aid){
        $roomId = oo::commonOprRedis('activity')->hGet(okeys::activityUserRankBindRoomId($aid),$uid);
        if($roomId){
            return $roomId;
        }
        $userCurRankNum = intval(oo::commonOprRedis('activity')->zScore(okeys::activityUserRankList($aid,0),$uid));
        if($userCurRankNum < 5){
            return false;
        }
        $actData = self::getActivity($aid);
        $extraData = json_decode($actData['extraData'],true);
        $setType   = $extraData['setType'] ?? 1;
        switch($setType){
            case 1: //vip积分
                $setId = self::getRankUserVipSetId($uid,$aid,$extraData);//vip积分分块-ID
                break;
            case 3: //过去4天体力消耗值
                $setId = self::getRankUserDaysSpinsSetId($uid,$aid,$extraData);//过去4天体力分块-ID
                break;
            default: //当前体力值
                $setId = self::getRankUserSpinsSetId($uid,$aid,$extraData);//体力分块-ID
                break;

        }
        //$setId   = $setType == 1 ? self::getRankUserVipSetId($uid,$aid,$extraData) : self::getRankUserSpinsSetId($uid,$aid,$extraData);
        $roomLen = oo::commonOprRedis('activity')->hLen(okeys::activityRankRoomList($aid,$setId));//排行榜活动房间分块列表长度
        $fullArr = oo::commonOprRedis('activity')->sMembers(okeys::activityRankRoomFull($aid));//排行榜活动满员的房间
        $curLimitNum = 30;
        $trueMax     = 50;
        $limitConfig = $extraData['rankLimit'];
        if(!empty($limitConfig)){
            array_multisort(array_column($limitConfig,'time'),SORT_DESC,$limitConfig);
            $trueMax     = max(array_column($limitConfig,'limit'));
            $endTime     = $actData['end_time'];
            $curTime     = time();
            foreach ($limitConfig as $row){
                if($endTime - $row['time'] * 60 * 60 <= $curTime){//距离活动结束越近,增长房间可承载人数
                    $curLimitNum = $row['limit'];
                }else{
                    break;
                }
            }
        }
        for ($i=$roomLen;$i>=1;$i--){
            $checkRoomId  = intval($setId.$i);
            if(in_array($checkRoomId,$fullArr)){
                continue;
            }
            $userCount = intval(oo::commonOprRedis('activity')->hGet(okeys::activityRankRoomList($aid),$checkRoomId));//真人数量
            if($userCount >= $trueMax - 2){
                oo::commonOprRedis('activity')->sAdd(okeys::activityRankRoomFull($aid),$checkRoomId);
                continue;
            }
            $curRoomUserListKey = okeys::activityRoomUserList($aid,$checkRoomId);//房间用户属性列表(包括机器人真人0,机器人1)
            $curRoomRankListKey = okeys::activityUserRankList($aid,$checkRoomId);//排行用户列表
            $userArrLen = oo::commonOprRedis('activity')->hLen($curRoomUserListKey);
            if($userArrLen >= $curLimitNum){
                if($userCount < $curLimitNum - 2){
                    $userArr = oo::commonOprRedis('activity')->hGetAll($curRoomUserListKey);
                    foreach ($userArr as $uid2=>$isRobot){
                        if($isRobot){
                            oo::commonOprRedis('activity')->hDel($curRoomUserListKey,$uid2);//房间用户属性列表去掉机器人
                            oo::commonOprRedis('activity')->zDelete($curRoomRankListKey,$uid2);//排行列表去掉机器人
                            $this->UserAddToRoom($aid,$checkRoomId,$uid,$userCurRankNum);//用户加入房间
                            return $checkRoomId;
                        }
                    }
                }
            }else{
                $remainNum = max($curLimitNum - $userArrLen - 1,0);//房间承载量-房间用户数-1
                $actionRobotNum = $userCount == 1 ? rand(3,5) : rand(1,3);
                $actionRobotNum = min($remainNum,$actionRobotNum);
                $this->UserAddToRoom($aid,$checkRoomId,$uid,$userCurRankNum);
                $actionRobotNum > 0 && $this->RobotAddToRoom($aid,$checkRoomId,$userCurRankNum,$actionRobotNum);//机器人加入房间
                return $checkRoomId;
            }
        }
        $roomLen       = $roomLen + 1;
        $actionRoomId  = intval($setId.$roomLen);
        oo::commonOprRedis('activity')->hSet(okeys::activityRoomUserList($aid,$actionRoomId),$uid,0);//房间内加人
        oo::commonOprRedis('activity')->zAdd(okeys::activityUserRankList($aid,$actionRoomId),$userCurRankNum,$uid);//设定加入房间的值
        $this->RobotAddToRoom($aid,$actionRoomId,$userCurRankNum,rand(5,10));
        oo::commonOprRedis('activity')->hIncrBy(okeys::activityRankRoomList($aid),$actionRoomId,1);     //房间列表加人
        oo::commonOprRedis('activity')->hSet(okeys::activityRankRoomList($aid,$setId),$actionRoomId,1); //设定分块长度
        oo::commonOprRedis('activity')->hSet(okeys::activityUserRankBindRoomId($aid),$uid,$actionRoomId);     //绑定用户房间
        oo::commonOprRedis('activity')->setex(okeys::ActivityRankLastNum($aid,$actionRoomId),$userCurRankNum,10800);// 设定机器人增长基础值
        oo::commonOprRedis('activity')->zDelete(okeys::activityUserRankList($aid,0),$uid);//未入房间前的分数
        return $actionRoomId;
    }

    /**
     * 真人入房间
     * @param $aid
     * @param $roomId
     * @param $uid
     * @param $userCurRankNum
     * @return bool
     * Created by: Owen
     * Created on: 2020/12/19 11:46
     */
    public function UserAddToRoom($aid,$roomId,$uid,$userCurRankNum){
        oo::commonOprRedis('activity')->hSet(okeys::activityRoomUserList($aid,$roomId),$uid,0);// 0真人，1机器人
        oo::commonOprRedis('activity')->zAdd(okeys::activityUserRankList($aid,$roomId),$userCurRankNum,$uid);//设定加入房间的值
        oo::commonOprRedis('activity')->hSet(okeys::activityUserRankBindRoomId($aid),$uid,$roomId);
        oo::commonOprRedis('activity')->zDelete(okeys::activityUserRankList($aid,0),$uid);//未入房间前的分数
        oo::commonOprRedis('activity')->hIncrBy(okeys::activityRankRoomList($aid),$roomId,1);
        return true;
    }

    /**
     * 机器人入房间
     * @param $aid
     * @param $actionRoomId
     * @param $userCurRankNum
     * @param $robotNum
     * @return bool
     * Created by: Owen
     * Created on: 2020/12/19 11:47
     */
    public function RobotAddToRoom($aid,$actionRoomId,$userCurRankNum,$robotNum){
        $robot = oo::commonOprModel('robot')->getAllRobot();
        $randRobot = array_rand($robot,$robotNum);
        if(!is_array($randRobot)){
            $randRobot = [$randRobot];
        }
        $key    = okeys::activityUserRankList($aid,$actionRoomId);
        foreach ($randRobot as $k=>$robotIndex){
            $robotUid = $robot[$robotIndex];
            oo::commonOprRedis('activity')->hSet(okeys::activityRoomUserList($aid,$actionRoomId),$robotUid,1);//房间内加人
            $num = self::getRankRobotInitNum($aid,$k,$userCurRankNum);
            oo::commonOprRedis('activity')->zIncrBy($key,$num,$robotUid);
        }
        return true;
    }

    /**
     * 机器人加分
     * @param $aid
     * Created by: Owen
     * Created on: 2020/8/6 20:54
     */
    public function RankRobotAddNum(){
        $aidArr = self::getAllOnlineActivityByType('rank');
        foreach ($aidArr as $aid){
            $extraData = self::getRankExtraData($aid);
            $setType   = $extraData['setType'] ?? 1;
            $setIdArr  = $setType == 1 ? self::getRankUserVipSetId(0,$aid,$extraData,true) : self::getRankUserSpinsSetId(0,$aid,$extraData,true);
            foreach ($setIdArr as $setIndex=>$setId){
                $key     = okeys::activityRankRoomList($aid,$setId);
                $roomLen = oo::commonOprRedis('activity')->hLen($key);
                $maxSpins= self::getRankMaxSpins($aid,$setType,$setIndex);
                for ($i=1;$i<=$roomLen;$i++){
                    $checkRoomId  = intval($setId.$i);
                    $roomUserList = oo::commonOprRedis('activity')->hGetAll(okeys::activityRoomUserList($aid,$checkRoomId));
                    $list = oo::commonOprRedis('activity')->zRevRange(okeys::activityUserRankList($aid,$checkRoomId),0,-1,true);
                    $keys = okeys::activityUserRankList($aid,$checkRoomId);
                    $j = 0;
                    $robotActionNum = 0;
                    $lastNum = intval(oo::commonOprRedis('activity')->get(okeys::ActivityRankLastNum($aid,$checkRoomId)));
                    foreach ($list as $uid3=>$score){
                        if(!$roomUserList[$uid3]){
                            oo::commonOprRedis('activity')->setex(okeys::ActivityRankLastNum($aid,$checkRoomId),$score,10800);
                            break;
                        }
                    }
                    foreach ($list as $uid3=>$score){
                        $j++;
                        $userOrRobot = $roomUserList[$uid3];
                        if($j==1){
                            if($userOrRobot == 1){
                                break;
                            }
                            if($userOrRobot == 0 && oo::commonOprRedis('User')->hGet(okeys::ActivityBuyGoods($aid),$uid3)){
                                break;
                            }
                            if($userOrRobot == 0 && intval(oo::commonOprRedis('User')->hGet(okeys::UserRankSpendSpins($aid),$uid3)) >= $maxSpins){
                                break;
                            }
                        }else if($userOrRobot){
                            $action = self::getRankRobotAddNum($aid,$robotActionNum,$j) + $lastNum;
                            $action > $score && oo::commonOprRedis('activity')->zAdd($keys,$action,$uid3);
                            $robotActionNum++;
                            if($robotActionNum >= 2){
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取排行榜机器人增长数量
     * @param $aid
     * @param $n
     * @param $i
     * @return int
     * Created by: Owen
     * Created on: 2020/8/7 17:14
     */
    public function getRankRobotAddNum($aid,$n,$i){
        if($n > 2){
            return 0;
        }else{
            $activityData = self::getActivity($aid);
            $endTimeNum   = floor(max($activityData['end_time'] - time(),0) / 3600);
            $coData       = self::getRankRobotCoefficient($aid,$n);
            return intval($coData['co1'] * $endTimeNum * $endTimeNum + $coData['co2'] * $endTimeNum / $i);
        }
    }

    /**
     * 獲取排行榜機器人指數
     * @param $aid
     * @param $n
     * @return array
     * Created by: Owen
     * Created on: 2020/8/7 17:12
     */
    public function getRankRobotCoefficient($aid,$n){
        $n += 1;
        $activityData = self::getActivity($aid);
        $extraData    = json_decode($activityData['extraData'],true);
        $robot = $extraData['robot'];
        $data  = $robot[$n];
        return [
            'co1' => $data['co1'],
            'co2' => $data['co2'],
        ];
    }

    /**
     * 机器人初始化数量
     * @param $aid
     * @param $k
     * @param $n
     * @return mixed
     * Created by: Owen
     * Created on: 2020/8/6 20:50
     */
    public function getRankRobotInitNum($aid,$k,$n){
        $k += 1;
        $activityData = self::getActivity($aid);
        $extraData = json_decode($activityData['extraData'],true);
        $robot = $extraData['robot'];
        if($k <= 4){
            $data = $robot[$k];
            $num = floor($data['pro'] * $n);
        }else if($k <= 10){
            $data = $robot[$k];
            $num = intval($data['num']);
        }else{
            $data = $robot[49];
            $num = intval($data['num']);
        }
        return max($num,5);
    }

    /**
     * Notes:获取排行榜阶段奖励配置
     * User: wsc
     * Time: 2020/8/1 10:24
     * @param $uid
     * @param $aid
     * @param $d 1对奖励进行处理 0不做处理
     * @return array
     */
    public function getRankStageRewardConf($uid,$aid,$d=1){
        //根据绑定的体力来获取配置
        $bindSpin = intval(oo::commonOprRedis('activity')->hGet(okeys::activityBindUserAttr($uid,$aid),'spins'));
        $data =[];
        $rewardConf = $this->getActReward($aid);//奖励配置
        if(isset($rewardConf['reward'][1]['list'])){//1.7.2版本新模式
            foreach ($rewardConf['reward'] as $k=>$v){
                $v['end'] = $v['end']?$v['end']:100000000;
                if($bindSpin>=$v['star']&&$bindSpin<=$v['end']){
                    $reward = $v['list'];
                    break;
                }
            }
        }
        if(empty($reward)){
            $reward = $rewardConf['reward'][1]['list'];
        }
        if(!$d){
            return $reward;
        }
        $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        $bet =$this->getCoinRewardByTypeAndLevel('rank',$lv);
        foreach ($reward as $k=>$v){
            $data[$k]['id'] =$v['stage'];
            $data[$k]['progressBarId'] =$v['progressBarId'];
            $data[$k]['max'] = $v['stepnum'];
            $data[$k]['props'] = [];
            foreach ($v['prize'] as $val){
                $data[$k]['props'][] = $this->getFormattingProps($uid,$aid,$val,$bet,'rank');
            }
        }
        return $data;
    }

    /**
     * Notes:获取最终排行结算奖励配置
     * User: wsc
     * Time: 2020/11/5 18:32
     * @param $aid
     * @param $uid
     * @param int $d  1对奖励进行处理 0不做处理
     * @return array|mixed
     */
    public function getRankEndRewardConf($aid,$uid){
        $data =[];
        $rewardConf = $this->getActReward($aid);//奖励配置
        $userBindArr = $this->getUserBindAttr($uid, $aid);
        $bindSpin = empty($userBindArr['spins']) ? 0 : $userBindArr['spins'];
        if(isset($rewardConf['extra_reward'][1]['list'])){//1.7.2版本新模式
            foreach ($rewardConf['extra_reward'] as $k=>$v){
                $v['end'] = $v['end']?$v['end']:100000000;
                if($bindSpin>=$v['star']&&$bindSpin<=$v['end']){
                    $reward = $v['list'];
                    break;
                }
            }

            if(empty($reward)){
                $reward = end($rewardConf['extra_reward'])['list'];
            }
        }else{//过度格式
            $reward = $rewardConf['extra_reward'];
        }

        $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        $bet = $this->getCoinRewardByTypeAndLevel('rank',$lv);
        foreach ($reward as $k=>$v){
            $data[$k]['ranklimit'] =$v['rankNum'];
            $data[$k]['props'] = [];
            foreach ($v['prize'] as $val){
                $data[$k]['props'][] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
        }
        return $data;
    }

    /**
     * Notes:获取排行榜当前进度条已领过阶段奖励的进度值
     * User: wsc
     * Time: 2020/8/13 15:05
     * @param $uid
     * @param $aid
     * @param $stage  -阶段id
     * @return int
     */
    public function getRankProgressNum($uid,$aid,$stage){
//        $reward = $this->getRankStageRewardConf($uid,$aid,0);
        $reward = $this->getBindActivityRewardCfg($uid,$aid);
        $progressBarId =$reward['list'][$stage]['progressBarId'];//进度条
        $skey = okeys::userActivityStageRate($uid,$aid);
        $num = oo::commonOprRedis('activity')->hIncrBy($skey,'progress_'.$progressBarId,0);//进度条值
        return intval($num);
    }

    /**
     * Notes:更具排名获取奖励内容
     * User: wsc
     * Time: 2020/8/6 16:15
     * @param $uid
     * @param $aid
     * @param $limit
     * @return array
     */
    public function getRankRewardByLimit($uid,$aid,$limit){
        $data = [];
//        $rewardConf = $this->getActReward($aid)['extra_reward'];//奖励配置;
        $rewardConf = $this->getRankEndRewardConf($aid,$uid);
//        array_multisort(array_column($rewardConf,'rankNum'),SORT_ASC,$rewardConf);
        $endReward = end($rewardConf);//安慰奖
        array_pop($rewardConf);
        foreach ($rewardConf as $k=>$v){
            if($v['ranklimit']>=$limit&&!empty($v['props'])){
                $data = $v['props'];
                break;
            }
        }
        if(empty($data)){//安慰奖励
            if(!empty($endReward['props'])){
                $data = $endReward['props'];
            }
        }
        return $data;
    }

    /**
     * Notes:获取排行榜数据
     * User: wsc
     * Time: 2020/8/3 9:30
     * @param $uid
     * @param $aid
     * @return array
     */
    public function getRankData($uid,$aid){
        $rankList = [];
        $roomId = $this->getUserRankRoomId($uid,$aid);
        if($roomId){
            $key = okeys::activityUserRankList($aid,$roomId);
            $list = oo::commonOprRedis('activity')->zRevRange($key,0,-1,true);
            $limit =1;
            foreach ($list as $k=>$v){
                $info = oo::commonOprModel('member')->getUserInfo($k);
                $arr = [
                    "rankId"=>$limit,
                    "uid"   =>$k,
                    "nick"  =>oo::commonOprModel('member')->getUserFirstName($info['nick']),
                    "s_picture"=>$info['s_picture'],
                    "vip"   =>$info['vip'],
                    "vipLv" =>$info['vipLv'],
                    "vipExpire"=>$info['vipExpire'],
                    "avatar"   =>$info['avatar'],
                    "curRankNum"=>$v
                ];
                $rankList[$limit] = $arr;
                $limit++;
            }
        }
        return array_values($rankList);
    }

    /**
     * Notes:获取用户当前排行数据
     * User: wsc
     * Time: 2020/8/3 10:25
     * @param $uid
     * @param $aid
     * @return mixed
     */
    public function getUserRankData($uid,$aid,$type = "rank"){
        $roomId = $this->getUserRankRoomId($uid,$aid);
        $key = okeys::activityUserRankList($aid,$roomId);
        $curRankId = oo::commonOprRedis('activity')->zRevRank($key,$uid);
        $userData['aid']    = $aid;//活动号
        $userData['roomId'] = $roomId;//当前房间号
        $userData['curRankId']  = $curRankId===false?0:intval($curRankId)+1;
        $userData['curRankNum'] = intval(oo::commonOprRedis('activity')->zScore($key,$uid));
        if($type == "rank"){
            $progress = $this->getUserActStageInfo($uid,$aid);
            $userData['curRankProgressNum'] = $this->getRankProgressNum($uid,$aid,$progress['stage'])+$progress['rate'];//当前进度条值
            $userData['curRankProgressId']  = $progress['stage']-1;//当前进度阶段
        }else{
            $userData['curRankProgressNum'] = 0;
            $userData['curRankProgressId'] = 0;
        }
        $userData['isRankReward'] = intval(oo::commonOprRedis('activity')->get(okeys::activityRankRewardStatus($uid,$aid)));//是否领过当前活动最终排行奖励
        //===此部分逻辑逐渐移除===(冗余限制扩展,容易配置错误)
        $userData['cardData'] =$this->getRankCard($uid,$aid,true);
        //=======================

        return $userData;
    }

    /**
     * Notes:获取用户房间id
     * User: wsc
     * Time: 2020/8/3 9:30
     * @param $uid
     * @param $aid
     * @return int
     */
    public function getUserRankRoomId($uid,$aid){
        $roomId  = oo::commonOprRedis('activity')->hGet(okeys::activityUserRankBindRoomId($aid),$uid);
        return intval($roomId);
    }

    /**
     * 排行榜活动动态奖励卡片
     * 2.卡片为金卡；
     * 3.玩家未获得的卡片；（如果玩家已获得符合条件所有金卡，则取获得数量最少的卡片）
     * 4.解锁等级最高的卡片；（如果解锁等级相同，则取卡片ID排前的卡片）
     * 20200922修改为解锁等级最低的卡片
     * @return array
     * Created by: Hss
     * Created on: 2020/7/15 14:59
     */
    public function getRankCard($uid,$aid,$isset=false){
        $ckey = okeys::activityUserRankCard($uid,$aid);
        $cardData =  oo::commonOprRedis('Activity')->get($ckey);
        if(empty($cardData)&&$isset){
            $uckey = okeys::userCacheShowCardList($uid);//即将获得的卡片id 列表
            $userShowCardList = oo::commonOprRedis('activity')->sMembers($uckey);
            //grade 2 金卡
//            $unlockCard = oo::commonOprModel('card')->getUnlockCard($uid);
            $assetsInfo  = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $unlockCard = oo::commonOprModel('card')->getUnlockCardByLevelId($assetsInfo['levelId']);
//            krsort($unlockCard);//20200922修改为解锁等级最低的卡片
            $userCardInfo = oo::commonOprModel('card')->getUserCardInfo($uid);
            $userCardTemp = array_keys($userCardInfo['ciid']);

            $level = oo::commonOprModel('member')->getUserLevel($uid);
            $levelId = intval($level['levelId']);

            $reward = [];
            $isNew = true;
            foreach($unlockCard as $key => $row){
                if($row['grade'] == 2 && $row['ci_lockRank'] <= $levelId && !in_array($row['ciid'],$userCardTemp)&&!in_array($row['ciid'],$userShowCardList)){
                    $reward = $row;
                    break;
                }
            }
            if(empty($reward)){
                $gradeCardTemp = [];
                $unlockCardTemp = [];
                foreach ($unlockCard as $key => $val){
                    $unlockCardTemp[$val['ciid']] = $val;
                }
                foreach ($userCardTemp as $ciid){
                    if($unlockCardTemp[$ciid]['grade'] == 2){
                        $gradeCardTemp[$ciid] = $userCardInfo['ciid'][$ciid];
                    }
                }
                if(count($gradeCardTemp)>count($userShowCardList)){//随机卡片中的卡片数多于已展示的卡片数,则去重
                    foreach ($userShowCardList as $ccid){
                        unset($gradeCardTemp[$ccid]);
                    }
                }
                asort($gradeCardTemp);
                $minCiid = array_slice($gradeCardTemp,0,1,true);
                $reward = $unlockCardTemp[key($minCiid)];
                $isNew = false;
            }
            $cardData = ['id'=>$reward['ciid'],'isNew'=>$isNew];
            $ainfo = $this->getActivity($aid);
            oo::commonOprRedis('Activity')->set($ckey,json_encode($cardData));
            $ts = $ainfo['end_time']-time()+60;
            if($ts>86400*7){//最多7天
                $ts = 86400*7;
            }
            $ts2 = intval(oo::commonOprRedis('activity')->ttl(okeys::userSpecialAct($uid,$ainfo['type'])));//临时道具活动
            $ts=$ts2>0?$ts2:oo::redisRandomExpire($ts);
            oo::commonOprRedis('Activity')->expire($ckey,$ts);
            oo::commonOprRedis('Activity')->sadd($uckey,$reward['ciid']);//已展示的卡片列表新增
            oo::commonOprRedis('Activity')->expire($uckey,$ts);
        }else{
            $cardData = !empty($cardData)?json_decode($cardData,true):[];
        }

        return $cardData;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    //>>>>>>>>>>>>>>>>>>>>>>通行证>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * 排行榜活动当前经验值
     * @param $aid
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/10/21 14:34
     */
    public function getTrafficPermitCurNum($aid,$uid){
        //先判断新key是否存在
        if(oo::commonOprRedis('activity')->hExists(okeys::TrafficPermitUser($aid, $uid), 'exp')){
            return intval(oo::commonOprRedis('activity')->hGet(okeys::TrafficPermitUser($aid, $uid),'exp'));
        }
        //老数据处理，后期业务可删除
        $key = okeys::TrafficPermitCurNum($aid);
        $num = intval(oo::commonOprRedis('activity')->hGet($key,$uid));
        if($num){
            $rewarded = oo::commonOprRedis('activity')->hMGet(okeys::TrafficPermitReward($aid),['special_' .$uid, 'normal_'.$uid]);
            $arr = ['exp' => $num];
            $key2 = okeys::TrafficPermitUser($aid, $uid);
            if($rewarded['special_' .$uid] !== false){
                $arr['receive_special'] = $rewarded['special_' .$uid];
            }
            if($rewarded['normal_' .$uid] !== false){
                $arr['receive_normal'] = $rewarded['normal_' .$uid];
            }
            oo::commonOprRedis('activity')->hMset($key2, $arr);
            $actData = oo::commonOprModel('activitynew')->getActivity($aid);
            if(empty($actData)){
                oo::commonOprRedis('activity')->expire($key2, 7 * 24 * 3600);
            } else{
                $expireAt = $actData['end_time'] > $actData['reward_time'] ? $actData['end_time'] : $actData['reward_time'];
                oo::commonOprRedis('activity')->expireAt($key2, $expireAt);
            }
        }
        return $num;
    }

    /**
     * 增加通行证经验值统一入口
     * @param int $aid
     * @param int $uid
     * @param int $num
     * @return int
     */
    public function addTrafficPermitBasicNum($aid,$uid, $num){
        $key = okeys::GamePassInfo($aid, $uid);
        return intval(oo::commonOprRedis('activity')->hIncrBy($key, 'exp', $num));
    }

    /**
     * 获取当前已领奖记录
     * @param $aid
     * @param $uid
     * @param $type
     * @return array
     * Created by: Owen
     * Created on: 2020/10/21 14:38
     */
    public function getTrafficPermitRewarded($aid,$uid,$type){
        $key = okeys::TrafficPermitUser($aid, $uid);
        $hkey = "{$type}_{$uid}";
        $res = oo::commonOprRedis('activity')->hExists($key,'receive_'.$type);
        if($res){
            $rewarded = oo::commonOprRedis('activity')->hGet($key,'receive_'.$type);
        }else{
            $rewarded = oo::commonOprRedis('activity')->hGet(okeys::TrafficPermitReward($aid),$hkey);
//            $arr['receive_special'] = $rewarded?$rewarded['special_' .$uid]:'';
            $arr['receive_'.$type] = $rewarded ? $rewarded:'';
            oo::commonOprRedis('activity')->hMset($key, $arr);
            $actData = oo::commonOprModel('activitynew')->getActivity($aid);
            if(empty($actData)){
                oo::commonOprRedis('activity')->expire($key, 31 * 24 * 3600);
            } else{
                $expireAt = $actData['end_time'] > $actData['reward_time'] ? $actData['end_time'] : $actData['reward_time'];
                oo::commonOprRedis('activity')->expireAt($key, $expireAt);
            }
        }
//        //先取新key
//        if(oo::commonOprRedis('activity')->exists(okeys::TrafficPermitUser($aid, $uid))){
//            $rewarded = oo::commonOprRedis('activity')->hGet(okeys::TrafficPermitUser($aid, $uid),'receive_'.$type);
//        } else {
//            $this->getTrafficPermitCurNum($aid, $uid); //先通过查询接口获取一次,从老数据导入新key
//            $rewarded = oo::commonOprRedis('activity')->hGet(okeys::TrafficPermitUser($aid, $uid),'receive_'.$type);
//        }

        return funs::ArrayFilter(explode(',',$rewarded??""));
    }

    /**
     * 设置已领奖记录
     * @param $aid
     * @param $uid
     * @param $type
     * @param $levelId
     * @return bool
     * Created by: Owen
     * Created on: 2020/10/21 14:38
     */
    public function setTrafficPermitRewarded($aid,$uid,$type,$levelId){
        $curRewarded = $this->getTrafficPermitRewarded($aid,$uid,$type);
        $curRewarded[] = $levelId;

        $curRewarded = implode(',',array_unique(funs::ArrayFilter($curRewarded)));
        return oo::commonOprRedis('activity')->hSet(okeys::TrafficPermitUser($aid, $uid), 'receive_'.$type, $curRewarded);
    }

    /**
     * 一键设置领取通行证奖励等级
     * @param int $aid
     * @param int $uid
     * @param int $type 领取类型
     * @param array $levelIds
     * @param return bool
     */
    public function setAllTrafficPermitRewarded($aid,$uid,$type,$levelIds){
        $curRewarded = $this->getTrafficPermitRewarded($aid,$uid,$type);
        $curRewarded = array_merge($curRewarded, $levelIds);
        $curRewarded = implode(',',array_unique(funs::ArrayFilter($curRewarded)));
        return oo::commonOprRedis('activity')->hSet(okeys::TrafficPermitUser($aid, $uid), 'receive_'.$type, $curRewarded);
    }

    /**
     * 获取通行证当前任务数量
     * @param $aid
     * @param $uid
     * @param $taskId
     * @return int
     * Created by: Owen
     * Created on: 2020/10/21 20:34
     */
    public function getTrafficPermitTaskCurNum($aid,$uid,$taskId){
        $key = okeys::TrafficPermitUserTask($aid, $uid);
        $num = intval(oo::commonOprRedis('activity')->hGet($key, $taskId));
        return $num;
//        if(oo::commonOprRedis('activity')->exists($key)){
//            $num = intval(oo::commonOprRedis('activity')->hGet($key, $taskId));
//            if($num){
//                return $num;
//            }
//            $num = intval(oo::commonOprRedis('activity')->hGet(okeys::TrafficPermitTaskCurNum($aid),"{$uid}-{$taskId}"));
//            if($num){
//                oo::commonOprRedis('activity')->hSet($key, "{$uid}-{$taskId}", $num);
//            }
//            return $num;
//        }
//        $num = intval(oo::commonOprRedis('activity')->hGet(okeys::TrafficPermitTaskCurNum($aid),"{$uid}-{$taskId}"));
//        if($num){
//            oo::commonOprRedis('activity')->hSet($key, "{$uid}-{$taskId}", $num);
//            $actData = oo::commonOprModel('activitynew')->getActivity($aid);
//            if(empty($actData)){
//                oo::commonOprRedis('activity')->expire($key, 7 * 24 * 3600);
//            }else{
//                $expireAt = $actData['end_time'] > $actData['reward_time'] ? $actData['end_time'] : $actData['reward_time'];
//                oo::commonOprRedis('activity')->expireAt($key, $expireAt);
//            }
//        }
        return $num;

    }

    /**
     * 增加通行证当前任务数量
     * @param $aid
     * @param $uid
     * @param $taskId
     * @param $num
     * @return int
     * Created by: Owen
     * Created on: 2020/10/21 20:34
     */
    public function addTrafficPermitTaskCurNum($aid,$uid,$taskId,$num){
        $key = okeys::TrafficPermitUserTask($aid, $uid);
//        if(oo::commonOprRedis('activity')->exists($key)){
        $ret =  intval(oo::commonOprRedis('activity')->hIncrBy($key,$taskId,$num));
        oo::commonOprRedis('activity')->expire($key,oo::todayDeadline());
        return $ret;
//        }

//        $this->getTrafficPermitTaskCurNum($aid, $uid, $taskId); //先获取一次值，从老数据导入新key
//        $ret = intval(oo::commonOprRedis('activity')->hIncrBy($key,$taskId,$num));
//        if(oo::commonOprRedis('activity')->ttl($key) == -1){
//            $actData = oo::commonOprModel('activitynew')->getActivity($aid);
//            if(empty($actData)){
//                oo::commonOprRedis('activity')->expire($key, 7 * 24 * 3600);
//            } else{
//                $expireAt = $actData['end_time'] > $actData['reward_time'] ? $actData['end_time'] : $actData['reward_time'];
//                oo::commonOprRedis('activity')->expireAt($key, $expireAt);
//            }
//        }

        return $ret;
    }

    /**
     * 通行证活动奖励配置
     * @param $aid
     * @param $uid
     * @param $dataType
     * @param $taskArr
     * @return array
     * Created by: Owen
     * Created on: 2020/10/21 15:10
     */
    public function getTrafficPermitRewardConf($aid,$uid,$dataType = "reward",$taskArr = []){
        $data  = [];
        $rewardConf = $this->getActReward($aid);//奖励配置
        if($dataType == "reward"){
            $bet = $this->getCoinRewardByTypeAndLevel('rank',oo::commonOprModel('member')->getUserLevel($uid)['levelId']);
            $reward = $rewardConf['reward']??[];
            foreach ($reward as $k=>$v){
                $data[$k]['level'] = $v['levelId'];
                $data[$k]['max']   = $v['max'];
                $data[$k]['isGrandPrize'] = $v['isGrandPrize'];
                $data[$k] = array_merge($data[$k],$this->makeTrafficPermitRewardConf($uid,$aid,$v,$bet));
            }
        }else if($dataType == "task"){
            $task = [];
            if(date("Ymd")%2){
                $task = $taskArr;
            }
            if(empty($task)){
                $task = $rewardConf['extra_reward'];
            }
            foreach ($task as $key=>$row){
                if($row['type'] == 11 && !oo::compareVersion(oo::commonOprModel('user')->getUserVersion($uid),'1.7.6')){
                    continue;
                }
                $temp = $row;
                $temp['curTaskNum'] = $this->getTrafficPermitTaskCurNum($aid,$uid,$row['type']);
                $data[] = $temp;
            }
        }
        return $data;
    }

    /**
     * 构建通行证奖励
     * @param $uid
     * @param $aid
     * @param $reward
     * @param $bet
     * Created by: Owen
     * Created on: 2021/3/8 11:21
     */
    public function makeTrafficPermitRewardConf($uid,$aid,$reward,$bet){
        $ret = [];
        foreach (['normal'=>"prize",'special'=>'specialPrize'] as $kType=>$type){
            if(empty($reward[$type])){
                $ret[$kType] = [];
                continue;
            }
            foreach ($reward[$type] as $val){
                $ret[$kType][] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
        }
        return $ret;
    }

    /**
     * 领取通行证活动奖励
     * @param $uid
     * @param $type
     * @param $levelId
     * @return string
     * Created by: Owen
     * Created on: 2020/10/21 14:32
     */
    public function getTrafficPermitReward($uid,$levelId,$oType){
        $aid = $this->activityLock($uid,"traffic_permit");
        if(!$aid){
            return oo::response(-2,[],"未参加活动");
        }
        $type = $oType==1?"normal":"special";
        if($type == "special"){
            if(!$this->getBuyTrafficPermitStatus($aid,$uid)){
                return oo::response(-6,[],"未购买通行证");
            }
        }
        $rewarded = $this->getTrafficPermitRewarded($aid,$uid,$type);
        if(in_array($levelId,$rewarded)){
            return oo::response(-3,[],"已领取过奖励");
        }
        $config = $this->getTrafficPermitRewardConf($aid,$uid);//奖励配置
        $rewardConfig = array_column($config,null,"level");
        $reward = $rewardConfig[$levelId];
        $curNum = $this->getTrafficPermitCurNum($aid,$uid);
        if(empty($reward)){
            $maxLevel  = max(array_column($rewardConfig,"level"));
            if($levelId<= $maxLevel){
                return oo::response(-4,[],"奖励异常");
            }
            $maxExp    = max(array_column($rewardConfig,"max"));
            $actData   = $this->getActivity($aid);
            $extraData = json_decode($actData['extraData'],true);
            $actionMaxExp = (($levelId - $maxLevel) * $extraData['maxLevelExpGap']) + $maxExp;
            if($curNum < $actionMaxExp){
                return oo::response(-5,[],"经验未达标");
            }
            $reward= $this->makeTrafficPermitRewardConf($uid,$aid,$extraData['maxReward'],$this->getCoinRewardByTypeAndLevel('rank',oo::commonOprModel('member')->getUserLevel($uid)['levelId']));
        }else{
            if($curNum < $reward['max']){
                return oo::response(-5,[],"经验未达标");
            }
        }
        $props = $reward[$type];
        foreach ($props as $k => $v) {
            $ret = oo::commonOprModel('member')->sendReward($uid, $v['propsId'], $v['num'],217, "活动:通行证:{$aid}:{$levelId}",$v['value'],$v);
            if(in_array($v['propsId'],[13,18,19,20,21,29,30])){
                $props[$k]['value'] = $ret;
            }
            oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("PROPS-{$type}"),$v['propsId'],$v['num']);
            if($v['propsId']==15){
                $maxSpins = intval(oo::commonOprModel('notice')->getAgesCfg('getMaxSpins')['maxSpins']);
                if($v['num']>=$maxSpins){
                    $sceneLangArr = ['TW'=> "瘋狂通行證", 'ZH'=> "疯狂通行证", 'FR'=> "Crazy Pass", 'DE'=> "Verrückten Pass", 'EN'=> "Crazy Pass"];
                    $openLevelId = intval(oo::commonOprModel('readconfig')->getCon('Game','openLevelIdHorseRace'));//跑马灯起始等级
                    $filter =["minLevel"=>$openLevelId];
                    oo::async()->add('oo::commonOprModel("notice")->sendNoticeMsg',[$uid,"getMaxSpins",[intval($v['num']),$sceneLangArr],$filter]);//获得大体力卡跑马灯消息
                }
            }
        }
        $this->setTrafficPermitRewarded($aid,$uid,$type,$levelId);
        $eventData = oo::commonOprModel('ta')->getPropsSSEventData($props);
        oo::commonOprModel('ta')->setEventData($uid,"activity_pass_reward",[
            "activity_pass_reward_type"=>$oType,
            "activity_pass_reward_spin"=>$eventData['reward_spin'],
            "activity_pass_reward_coin"=>$eventData['reward_coin'],
            "activity_pass_reward_petfood"=>$eventData['reward_petfood'],
            "activity_pass_reward_petexp"=>$eventData['reward_petexp'],
            "activity_pass_reward_chest_list"=>$eventData['reward_chest_list'],
            "activity_pass_reward_activity"=>$eventData['reward_activity'],
            "activity_pass_reward_activity_time"=>$eventData['reward_activity_time'],
            "activity_pass_reward_card_list"=>$eventData['reward_card_list'],
            "activity_pass_reward_card_joker"=>$eventData['reward_card_joker'],
        ]);
        return oo::response(1,$props,"领奖成功");
    }

    /**
     * 获取一键领取通行证可获得的奖励信息
     * @param int $aid
     * @param int $uid
     * @param string $type
     * @return array
     */
    public function getAlllTrafficPermitRewardData($aid, $uid, $type) {
        $rewarded = $this->getTrafficPermitRewarded($aid,$uid,$type);
        $config = $this->getTrafficPermitRewardConf($aid,$uid);//奖励配置
        $rewardConfig = array_column($config,null,"level");
        if(empty($rewardConfig)){
            return ['rewards' => [], 'levelIds' => []];
        }
        $curNum = $this->getTrafficPermitCurNum($aid,$uid);
        $myMaxLevel = $rewarded ? max($rewarded) : 0;
        $levelIds = $rewards = [];
        foreach($config as $val){
            if(in_array($val['level'], $rewarded)){
                continue;
            }
            if($curNum < $val['max']) {
                break;
            }
            $rewards = $this->makeAllTrafficPermitRewards($rewards, $val[$type]);
            $levelIds[] = $val['level'];
            $myMaxLevel = $val['level'] > $myMaxLevel ? $val['level'] : $myMaxLevel;
        }

        //最大等级
        $maxLevel = max(array_column($rewardConfig,"level"));
        //领取到最大等级了,获取额外可领取奖励信息
        if($myMaxLevel >= $maxLevel){
            $maxExp    = max(array_column($rewardConfig,"max"));
            $actData   = $this->getActivity($aid);
            $extraData = json_decode($actData['extraData'],true);
            $remainNum = $curNum - $maxExp;
            $actionMaxExp = ($myMaxLevel - $maxLevel) * $extraData['maxLevelExpGap'] + $maxExp;
            $extraRate = (floor(($curNum - $actionMaxExp)/$extraData['maxLevelExpGap']));
            for($i = 1; $i <= $extraRate; $i++){
                $levelIds[] = $myMaxLevel + $i;
            }
            if($extraRate > 0){
                $reward = $this->makeTrafficPermitRewardConf($uid,$aid,$extraData['maxReward'],$this->getCoinRewardByTypeAndLevel('rank',oo::commonOprModel('member')->getUserLevel($uid)['levelId']));
                $rewards = $this->makeAllTrafficPermitRewards($rewards, $reward[$type], $extraRate);
            }
        }
        $eventData = oo::commonOprModel('ta')->getPropsSSEventData($rewards);
        oo::commonOprModel('ta')->setEventData($uid,"activity_pass_reward",[
            "activity_pass_reward_type"=>$type=="normal"?1:2,
            "activity_pass_reward_spin"=>$eventData['reward_spin'],
            "activity_pass_reward_coin"=>$eventData['reward_coin'],
            "activity_pass_reward_petfood"=>$eventData['reward_petfood'],
            "activity_pass_reward_petexp"=>$eventData['reward_petexp'],
            "activity_pass_reward_chest_list"=>$eventData['reward_chest_list'],
            "activity_pass_reward_activity"=>$eventData['reward_activity'],
            "activity_pass_reward_activity_time"=>$eventData['reward_activity_time'],
            "activity_pass_reward_card_list"=>$eventData['reward_card_list'],
            "activity_pass_reward_card_joker"=>$eventData['reward_card_joker'],
        ]);
        return ['rewards' => $rewards, 'levelIds' => $levelIds];
    }

    /**
     * 通行证一键领取数据组装
     * @param array $rewards
     * @param array $props
     * @param int $bet 倍数
     * @return array
     */
    private function makeAllTrafficPermitRewards(array $rewards = [], array $props = [], $ret = 1) {
        foreach($props as $v){
            if(!empty($v['value']) && !empty($v['value']['skin'])){
                $key = $v['propsId'].'_'.$v['value']['skin'];
            } else {
                $key = $v['propsId'];
            }
            $num = $ret > 1 ? $v['num'] * $ret : $v['num'];
            if(empty($rewards[$key])){
                $rewards[$key] = ['propsId' => $v['propsId'], 'num' => $num];
                !empty($v['skin']) && $rewards[$key]['skin'] = $v['skin'];
            } else {
                $rewards[$key]['num'] += $num;
            }
            if(empty($rewards[$key]['value']) && !empty($v['value'])){
                $rewards[$key]['value'] = $v['value'];
            }
        }
        return $rewards;
    }

    /**
     * 一键领取通行证奖励
     * @param int $uid
     * @param int $type
     * @return string
     */
    public function allTrafficPermitReward($uid){
        $aid = $this->activityLock($uid,"traffic_permit");
        if(!$aid){
            return oo::response(-2,[],"未参加活动");
        }
        //只有购买了通行证的人才能一键领取
        if(!$this->getBuyTrafficPermitStatus($aid,$uid)){
            return oo::response(-6,[],"未购买通行证");
        }
        $dataNormal = $this->getAlllTrafficPermitRewardData($aid, $uid, "normal");
        $dataSpecial = $this->getAlllTrafficPermitRewardData($aid, $uid, "special");
        if(empty($dataNormal['rewards']) && empty($dataSpecial['rewards'])){
            return oo::response(errorCode::CONDITION_NOT_RNOUGH); //没有奖励可领取
        }
        $rewardsTmp = $this->makeAllTrafficPermitRewards($dataSpecial['rewards'], $dataNormal['rewards']);

        //设置等级已领取
        $ret = empty($dataNormal['levelIds']) ? true : $this->setAllTrafficPermitRewarded($aid,$uid,"normal",$dataNormal['levelIds']);
        if($ret=== false){
            oo::logs()->debug3(['msg' => "update all traffic normal reward fail", 'data' => $dataNormal],'traffic_err.txt');
            return oo::response(errorCode::SYSTEM_ERROR); //系统错误
        }
        $ret = empty($dataSpecial['levelIds']) ? true : $this->setAllTrafficPermitRewarded($aid,$uid,"special",$dataSpecial['levelIds']);
        if($ret=== false){
            oo::logs()->debug3(['msg' => "update all traffic special reward fail", 'data' => $dataSpecial],'traffic_err.txt');
            return oo::response(errorCode::SYSTEM_ERROR); //系统错误
        }

        oo::logs()->debug3(['uid' => $uid, 'aid' => $aid, 'dataNormal' => $dataNormal, 'dataSpecial' => $dataSpecial],'alltrafficreward.txt');

        //加入统计打点数据
        foreach($dataNormal['rewards'] as $k => $v){
            oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("PROPS-normal"),$v['propsId'],$v['num']);
        }
        foreach($dataSpecial['rewards'] as $k => $v){
            oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("PROPS-special"),$v['propsId'],$v['num']);
        }

        //发奖
        $rewards = $rewardRes = [];
        foreach($rewardsTmp as $k => $v){
            if(empty($v['value']) || $v['num'] <= 1||in_array($v['propsId'],array_column(oo::commonOprModel('activitynew')->specialActTypeList,'propsId'))){
                $rewards[$k] = $v;
                continue;
            }
            for($i=0; $i < $v['num']; $i++){
                $rewards[$k.'_'.$i] = ['propsId' => $v['propsId'], 'num' => 1, 'value' => $v['value']];
            }
        }
        foreach ($rewards as $k => $v) {
            $ret = oo::commonOprModel('member')->sendReward($uid, $v['propsId'], $v['num'], 217, "活动:一键领取通行证:{$aid}",$v['value'],$v);
            if(in_array($v['propsId'],[13,18,19,20,21,29,30])){
                $v['value'] = $ret;
            }
            $rewardRes[] = $v;
            //oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("PROPS-{$type}"),$v['propsId'],$v['num']);
            if($v['propsId']==15){
                $maxSpins = intval(oo::commonOprModel('notice')->getAgesCfg('getMaxSpins')['maxSpins']);
                if($v['num']>=$maxSpins){
                    $sceneLangArr = ['TW'=> "瘋狂通行證", 'ZH'=> "疯狂通行证", 'FR'=> "Crazy Pass", 'DE'=> "Verrückten Pass", 'EN'=> "Crazy Pass"];
                    $openLevelId = intval(oo::commonOprModel('readconfig')->getCon('Game','openLevelIdHorseRace'));//跑马灯起始等级
                    $filter =["minLevel"=>$openLevelId];
                    oo::async()->add('oo::commonOprModel("notice")->sendNoticeMsg',[$uid,"getMaxSpins",[intval($v['num']),$sceneLangArr],$filter]);//获得大体力卡跑马灯消息
                }
            }
        }
        return oo::response(1,$rewardRes,"领奖成功");
    }

    /**
     * 通行证购买状态
     * @param $aid
     * @param $uid
     * @return bool|false
     * Created by: Owen
     * Created on: 2020/10/22 18:27
     */
    public function getBuyTrafficPermitStatus($aid,$uid){
        $cacheKey = okeys::BuyTrafficPermitStatus($aid,$uid);
        $cache    = oo::commonOprRedis('activity')->get($cacheKey);
        if($cache !== false){
            return $cache;
        }
        $tb  = otable::payment($uid);
        $sql = "SELECT * FROM {$tb} WHERE uid='{$uid}' AND gid='1770' AND buff='{$aid}'";
        $ret = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        $status = empty($ret)? 0 : 1;
        oo::commonOprRedis('activity')->setex($cacheKey,$status,5*24*60*60);
        return $status;
    }

    /**
     * Notes:跑马灯
     * User: wsc
     * Time: 2021/1/21 16:59
     * @param $uid
     */
    public function BuyTrafficPermitNotice($uid){
        $openLevelId = intval(oo::commonOprModel('readconfig')->getCon('Game','openLevelIdHorseRace'));//跑马灯起始等级
        $filter =["minLevel"=>$openLevelId];
        oo::commonOprModel("notice")->sendNoticeMsg($uid,"buyCrazyPass",[],$filter);
    }

    /**
     * 通知当前节点购买通行证消息
     */
    public function BuyTrafficPermitCircleNotice($openLevelId, $ret) {
        $allUid = oo::commonOprModel("workerman")->getCurAllUidList();
        $i = 0;
        foreach($allUid as $k => $uid){
            $property = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $levelId = intval($property['levelId']);
            if($levelId >= $openLevelId){
                $i++;
                if($i >= 200){
                    usleep(50000); //延迟
                    $i = 0;
                }
                //直接推送当前节点
                oo::commonOprModel('Workerman')->pushCur($uid,ocmd::$send['Announcement_Rec'],$ret);
            }
        }
    }

    /**
     * 通行证任务消耗体力任务
     * @param $uid
     * @param $addSpins
     * Created by: Owen
     * Created on: 2021/3/4 20:31
     */
    public function trafficPermitSpendSpinsTask($uid,$addSpins){
        $ttl = oo::commonOprRedis('activity')->ttl(okeys::TrafficPermitSpendSpins($uid));
        if($ttl > 0){
            $newCur = oo::commonOprRedis('activity')->incrBy(okeys::TrafficPermitSpendSpins($uid),$addSpins);
            $taskArr= [12 => 200, 13 => 800, 14 => 2000];
            foreach ($taskArr as $taskId=>$spins){
                if($newCur - $addSpins < $spins  && $newCur >= $spins){
                    $this->addTrafficPermitNum($uid,$taskId);
                }
            }
        }
    }

    /**
     * 追加通行证经验值
     * @param $uid
     * @param $taskId
     * @param $bet
     * @return bool|int
     * Created by: Owen
     * Created on: 2020/10/22 20:39
     */
    public function addTrafficPermitNum($uid,$taskId,$bet = 1){
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        if(!oo::compareVersion($version,'1.7.1')){
            return false;
        }
        $actInfo = $this->activityLock($uid,"traffic_permit",true);
        if(!$actInfo){
            return false;
        }
        $activityData   = $actInfo['activityData'];
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        if($userAssetsInfo['levelId'] < $activityData['openLv']){
            return false;
        }
        $taskList = array_column($activityData['taskConfig'],null,"type");
        $taskConfig = $taskList[$taskId];
        if(empty($taskConfig)){
            return false;
        }
        $curTaskNum = $this->getTrafficPermitTaskCurNum($activityData['aid'],$uid,$taskId);
        if($curTaskNum >= $taskConfig['num']){
            return false;
        }

        $remainTaskNum  = $taskConfig['num'] - $curTaskNum;
        $needAddTaskNum = min(1 * $bet,$remainTaskNum);

        $newTaskNum = $this->addTrafficPermitTaskCurNum($activityData['aid'],$uid,$taskId,$needAddTaskNum);

        /**
         * 通行证购买 统计--完成次数
         */
        if($this->getBuyTrafficPermitStatus($activityData['aid'],$uid)){
            oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("COMPLETE-1"),$taskId,$needAddTaskNum);
        }else{
            oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("COMPLETE-2"),$taskId,$needAddTaskNum);
        }
        if($newTaskNum >= $taskConfig['num']){
            /**
             * 通行证购买 统计--达标人数
             */
            oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("STANDARD"),$taskId,1);
        }
        /**
         * 通行证购买 统计--当天在玩人数
         */
        oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("PLAY"),$uid,1);

        $actionGetNum = $taskConfig['getNum'];
        /**
         * 判断通行证倍率活动
         */
        $actInfo = $this->activityLock($uid,"traffic_permit_bet",true);
        if($actInfo){
            $betAct = max(intval($actInfo['activityData']['config']["bet"]),1);
            $actionGetNum = $actionGetNum * min(5,$betAct);
        }
        $addNum = $actionGetNum * $needAddTaskNum;
        $newNum = $this->addTrafficPermitBasicNum($activityData['aid'], $uid, $addNum);
        oo::commonOprModel('currency')->log($uid,"trafficPermitExp","+",$addNum,$newNum,119,"通行证任务增加经验type:{$taskId}");//增加经验流水
        oo::commonOprModel('Workerman')->push($uid,ocmd::$send['trafficPermitAddNum'],['curNum'=>$newNum]);
        return $newNum;
    }

    /**
     * 道具加通行证经验
     * @param $uid
     * @param $num
     * @param int $rid
     * @param string $ext
     * @return bool|int
     * Created by: Owen
     * Created on: 2021/2/3 12:32
     */
    public function addTrafficPermitNumByProps($uid,$num,$rid = 0,$ext = ""){
        $aid = $this->activityLock($uid,"traffic_permit");
        if(!$aid){
            return 0;
        }

        //添加通行证经验值
        $newNum = $this->addTrafficPermitBasicNum($aid, $uid, $num);
        oo::commonOprModel('Workerman')->push($uid,ocmd::$send['trafficPermitAddNum'],['curNum'=>$newNum]);
        oo::commonOprModel('currency')->log($uid,"trafficPermitExp","+",$num,$newNum,119,"{$rid}-{$ext} => 发放经验 {$num} ，最新值：{$newNum}");
        return $newNum;
    }


    /**
     * 删除通行证每日任务
     * Created by: Owen
     * Created on: 2020/10/23 10:17
     */
    public function delUserTrafficPermitTaskNum(){
        $keyArr = [];
        $aidArr = self::getAllOnlineActivityByType('traffic_permit');
        foreach ($aidArr as $aid){
            $keyArr[] = okeys::TrafficPermitTaskCurNum($aid);
        }
        oo::commonOprRedis('activity')->delete($keyArr);
    }

    /**
     * 通行證升級
     * @param $uid
     * @param $num
     * @return string
     * Created by: Owen
     * Created on: 2020/10/27 19:31
     */
    public function buyTrafficPermitLevel($uid,$num){
        $actInfo = $this->activityLock($uid,"traffic_permit",true);
        if(!$actInfo){
            return oo::response(-2,[],"未参加活动");
        }
        $rewardConfig = array_column($actInfo['activityData']['rewardConfig'],null,"level");
        $curNum = $actInfo['userData']['curNum'];
        $level  = 0;
        $previousMax = 0;
        foreach ($rewardConfig as $row){
            if($row['max'] <= $curNum){
                $level = $row['level'];
                $previousMax = $row['max'];
            }else{
                break;
            }
        }
        /**
         * 通行证购买 统计--购买等级
         */
        oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("BUYLEVEL"),$level,1);
        $exceedNum = $curNum - $previousMax;
        $newLevel  = min($level + $num,max(array_keys($rewardConfig)));
        $actionAddNum = $rewardConfig[$newLevel]['max'] - $curNum;
        if($actionAddNum > 0){
            $actionLvNum = $newLevel - $level;
            if($actionLvNum == 0){
                $actionLvNum = 1;
            }
            $actionDiamondNum = $actionLvNum * $actInfo['activityData']['upLvDiamondNum'];
            $assetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            if($actionDiamondNum > $assetsInfo['diamond']){
                return oo::response(-3,[],"钻石不足");
            }
            //增加通行证经验值
            $newNum = $this->addTrafficPermitBasicNum($actInfo['activityData']['aid'],$uid,$actionAddNum + $exceedNum);
            oo::commonOprModel('member')->optProperty($uid,array('diamond'=>intval($actionDiamondNum)),'-',402,"购买通行证升级:当前等级 {$level}，最新等级 {$newLevel}");
            $actInfo['userData']['curNum'] = $newNum;
            oo::commonOprModel('ta')->setEventData($uid,"activity_pass_levelup",["activity_pass_levelup_before"=>$level,"activity_pass_levelup_after"=>$newLevel]);
            return oo::response(1,['userData'=>$actInfo['userData']]);
        }else{

            return oo::response(-3,[],"达到最大等级");
        }
    }

    /**
     * 通行證升級 -- 充值
     * @param $uid
     * @param $num
     * @return string
     * Created by: Owen
     * Created on: 2020/10/27 19:31
     */

    public function buyTrafficPermitLevelByPay($uid, $num = 1)
    {
        $actInfo = $this->activityLock($uid, "traffic_permit", true);
        if (!$actInfo) {
            return false;
        }

        $aid = $actInfo['activityData']['aid'];
        $curNum = $actInfo['userData']['curNum'];

        $levelConf = self::findPassRewardConfByLvRange($uid, $aid)['levels'] ?? [];
        if (empty($levelConf)) {
            return false;
        }

        $levelConf = array_column($levelConf, null, "levelId");

        $maxLevel = max(array_keys($levelConf));
        $level = 0;
        foreach ($levelConf as $row) {
            if ($row['max'] > $curNum) {
                break;
            }
            $level = $row['levelId'];
        }

        // 按配置升级
        $newLevel = $level + $num;
        if ($newLevel <= $maxLevel) {
            $addNum = max($levelConf[$newLevel]['max'] - $curNum, 0);
        } else {
            $addNum = max($levelConf[$maxLevel]['max'] - $curNum, 0);
            $addNum += $actInfo['activityData']['maxLevelExpGap'] * ($newLevel - $maxLevel);
        }
//        echo json_encode([$level, $num, $newLevel, $maxLevel, $curNum, $addNum]);die;
        $newNum = $this->addTrafficPermitBasicNum($aid, $uid, $addNum);
        oo::commonOprModel('currency')->log($uid, "trafficPermitExp", "+", $addNum, $newNum, 119, "在{$level},购买{$num}级,发放经验 {$addNum} ，最新值：{$newNum}");
        oo::commonOprModel('ta')->setEventData($uid, "activity_pass_levelup", ["activity_pass_levelup_before" => $level, "activity_pass_levelup_after" => $newLevel]);
        return [
            'curNum' => $newNum,
            'actionNum' => $addNum,
        ];
    }



    /**
     * 通行证购买 统计--购买量
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/11/6 17:31
     */
    public function buyTrafficPermitSta($uid){
        $actInfo = $this->activityLock($uid,"traffic_permit",true);
        if(!$actInfo){
            return oo::response(-2,[],"未参加活动");
        }
        $rewardConfig = array_column($actInfo['activityData']['rewardConfig'],null,"level");
        $curNum = $actInfo['userData']['curNum'];
        $level  = 0;
        foreach ($rewardConfig as $row){
            if($row['max'] <= $curNum){
                $level = $row['level'];
            }else{
                break;
            }
        }
        oo::commonOprRedis('Statistics')->hIncrBy(okeys::TrafficPermitSta("BUY"),$uid,$level);
    }

    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>宝藏探索>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * 入门奖励
     * @param $uid
     * @param bool $get
     * @return string
     * Created by: Owen
     * Created on: 2020/7/28 16:50
     */
    public function getTreasureGift($uid,$get = false){
        $aid = $this->activityLock($uid,"treasure");
        if(!$aid){
            return oo::response(-2,[],'活动未开启');
        }
        if(!$get){
//            if(oo::commonOprRedis('Activity')->hGet(okeys::TreasureTaskGift($aid),$uid)){
//                return oo::response(-2,"奖励已领取");
//            }
            if($this->getUserTreasureCacheLog($aid,$uid,"GiftReceiveStatus")){
                return oo::response(-2,"奖励已领取");
            }
        }
        $userTreasureData = self::getUserTreasureData($aid,$uid);
        $rewardConfig = array_column($userTreasureData['config'],NULL,'id');
        $reward = $rewardConfig[1];
        if($get){
            return $reward['bet'][0];
        }
        oo::commonOprModel('member')->setUserStealProtect($uid,300);
        oo::commonOprModel('member')->optProperty($uid,['money'=>$reward['bet'][0]],"+",215,"宝藏活动-入门奖励");
//        oo::commonOprRedis('Activity')->hSet(okeys::TreasureTaskGift($aid),$uid,1);
        $this->setUserTreasureCacheLog($aid,$uid,"GiftReceiveStatus",1);
        return oo::response(1);
    }

    /**
     * 宝藏活动用户信息
     * @param $aid
     * @param $uid
     * @param $origData
     * @return array
     * Created by: Owen
     * Created on: 2020/7/27 18:55
     */
    public function getUserTreasureData($aid,$uid,$origData = false){
        $userAssetsInfo  = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $levelId         = $userAssetsInfo['levelId'];
        $treasureCollect = $this->getCoinRewardByTypeAndLevel("treasureCollect",$levelId);
        $treasureReward  = $this->getCoinRewardByTypeAndLevel("treasureReward",$levelId);
        $treasureBet     = $this->getCoinRewardByTypeAndLevel("treasureBet",$levelId);
        $rewardConfig    = $this->getActReward($aid)['reward'];
        $config = [];
        foreach ($rewardConfig as $key=>$row){
            $config[$key]['id'] = $row['id'];
            if($row['taskType'] != 1){
                $config[$key]['target'] = $row['target'] * $treasureCollect;
            }else{
                $config[$key]['target'] = $row['target'];
            }
            $temp = $row['bet'];
            foreach ($temp as $b=>$bet){
                $temp[$b] = $bet * $treasureBet;
            }
            $config[$key]['bet']      = $temp;
            $config[$key]['taskType'] = $row['taskType'];
            foreach($row['prize'] as $k => $val){
                $config[$key]['props'][] =$this->getFormattingProps($uid,$aid,$val,$treasureReward);
            }
        }
        if($origData){
            foreach ($config as $key=>$row){
                $temp = $config[$key]['props'];
                if(empty($temp)){
                    $config[$key]['props'] = [];continue;
                }
                array_multisort(array_column($temp,'propsId'),SORT_DESC,$temp);
                $config[$key]['props'] = $temp;
            }

        }
        $betConfig  = oo::commonOprModel('config')->getTreasureProConfig($levelId);
        $reward     = $betConfig['pro'];
        foreach ($reward as $key=>$row){
            $temp = $row;
            unset($temp['pro']);
            $reward[$key] = $temp;
        }
        $bet = array_column($betConfig['superBet'],'bet');
        rsort($bet);
        return [
            'config' => $config,
            'bet'    => $bet,
            'reward' => $reward,
        ];
    }

    /**
     * 更新宝藏活动任务数量
     * @param $aid
     * @param $uid
     * @param $num
     * @param $from
     * @return mixed
     * Created by: Owen
     * Created on: 2020/7/27 20:04
     */
    public function updateTreasureTaskNum($aid,$uid,$num,$from){
        $taskType = self::getUserTreasureCurTaskType($aid,$uid);
        if($taskType == 1){
//            $newNum = oo::commonOprRedis('User')->hIncrBy(okeys::TreasureTaskNum($aid),$uid,1);
            $newNum = $this->addUserTreasureCacheLog($aid,$uid,"TaskOverLimit",1);
        }else {
            if ($taskType == 2) {
//                $newNum = oo::commonOprRedis('User')->hIncrBy(okeys::TreasureTaskNum($aid), $uid, $num);
                $newNum = $this->addUserTreasureCacheLog($aid,$uid,"TaskOverLimit",$num);
            }else if ($taskType == 3 && $from == 1) {
//                $newNum = oo::commonOprRedis('User')->hIncrBy(okeys::TreasureTaskNum($aid), $uid, $num);
                $newNum = $this->addUserTreasureCacheLog($aid,$uid,"TaskOverLimit",$num);
            }else{
//                $newNum = intval(oo::commonOprRedis('User')->hGet(okeys::TreasureTaskNum($aid),$uid));
                $newNum = intval($this->getUserTreasureCacheLog($aid,$uid,"TaskOverLimit"));
            }
        }
        return [
            'taskId' => $this->getUserTreasureCurTaskId($aid,$uid),
            'taskNum'=> $newNum,
        ];
    }

    /**
     * 领取宝藏奖励
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/7/27 20:15
     */
    public function getTreasureTaskReward($uid){
        $aid = $this->activityLock($uid,"treasure");
        if(!$aid){
            return oo::response(-2,[],'活动未开启');
        }
        $userTreasureData = self::getUserTreasureData($aid,$uid);
        $taskId = $this->getUserTreasureCurTaskId($aid,$uid);
//        $taskNum= intval(oo::commonOprRedis('User')->hGet(okeys::TreasureTaskNum($aid),$uid));
        $taskNum = intval($this->getUserTreasureCacheLog($aid,$uid,"TaskOverLimit"));
        $rewardConfig = array_column($userTreasureData['config'],NULL,'id');
        $reward = $rewardConfig[$taskId];
        if($reward['target'] > $taskNum){
            return oo::response(-2,[],'目标未达标');
        }
//        oo::commonOprRedis('Activity')->hDel(okeys::TreasureTaskNum($aid),$uid);
        $this->setUserTreasureCacheLog($aid,$uid,"TaskOverLimit",0);
//        $newId = oo::commonOprRedis('User')->hIncrBy(okeys::TreasureTaskId($aid),$uid,$taskId==1?2:1);
        $newId = $this->addUserTreasureCacheLog($aid,$uid,"TaskCurTaskId",1);
        $cardData = $rData = [];
        foreach ($reward['props'] as $k=>$v){
            $one =["propsId"=>$v['propsId'],"num"=>$v['num']];
            $ret = oo::commonOprModel('member')->sendReward($uid, $v['propsId'], $v['num'], 213, "活动:宝藏活动(新):{$aid},关卡{$taskId}", $v['value'],$v);
            if(in_array($v['propsId'],[18,19,20,21,29,30])){
                $one['value'] = $ret;
            }
            $rData[] = $one;
            if($v['propsId'] == 13) {
                $cardData[] = is_array($ret) ? $ret[0] : $ret;
            }
            oo::commonOprModel('statistics')->treasureRewardSta($v['propsId'],$taskId,$v['num']);//宝藏探索产出消耗统计
        }
//        oo::commonOprRedis('Activity')->hDel(okeys::TreasureCurTaskType($aid),$uid);
        $newTaskType = $this->getUserTreasureCurTaskType($aid,$uid,true);
        $this->setUserTreasureCacheLog($aid,$uid,"TaskCurType",$newTaskType);
        $data['curData'] = [
            'taskId' => $newId,
            'taskNum'=> 0,
            'cardData'=>!empty($cardData)?$cardData:null,
            'reward'=>isset($rData)?$rData:null
        ];

        $eventData = oo::commonOprModel('ta')->getPropsSSEventData($rData);
        oo::commonOprModel('ta')->setEventData($uid,"activity_coinslot_quest",[
            "activity_coinslot_quest"=>$taskId,
            "activity_coinslot_quest_reward_spin"=>$eventData['reward_spin'],
            "activity_coinslot_quest_reward_coin"=>$eventData['reward_coin'],
            "activity_coinslot_quest_reward_petfood"=>$eventData['reward_petfood'],
            "activity_coinslot_quest_reward_petexp"=>$eventData['reward_petexp'],
            "activity_coinslot_quest_reward_chest_list"=>$eventData['reward_chest_list'],
            "activity_coinslot_quest_reward_activity"=>$eventData['reward_activity'],
            "activity_coinslot_quest_reward_activity_time"=>$eventData['reward_activity_time'],
            "activity_coinslot_quest_reward_card_list"=>$eventData['reward_card_list'],
            "activity_coinslot_quest_reward_card_joker"=>$eventData['reward_card_joker'],
        ]);

        return oo::response(1,$data);
    }

    /**
     * 获取偷打保护到期时间key
     */
    public function getEndproteTimeKey($uid, $date = '') {
        $date = empty($date) ? date("Ymd",time()) : $date;
        //return akey::proteTimeKey($date);
        return akey::proteTimeKey($date, $uid);
    }

    /**
     *  统一获取偷保护到期时间数据
     *  @param int $uid
     *  @return int
     */
    public function getEndproteTime($uid, $date = '') {
        $key = $this->getEndproteTimeKey($uid, $date);
        return intval(oo::commonOprRedis('server')->hGet($key, $uid));
    }

    /**
     * 统一设置偷保护到期时间数据
     * @param int $uid
     * @param string $date 如:20201204
     * @param int $ovTime timestamp
     */
    public function upEndproteTime($uid, $date = '', $ovTime) {
        $key = $this->getEndproteTimeKey($uid, $date);
        return oo::commonOprRedis('server')->hSet($key,$uid,$ovTime);
    }

    /**
     * 设置偷保护到期时间过期
     */
    public function upEndproteTimeExpire($uid, $date = '', $time) {
        $key = $this->getEndproteTimeKey($uid, $date);
        oo::commonOprRedis('server')->expireAt($key, oo::redisRandomExpire($time));
    }

    /**
     * 刷新宝藏活动保护时间
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/11/3 15:10
     */
    public function RefreshTreasureProtectTime($uid){
        $aid = $this->activityLock($uid,"treasure");
        if(!$aid){
            return oo::response(-2,[],'活动未开启');
        }
        if(oo::commonOprRedis('Activity')->delete(okeys::TreasureProtect($uid))){
            oo::commonOprModel('member')->setUserStealProtect($uid,300);
            $data['proteEndTs'] = $this->getEndproteTime($uid);
            return oo::response(1,$data);
        }
        return oo::response(-2);
    }

    /**
     * 宝藏活动结果
     * @param $uid
     * @param $id
     * @return array
     * Created by: Owen
     * Created on: 2020/7/28 14:43
     */
    public function getUserTreasureSlotResult($aid,$uid,$spend){
        $totalSpend= oo::commonOprRedis('Activity')->hGet(okeys::TreasureSpend($aid),"TOTAl_".$uid);
        $config    = $this->getActReward($aid);
        $reward    = array_column($config['reward'],null,"id");
        $taskId    = $this->getUserTreasureCurTaskId($aid,$uid);
        $frequency = $reward[$taskId]['frequency'];
//        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
//        $betConfig      = oo::commonOprModel('config')->getTreasureProConfig($userAssetsInfo['levelId'] ?? 1);
        $betConfig      = oo::commonOprModel('config')->getTreasureProConfigByTaskId($taskId );//根据任务层获取概率配置====(???)
        $superBet       = array_column($betConfig['superBet'],'pro');
        $betConfigPro   = $betConfig['pro'];
        if($totalSpend > $frequency){
            oo::commonOprRedis('Activity')->hIncrBy(okeys::TreasureSpend($aid),"TOTAl_".$uid,-$frequency);
            $bonus = oo::commonOprRedis('Activity')->hGet(okeys::TreasureSpend($aid),"BONUS_".$uid);
            $totalWeight = max(array_sum(array_column($betConfigPro,"pro")),1);
            $newBonus = $bonus - ($frequency * ($betConfigPro[0]['pro'] / $totalWeight));
            oo::commonOprRedis('Activity')->hSet(okeys::TreasureSpend($aid),"BONUS_".$uid,$newBonus);
            $p          = 0;
            if($newBonus/$spend != 0){
                $p = round($newBonus/$spend,2);
            }
            $fixCo      = $config['extra_reward']['fixCo'];
            array_multisort(array_column($fixCo,'pro'),SORT_DESC,$fixCo);
            $co           = $fixCo[0]['fix'];
            foreach ($fixCo as $row){
                if($row['pro'] >= $p ){
                    $co = $row['fix'];
                }else{
                    break;
                }
            }
            foreach ($betConfigPro as $key=>$row){
                if($row['id'] == 1){
                    $betConfigPro[$key]['pro'] = round($row['pro'] * $co,2);
                    break;
                }
            }
        }
        $pro            = array_column($betConfigPro,'pro');
        $proReward      = array_column($betConfigPro,null,'id');
        $rid  = oo::commonOprModel('slot')->get_rand($pro,true) + 1;
        $temp = $proReward[$rid];
        if($temp['bet'] == -1){
            $superRid    = oo::commonOprModel('slot')->get_rand($superBet,true);
            $superRid   += 1;
            $superReward = array_column($betConfig['superBet'],null,'id');
            $superTemp   = $superReward[$superRid];
            $temp['bet'] = $superTemp['bet'];
        }
        return [
            'id'   => time().rand(0,9),
            'rid'  => $rid,
            'bet'  => $temp['bet'],
        ];
    }

    /**
     * 获取宝藏活动用户当前任务
     * @param $aid
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/7/31 10:36
     */
    public function getUserTreasureCurTaskType($aid,$uid,$isNew=false){
//        $cacheKey = okeys::TreasureCurTaskType($aid);
//        $cache    = oo::commonOprRedis('Activity')->hGet($cacheKey,$uid);
//        if(empty($cache)){
//            $userTreasureData = self::getUserTreasureData($aid,$uid);
//            $taskId = $this->getUserTreasureCurTaskId($aid,$uid);
//            $rewardConfig = array_column($userTreasureData['config'],NULL,'id');
//            $reward = $rewardConfig[$taskId];
//            oo::commonOprRedis('Activity')->hSet($cacheKey,$uid,$reward['taskType']);
//            $cache = $reward['taskType'];
//        }
        $cache = $this->getUserTreasureCacheLog($aid,$uid,"TaskCurType");
        if(empty($cache)||$isNew){
            $userTreasureData = self::getUserTreasureData($aid,$uid);
            $taskId = $this->getUserTreasureCurTaskId($aid,$uid);
            $rewardConfig = array_column($userTreasureData['config'],NULL,'id');
            $reward = $rewardConfig[$taskId];
            $this->setUserTreasureCacheLog($aid,$uid,"TaskCurType",$reward['taskType']);
            $cache = $reward['taskType'];
        }
        return $cache;
    }

    /**
     * 获取宝藏活动用户当前任务ID
     * @param $aid
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2021/3/5 18:22
     */
    public function getUserTreasureCurTaskId($aid,$uid,$version = ''){
        //1.14版本使用任务分层id
//        $version = empty($version) ? '' : '2';
//        return max(oo::commonOprRedis('User')->hGet(okeys::TreasureTaskId($aid,$version),$uid),1);
        return $this->getUserTreasureCacheLog($aid,$uid,"TaskCurTaskId");
    }

    /**
     * 重整金币老虎机
     * @param $uid
     * @param $coins
     * @return string
     * Created by: Owen
     * Created on: 2020/12/31 14:27
     */
    public function treasureSlotReward($uid,$coins, $json = true){
        $coins = abs($coins);
        $aid = $this->activityLock($uid,"treasure");
        if(!$aid){
            return $json ? oo::response(-2,[],'活动未开启') : ['code'=> -2, 'msg' => '活动未开启'];
        }
        $assetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        if($coins > $assetsInfo['money']){
            return $json ? oo::response(-2,['id'=>0],'金币不足') : ['code' => -2, 'data' => ['id' => 0], 'msg' => '金币不足'];
        }
        $treasureBet = $this->getCoinRewardByTypeAndLevel("treasureBet",$assetsInfo['levelId']);
        $spend       = max(ceil($coins/$treasureBet),1);
        $result = $this->getUserTreasureSlotResult($aid,$uid,$spend);
        $id   = $result['id'];
        $rid  = $result["rid"];
        $getCoins    = $result["bet"] * $coins;
        $actionCoins = $getCoins - $coins;
        $actionType  = $actionCoins >= 0 ? "+" : "-";
        oo::commonOprModel('member')->optProperty($uid,['money'=>abs($actionCoins)],$actionType,214,"宝藏活动:(花费{$coins}),奖励倍率{$result["bet"]},摇奖ID:{$rid}");

        $proteEndTs = $this->getEndproteTime($uid);
        $ttl = $proteEndTs-time();
        if($getCoins > 0 ){
            oo::commonOprRedis('Activity')->setex(okeys::TreasureProtect($uid),1,180);
            if($ttl < 100){
                oo::commonOprModel('member')->setUserStealProtect($uid,300);
                $proteEndTs = time()+298;
            }
        }
        $newData = self::updateTreasureTaskNum($aid,$uid,$getCoins,$rid == 1 ? 1 : 2);
        $data['curData']    = $newData;
        $data['id']         = $id;
        $data['proteEndTs'] = $proteEndTs;//保护截至时间戳
        $data['preset']     = [$result];
        oo::commonOprModel('currency')->log($uid,"money","-",$coins,0,1003,$newData['taskId']);//发放消耗统计
        oo::commonOprModel('currency')->log($uid,"money","+",$getCoins,0,1010+$rid,$newData['taskId']);//宝藏统计
        oo::commonOprModel('currency')->participation($uid, 'treasure', 0); //宝藏活动参与率
        oo::commonOprRedis('Activity')->hIncrBy(okeys::TreasureSpend($aid),"TOTAl_".$uid,$spend);
        if($rid == 1){
            oo::commonOprRedis('Activity')->hIncrBy(okeys::TreasureSpend($aid),"BONUS_".$uid,$spend);
        }

        $userTreasureData = self::getUserTreasureData($aid,$uid);
        $taskId = $this->getUserTreasureCurTaskId($aid,$uid);
//        $taskNum= intval(oo::commonOprRedis('User')->hGet(okeys::TreasureTaskNum($aid),$uid));
        $taskNum = intval($this->getUserTreasureCacheLog($aid,$uid,"TaskOverLimit"));
        $rewardConfig = array_column($userTreasureData['config'],NULL,'id');
        $reward = $rewardConfig[$taskId];
        oo::commonOprModel('ta')->setEventData($uid,"activity_coinslot",[
            "activity_coinslot_bet"=>$spend,
            "activity_coinslot_coin_cost"=>$coins,
            "activity_coinslot_result"=>$rid,
            "activity_coinslot_bonus"=>$rid == 1 ? $result["bet"] : 0,
            "activity_coinslot_coin_obtain"=>$getCoins,
            "activity_coinslot_quest"=>$this->getUserTreasureCurTaskId($aid,$uid),
            "activity_coinslot_quest_progress"=>$reward['target'] == 0 ? 0 :round($taskNum/$reward['target'],2),
        ]);

        //每个任务层开始时总消耗值和Bonus消耗值清零。(???)
        if($taskNum >= $reward['target']){
            oo::commonOprRedis('Activity')->hSet(okeys::TreasureSpend($aid),"TOTAl_".$uid, 0);
            oo::commonOprRedis('Activity')->hSet(okeys::TreasureSpend($aid),"BONUS_".$uid, 0);
        }

        if($json){
            return oo::response(1, $data);
        }
        return [ 'data' => $data, 'code' => 1];
    }

    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


    //>>>>>>>>>>>>>>>>>>>>>>体力存钱罐>>>>>>>>>>>>>>>>>>>>>>>

    /**
     * 通过gid获取商品sku和价格
     * @param int $uid
     * @param int $gid
     */
    public function getSpinSafeGoodsByGid($uid, $gid, $aid = 0) {
        $stage = $gid == 1807?1:2;
        $aid = !$aid ? $this->getBindActivity($uid, 'spin_safe') : $aid;
        if(empty($aid)){
            return [];
        }
        $actReward = $this->getActReward($aid);
        if(!isset($actReward['extra_reward'], $actReward['extra_reward']['config'])){
            return [];
        }
        $stageInfo = [];
        if(!empty($actReward['extra_reward']['config'][$stage])){
            $stageInfo = $actReward['extra_reward']['config'][$stage];
        }
        if(empty($stageInfo['sku'])){
            return [];
        }
        return [
            'aid'   => $aid,
            'sku'   => $stageInfo['sku'],
            'price' => empty($stageInfo['price']) ? 9.99 : $stageInfo['price'],
        ];
    }

    /**
     * 体力存钱罐当前值
     * @param $aid
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2020/12/3 20:25
     */
    public function getSteelSafeCurNum($aid,$uid){
        return intval(oo::commonOprRedis('Activity')->hGet(okeys::SteelSafeCurNum($aid),$uid));
    }

    /**
     * 追加体力存钱罐当前值
     * @param $aid
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2020/12/3 20:25
     */
    public function addSteelSafeCurNum($aid,$uid,$num){
        return oo::commonOprRedis('Activity')->hIncrBy(okeys::SteelSafeCurNum($aid),$uid,$num);
    }

    /**
     * 体力存钱罐领奖状态
     * @param $aid
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/12/3 20:25
     */
    public function getSteelSafeCurProgress($aid,$uid){
        return funs::ArrayFilter(explode(',',oo::commonOprRedis('Activity')->hGet(okeys::SteelSafeCurProgress($aid),$uid)??""));
    }

    /**
     * 用户限时奖励
     * @param $aid
     * @param $uid
     * @return mixed|null
     * Created by: Owen
     * Created on: 2020/12/3 20:34
     */
    public function getSteelSafeLimitReward($aid,$uid){
        return json_decode(oo::commonOprRedis('Activity')->get(okeys::SteelSafeLimitReward($aid,$uid)),true)??null;
    }

    /**
     * 体力存钱罐逻辑触发
     * @param $uid
     * @param $num (1,2,3) 收集1,2,3体力瓶
     * @return bool|int
     * Created by: Owen
     * Created on: 2020/12/7 20:32
     */
    public function actionSteelSafe($uid, $num, $aid = 0, $bet = 1){
        if(!$aid){
            $aid = $this->activityLock($uid,"spin_safe");
        }
        if(empty($aid)){
            return false;
        }
        $activity = $this->getActivity($aid);
        $actConf = !empty($activity['reward_conf']) ? (array)json_decode($activity['reward_conf'],true) : [];

        $actInfo = $this->getActReward($aid);
        $reward  = $actInfo['reward'];
        $conf    = $actInfo['extra_reward'];
        $userCurProgress = count($this->getSteelSafeCurProgress($aid,$uid));
        $pConfig = $conf['config'][$userCurProgress];
        //$n       = $pConfig['n'] ?? 0.5;
        //$coins = intval(oo::commonOprModel('goods')->getGoodCoins($uid,$pConfig['coins']) * $pConfig['bet']);

        $spins = empty($pConfig['spins']) ? 3 : $pConfig['spins'];
        $curNum= $this->getSteelSafeCurNum($aid,$uid);
        if($curNum < $spins){
            //$actionAddNum = $actionAddNummin($spins - $curNum,ceil($num * round($n,2)));
            $actionAddNum = $num == 3 ? (int)$actConf['three_hit'] : ($num == 2 ? (int)$actConf['two_hit'] : (int)$actConf['one_hit']);
            //增加值超过上限,直接加到上限值
            $actionAddNum = ($actionAddNum + $curNum) > $spins ? $spins - $curNum : $actionAddNum;
            if($actionAddNum > 0){
                $curNum = $this->addSteelSafeCurNum($aid,$uid,(int)($actionAddNum * $bet));
            }
        }
        $this->actionSteelSafeLimit($aid,$uid,$reward,$conf['limit'],$curNum,$spins,$userCurProgress);
        return $curNum;
    }

    /**
     * 触发体力存钱罐限时奖励
     * @param $aid
     * @param $uid
     * @param $reward
     * @param $conf
     * @param $curNum
     * @param $maxNum
     * @param $curProgress
     * @return bool
     * Created by: Owen
     * Created on: 2020/12/7 20:31
     */
    public function actionSteelSafeLimit($aid,$uid,$reward,$conf,$curNum,$maxNum,$curProgress){
        if(oo::commonOprRedis('Activity')->get(okeys::SteelSafeLimitReward($aid,$uid))){
            return false;
        }
        $waitPush = oo::commonOprRedis('Activity')->get(okeys::SteelSafeWaitPush($uid));
        if($waitPush){
            $waitPush = json_decode($waitPush,true);
            if($waitPush['pushTime'] > time()){
                $waitPush['time'] = $waitPush['duration'] + time();
                unset($waitPush['pushTime']);
                unset($waitPush['duration']);
                oo::commonOprRedis('Activity')->setex(okeys::SteelSafeLimitReward($aid,$uid),json_encode($waitPush),min($waitPush['time'] + 5,oo::todayDeadline()));
                oo::commonOprRedis('Activity')->delete(okeys::SteelSafeWaitPush($uid));
                oo::commonOprModel('workerman')->push($uid,ocmd::$send['Activity_spinSafePush'],$waitPush);
            }
            return false;
        }else if(!oo::commonOprRedis('Activity')->get(okeys::SteelSafePushStatus($uid,$aid.'_'.$curProgress))){
            $actionProgress = $curProgress + 1;
            $curPoint = oo::commonOprModel('newvip')->getUserCurPoint($uid);
            $bet = $this->getCoinRewardByTypeAndLevel('rank',oo::commonOprModel('member')->getUserLevel($uid)['levelId']);
            foreach ($conf as $row){
                if($actionProgress == $row['progress'] && $row['pointMin'] <= $curPoint && $row['pointMax'] >= $curPoint){
                    if($curNum >= $row['percent'] * $maxNum){
                        oo::commonOprRedis('Activity')->setex(okeys::SteelSafePushStatus($uid,$aid.'_'.$curProgress),1,oo::todayDeadline());
                        $proTotal = array_sum(array_column($reward,'pro'.$curProgress));
                        $tempReward = [];
                        foreach ($reward as $rw){
                            if(rand(0,$proTotal) <= $rw['pro'.$curProgress]){
                                foreach ($rw['prize'] as $val){
                                    $tempReward[] = $this->getFormattingProps($uid,$aid,$val,$bet);
                                }
                                break;
                            }else{
                                $proTotal -= $rw['pro'.$curProgress];
                            }
                        }
                        if(!empty($tempReward)){
                            $curTime = time();
                            if($row['delay'] == 0){
                                $waitPush = [
                                    'time'  => $curTime + $row['duration'],
                                    'props' => $tempReward,
                                ];
                                oo::commonOprRedis('Activity')->setex(okeys::SteelSafeLimitReward($aid,$uid),json_encode($waitPush),min($curTime + $row['duration'] + 5,oo::todayDeadline()));
                                oo::commonOprModel('workerman')->push($uid,ocmd::$send['Activity_spinSafePush'],$waitPush);
                            }else{
                                oo::commonOprRedis('Activity')->setex(okeys::SteelSafeWaitPush($uid),json_encode([
                                    'pushTime' => $curTime + $row['delay'],
                                    'duration' => $row['duration'],
                                    'props'    => $tempReward,
                                ]),oo::todayDeadline());
                            }
                        }
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 保險柜领奖
     * @param $uid
     * @param $progressId
     * @param bool $isPay
     * @return string
     * Created by: Owen
     * Created on: 2020/12/5 12:33
     */
    public function rewardSteelSafe($uid,$progressId,$isPay = false){
        $aid  = $this->activityLock($uid,"spin_safe");
        if(!$aid){
            return oo::response(errorCode::NOT_FOUND_ACTIVITY);
        }
        $curProgressStatus = $this->getSteelSafeCurProgress($aid,$uid);
        if(!$isPay && in_array($progressId,$curProgressStatus)){
            return oo::response(errorCode::STEELSAFE_REWARDED);
        }
        $conf = $this->getActReward($aid)['extra_reward'];
        $pConfig = array_column($conf['config'],null,'progress');
        $pStages = array_keys($pConfig);
        $endStage = $pStages?end($pStages):3;
        $pConfig = $pConfig[$progressId];
        //$coins = intval(oo::commonOprModel('goods')->getGoodCoins($uid,$pConfig['coins']) * $pConfig['bet']);
        $spins = empty($pConfig['spins']) ? 3 : $pConfig['spins'];
        $curNUm= $this->getSteelSafeCurNum($aid,$uid);
        if(!$isPay && $curNUm < $spins){
            return oo::response(errorCode::STEELSAFE_PROGRESS_ERROR);
        }

        oo::commonOprRedis('Activity')->hIncrBy(okeys::SteelSafeSta(),"reward:".$progressId,1);//  每天统计每个进度领取/购买次数

        $limitReward = json_decode(oo::commonOprRedis('Activity')->get(okeys::SteelSafeLimitReward($aid,$uid)),true) ?? null;
        $props = [];
        if(!empty($limitReward)){
            oo::commonOprRedis('Activity')->hIncrBy(okeys::SteelSafeSta(),"limit:".$progressId,1);
            $props = $limitReward['props'];
            foreach ($props as $key=>&$row){
                oo::commonOprRedis('Activity')->hIncrBy(okeys::SteelSafeSta(),"props:".$progressId."-".$row['propsId'],$row['num']);       // 每天统计每个进度的领取到限时奖励物品和数量。
                oo::commonOprModel('member')->sendReward($uid,$row['propsId'],$row['num'],218,"体力存钱罐-限时奖励：".$progressId,[],$row);
            }
            if($endStage > $progressId){
                oo::commonOprRedis('Activity')->delete(okeys::SteelSafeLimitReward($aid,$uid));
            }
        }
        oo::commonOprRedis('Activity')->hIncrBy(okeys::SteelSafeSta(),"spins:".$progressId,$spins);       // 每天统计每个进度金币金额
        oo::commonOprModel('member')->optProperty($uid,['spins'=>$spins],'+',218,'活动-体力存钱罐：'.$progressId);

        array_unshift($props,['propsId'=>15,'num'=>$spins,'value'=>$spins]);

        $curProgressStatus[] = $progressId;
        oo::commonOprRedis('Activity')->hSet(okeys::SteelSafeCurProgress($aid),$uid,implode(',',array_filter($curProgressStatus)));
        oo::commonOprRedis('Activity')->hdel(okeys::SteelSafeCurNum($aid),$uid); //领奖后清楚数值
        if($isPay){
            return $props;
        }
        return oo::response(errorCode::SUCCESS,['props'=>$props]);
    }

    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>金币爆炸>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:获取金币爆炸倍率
     * User: wsc
     * Time: 2020/12/7 17:44
     * @param $uid
     * @param $type
     * @return int
     */
    public function getCoinBlastBetByType($uid,$type){
        $bet=0;
        $aid = $this->getBindActivity($uid,'coin_blast');
        if($aid){
            $rewardConf = $this->getActReward($aid);
            $data = $rewardConf['reward'];
            $data = array_column($data,null,'type');
            if(intval($data[$type]['bet'])>=1){
                $bet = intval($data[$type]['bet']);
            }
        }
        return $bet;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>二选一活动>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * 二选一活动奖励配合
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2021/2/5 15:38
     */
    public function getChooseOneGoods($uid){
        $data= [];
        $aid = $this->activityLock($uid,"choose_one");
        if(empty($aid)){
            return $this->getActivityShopCache(okeys::activityShopCache($uid, 'choose_one'));
        }
        $sid = oo::getDefinedSid($uid);
        $actInfo = $this->getActReward($aid);
        $reward  = $goods   = [];
        $bet     = $this->getCoinRewardByTypeAndLevel("collect",oo::commonOprModel('member')->getUserLevel($uid)['levelId']);
        //1.8.6区分rfm分组
        if(isset($actInfo['reward'][0]) && !empty($actInfo['reward'][0]['data'])){
            $groupRid = 2;
            //1.14.1支持动态选择分组
            if(!empty($actInfo['extra_reward']["groupRid"])){
                $groupRid = $actInfo['extra_reward']["groupRid"];
            }
            $reward = $this->getGroupGoods($uid,$aid, $groupRid, $actInfo['reward']);
//            $defaultRwd = [];
//            //rfm分组
//            $groupId = oo::commonOprModel('config')->getUserGroupIdByCid($uid, $groupRid);
//            foreach($actInfo['reward'] as $tmp){
//                if(empty($tmp['gid']) || in_array(0, $tmp['gid'])){
//                    $defaultRwd = $tmp['data'];
//                }
//                if(!empty($tmp['gid']) && !in_array($groupId, $tmp['gid'])){
//                    continue;
//                }
//                $reward = $tmp['data'];
//                break;
//            }
//            $reward = (empty($reward) && !empty($defaultRwd)) ? $defaultRwd : $reward;
        }else{
            $reward = $actInfo['reward'];
        }
        foreach($reward as $row){
            $props   = [];
            foreach ($row['prize'] as $val){
                $props[] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
            $goods[] = [
                'gid'      => $row['gid'],
                'pid'      => 1,
                'price'    => "$".$row['gprice'],
                'priceNum' => (string)$row['gprice'],
                'sku'      => ($sid == 1) ? oo::commonOprModel('goods')->googleSkuToAndroid($row['gsku']) : oo::commonOprModel('goods')->googleSkuToIosSku($row['gsku']),
                'ggameid'  => 1,
                'gdiscount'=> $row['gdiscount'],
                'addRatio' => 0,
                'max'      => 1,
                'props'    => $props,
                'priceDollar'      => '$',
                'priceCurrencyCode'=> 'USD'
            ];
        }
        //添加商品活动缓存
        oo::commonOprRedis('activity')->hMset(okeys::activityShopCache($uid, 'choose_one'), $goods);
        $this->setActivityShopCache(okeys::activityShopCache($uid, 'choose_one'), $goods);
        $data = $goods;
        return $data;
    }

    /**
     * Notes:根据分组获取商品配置
     * User: hss
     * Time: 2021/08/06 15:36
     * @param $groupRid 分组类型
     * @param $config 配置
     * @return int|mixed
     */
    public function getGroupGoods($uid,$aid,$groupRid = 0,$config = []){
        $userBindAttrInfo =  $this->getUserBindAttr($uid,$aid);
//        $userDynamicsData = oo::commonOprModel('member')->getUserDynamicsData($uid);
        if($groupRid == 2){
            $userGroupId = !empty($userBindAttrInfo['userGroup'])? explode(',',$userBindAttrInfo['userGroup']):[0];
        }else{
            $userGroupId = !empty($userBindAttrInfo['userSSGroup'])? explode(',',$userBindAttrInfo['userSSGroup']):[0];
        }
        foreach($config as $tmp){
            if(empty($tmp['gid']) || in_array(0, $tmp['gid'])){
                $defaultRwd = $tmp['data'];
            }
            foreach($userGroupId as $groupId){
                if(in_array($groupId, $tmp['gid'])){
                    $reward = $tmp['data'];
                    break;
                }
            }
            if(isset($reward)){
                break;
            }
        }
        $defaultRwd = empty($defaultRwd) ? $config[0]['data'] : $defaultRwd;
        $reward = empty($reward) ? $defaultRwd : $reward;
        return $reward;
    }

    /**
     * Notes:根据活动类型和活动ID获取商品数据
     * User: hss
     * Time: 2021/08/06 15:36
     * @param $uid
     * @param $type 活动类型
     * @return int|mixed
     */
    public function getActivityGoods($uid,$type){
        $data= [];
        $aid = $this->activityLock($uid,$type);
        if(empty($aid)){
            return $this->getActivityShopCache(okeys::activityShopCache($uid, $type));
        }
        $sid = oo::getDefinedSid($uid);
        $actInfo = $this->getActReward($aid);
        $reward  = $goods   = [];
        $bet     = $this->getCoinRewardByTypeAndLevel("collect",oo::commonOprModel('member')->getUserLevel($uid)['levelId']);
        //1.8.6区分rfm分组
        if(isset($actInfo['reward'][0]) && !empty($actInfo['reward'][0]['data'])){
            $reward = $this->getGroupGoods($uid,$aid,$actInfo['extra_reward']["groupRid"],$actInfo['reward']);
        }else{
            $reward = $actInfo['reward'];
        }
        foreach($reward as $row){
            $props   = [];
            foreach ($row['prize'] as $val){
                $props[] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
            $goods[] = [
                'gid'      => $row['gid'],
                'pid'      => 1,
                'price'    => "$".$row['gprice'],
                'priceNum' => (string)$row['gprice'],
                'sku'      => ($sid == 1) ? oo::commonOprModel('goods')->googleSkuToAndroid($row['gsku']) : oo::commonOprModel('goods')->googleSkuToIosSku($row['gsku']),
                'ggameid'  => 1,
                'gdiscount'=> $row['gdiscount'],
                'addRatio' => 0,
                'max'      => 1,
                'props'    => $props,
                'priceDollar'      => '$',
                'priceCurrencyCode'=> 'USD'
            ];
        }
        //添加商品活动缓存
        oo::commonOprRedis('activity')->hMset(okeys::activityShopCache($uid, $type), $goods);
        $this->setActivityShopCache(okeys::activityShopCache($uid, $type), $goods);
        $data = $goods;
        return $data;
    }

    /**
     * 基金活动,二选一活动商品添加缓存,防止活动到期后支付不发货bug
     * 默认保存3小时
     */
    public function setActivityShopCache($cacheKey, $goods = []) {
        return oo::commonOprRedis('activity')->setex($cacheKey, json_encode($goods), 3 * 3600);
    }

    /**
     * 基金活动,二选一活动商品添加缓存,防止活动到期,支付不发货
     */
    public function getActivityShopCache($cacheKey) {
        $cache = oo::commonOprRedis('activity')->get($cacheKey);
        return $cache ? (array)json_decode($cache, true) : [];
    }

    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>基金活动>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * 基金活动奖励配置
     * @param $aid
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2021/2/5 15:38
     */
    public function getFundConfig($aid,$uid){
        $actInfo = $this->getActReward($aid);
        $config  = [];
        $bet     = $this->getCoinRewardByTypeAndLevel("collect",oo::commonOprModel('member')->getUserLevel($uid)['levelId']);
        $i = 0;
        $versionFlag = true;
        if(oo::compareVersion(oo::commonOprModel('user')->getUserVersion($uid),'1.8.5')){
            $versionFlag = false;
        }
        foreach ($actInfo['reward'] as $row){
            $props   = [];
            foreach ($row['prize'] as $val){
                $props[] = $this->getFormattingProps($uid,$aid,$val,$bet);
            }
            $config[] = [
                'id'   =>$row['id'],
                'props'=>$props
            ];
            $i ++;
            if($versionFlag && $i == 7){
                break;
            }
        }
        return $config;
    }

    /**
     * 基金活动购买状态
     * @param $aid
     * @param $uid
     * @return bool|false
     * Created by: Owen
     * Created on: 2020/10/22 18:27
     */
    public function getBuyFundStatus($aid,$uid){
        $cacheKey = okeys::BuyFundStatus($aid,$uid);
        $cache    = oo::commonOprRedis('activity')->get($cacheKey);
        if($cache !== false){
            return $cache;
        }
        $tb  = otable::payment($uid);
        $sql = "SELECT COUNT(*) as c FROM {$tb} WHERE uid='{$uid}' AND gid in (1812,1813) AND buff='{$aid}'";
        $ret = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        oo::commonOprRedis('activity')->setex($cacheKey,$ret['c'],7*24*60*60);
        return $ret['c'];
    }

    /**
     * 基金活动领奖ID
     * @param $aid
     * @param $uid
     * @return bool|false
     * Created by: Owen
     * Created on: 2020/10/22 18:27
     */
    public function getFundRewardDayId($aid,$uid){
        return ((intval((time() - $this->getBuyFundTime($aid,$uid)) / 86400))%14) + 1;
    }

    /**
     * 获取基金活动领取ID
     * @param $aid
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2021/2/23 17:53
     */
    public function getFundRewardList($aid,$uid){
        return funs::ArrayFilter(explode(',',oo::commonOprRedis('activity')->hGet(okeys::FundRewardList($aid),$uid) ?? ""));
    }

    /**
     * 领奖时间
     * @param $aid
     * @param $uid
     * @return false|int|mixed
     * Created by: Owen
     * Created on: 2021/2/5 16:51
     */
    public function getBuyFundTime($aid,$uid){
        $cacheKey = okeys::BuyFundTime($aid,$uid);
        $cache    = oo::commonOprRedis('activity')->get($cacheKey);
        if($cache !== false){
            return $cache;
        }
        $tb  = otable::payment($uid);
        $sql = "SELECT * FROM {$tb} WHERE uid='{$uid}' AND gid=1812 AND buff='{$aid}' LIMIT 1";
        $ret = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        if(empty($ret)){
            return time();
        }
        $min = $ret["pay_time"];
        oo::commonOprRedis('activity')->setex($cacheKey,$min,7*24*60*60);
        return $min;
    }

    /**
     * 基金活动当天领奖状态
     * @param $aid
     * @param $uid
     * @return bool|false
     * Created by: Owen
     * Created on: 2020/10/22 18:27
     */
    public function getTodayRewardStatus($aid,$uid){
        return intval(oo::commonOprRedis('activity')->get(okeys::TodayRewardStatus($aid,$uid)));
    }

    /**
     * 领取基金活动奖励
     * @param $uid
     * Created by: Owen
     * Created on: 2021/2/5 16:56
     */
    public function rewardFund($uid,$reissueId = 0){
        $aid = oo::commonOprRedis("Activity")->get(okeys::FundAid($uid));
        if(!$aid){
            return oo::response(errorCode::NOT_OPEN,[],"活动未购买");
        }
        if($reissueId == 0 && $this->getTodayRewardStatus($aid,$uid)){
            return oo::response(errorCode::OVER_RECEIVE_REWARD,[],"当天奖励已领取");
        }
        if($reissueId != 0){
            if(!in_array($reissueId,$this->getFundReissue($aid,$uid))){
                return oo::response(errorCode::NOT_OPEN,[],"活动未购买");
            }
            if(in_array($reissueId,$this->getFundRewardList($aid,$uid))){
                return oo::response(errorCode::OVER_RECEIVE_REWARD,[],"奖励已领取");
            }
        }
        $id = $reissueId == 0 ? $this->getFundRewardDayId($aid,$uid) : $reissueId;
        $config = array_column($this->getFundConfig($aid,$uid),"props",'id');
        $props  = $config[$id];
        if(empty($props)){
            $props = $config[$id - 7];
        }
        $tip = $reissueId == 0 ? "":"(补签-{$reissueId})";
        foreach ($props as $key=>&$row){
            $info = oo::commonOprModel('member')->sendReward($uid, $row['propsId'], $row['num'],121,"基金活动领取奖励=>：{$aid}，{$id} {$tip}",[],$row);
            $row['propsId'] == 13 && $row['value'] = is_array($info) ? $info : [$info];
        }
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        if($reissueId == 0 && oo::compareVersion($version,'1.8.5')){
            $expireTime = max((oo::commonOprRedis("Activity")->hGet(okeys::FundAidUid($aid),$uid) + $id * 24*60*60) - time(),0);
            oo::commonOprRedis('activity')->setex(okeys::TodayRewardStatus($aid,$uid),1,$expireTime);
        }else{
            $reissueId == 0 && oo::commonOprRedis('activity')->setex(okeys::TodayRewardStatus($aid,$uid),1,oo::todayDeadline());
        }

        $rewardList = $this->getFundRewardList($aid,$uid);
        $rewardList[] = $id;
        oo::commonOprRedis('activity')->hSet(okeys::FundRewardList($aid),$uid,implode(',',$rewardList));
        return oo::response(1,['props'=>$props]);
    }

    /**
     * 获取当前补签记录
     * @param $aid
     * @param $uid
     * @param $type
     * @return array
     * Created by: Owen
     * Created on: 2020/10/21 14:38
     */
    public function getFundReissue($aid,$uid){
        $rewarded = oo::commonOprRedis('activity')->hGet(okeys::FundReissue($aid),$uid);
        return funs::ArrayFilter(explode(',',$rewarded??""));
    }

    /**
     * 设置补签记录
     * @param $aid
     * @param $uid
     * @param $type
     * @param $levelId
     * @return bool
     * Created by: Owen
     * Created on: 2020/10/21 14:38
     */
    public function setFundReissue($aid,$uid,$id){
        $curData = $this->getFundReissue($aid,$uid);
        $curData[] = $id;
        $curData = implode(',',array_unique(funs::ArrayFilter($curData)));
        return oo::commonOprRedis('activity')->hSet(okeys::FundReissue($aid),$uid,$curData);
    }

    //***1+1礼包***//
    public function onePlusGiftReward($uid,$aid = 0){
        if(!$aid){
            $aid = oo::commonOprModel('activitynew')->activityLock($uid,'one_plus_gift');
            if(!$aid){
                return oo::response(errorCode::NOT_FOUND_ACTIVITY,[],'活动不存在');
            }
        }
        if(intval(oo::commonOprRedis('activity')->hGet(okeys::onePlusGiftBuyStatus($aid),$uid)) > 0){
            $onePlusGift = oo::commonOprModel('activitynew')->getActivityGoods($uid,"one_plus_gift");
            $reward = $onePlusGift[1]['props'];
            foreach ($reward as $key => &$row){
                $info = oo::commonOprModel('member')->sendReward($uid,$row['propsId'],$row['num'],456,'活动ID：'.$aid.' 1+1礼包 免费',[],$row);
            }
            oo::commonOprRedis('activity')->hDel(okeys::onePlusGiftBuyStatus($aid),$uid);
            return oo::response(1,["reward"=>$reward]);
        }else{
            return oo::response(errorCode::NONE_REWARD,[],'无奖励');
        }
    }
    //*****//


    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>四选一活动>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:获取用户四选一活动信息(用于步骤快照恢复)
     * User: wsc
     * Time: 2021/3/8 11:15
     * @param $uid
     * @param $t int 调用方 0对外输出 1发奖调用
     * @return array ["lockLv"=>"锁定的关卡","thisLv"=>"当前关卡","getReward"=>"获取的奖励关卡及关卡内已敲奖励蛋的id","lastEasterLv"=>"最后一次复活所在关卡","easterLimit"=>"复活次数","easterLog"=>"复活记录"]
     */
    public function getUserEasterEggInfo($uid,$t=0){
        $data=[];
        $aid = $this->getBindActivity($uid,'easter_egg');
        if(!$aid){
            return $data;
        }
        $key = okeys::easterEggInfo($uid,$aid);
        $userActInfo = oo::commonOprRedis('activity')->hGetAll($key);//用户个人游戏信息记录
        if($t==1){
            $data = $userActInfo;
            $data['easterLog'] =$userActInfo['easterLog']?json_decode($userActInfo['easterLog'],true):[];
            $data['aid'] = $aid;
        }else{
            $data['thisLv'] = $userActInfo['thisLv'];
            $data['status'] = $userActInfo['lockLv']?1:0;
        }
        $data['getReward'] =$userActInfo['getReward']?json_decode($userActInfo['getReward'],true):[];//累计获得的奖励配置
        $prizes = $prize = [];
        if(!empty($data['getReward'])){
            $reward =$this->getEggInfo($uid,$aid);
            foreach ($data['getReward'] as $key=>$vel){
                $thisLvReward = array_column($reward[$vel['lv']]['eggs'],null,'stage');
                $prize = $thisLvReward[$vel['stage']]['prize'];
//                $prizes[$prize['propsId']] += $prize['num'];
                $prizes[] = $prize;
            }
            if($t!=1){
//                $arr = [];
//                foreach ($prizes as $k=>$v){
//                    $arr[] = ["propsId"=>$k,"num"=>$v];
//                }
//                $prizes = $arr;
                unset($data['getReward']);
                $data['giftBag'] = $this->getEasterGiftBag($uid);
            }
            $data['rewardInfo'] = $prizes;//奖励配置格式化
        }else{
            unset($data['getReward']);
            $data['rewardInfo'] = [];
        }
        $easterInfo = $this->getEasterInfo($uid,$aid,1);
        $data['easterMoney'] = $easterInfo['money'];
        return $data;
    }
    /**
     * Notes:获取当前蛋组奖励信息
     * User: wsc
     * Time: 2021/3/5 20:10
     * @param $uid
     * @return array
     */
    public function getEggInfo($uid,$aid){
        $data=[];
        $rewardInfo = $this->getActReward($aid)['extra_reward'];
        $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        $bet =$this->getCoinRewardByTypeAndLevel('easter_egg',$lv);
        foreach ($rewardInfo as $key=>$val){
            $eggs = [];
            foreach ($val['list'] as $k=>$v){

                if(empty($v['prize'][0])){
                    $egg['prize'] = null;
                    $egg['stage'] = $v['stage'];
                    $egg['type'] = 0;
                    $eggs[] = $egg;
                }else{
                    $egg['prize'] = $this->getFormattingProps($uid,$aid,$v['prize'][0],$bet);
                    $egg['stage'] = $v['stage'];
                    $egg['type'] = 1;
                    $eggs[] = $egg;
                }
            }
            $one['eggs'] = $eggs;
            $one['lv']  = $val['star'];
            $data[$val['star']] = $one;
        }
        return $data;
    }

    /**
     * Notes:获取用户复活配置信息
     * User: wsc
     * Time: 2021/3/5 18:46
     * @param $uid
     * @param $aid
     * @param $t int 0当前关 1将要复活的关 2附加复活礼包信息
     * @return array ["money"=>"当前关/即将复活关-复活所需金币","limit"=>"已经复活的次数","ce"=>"此次复活对概率修正系数","maxlimit"=>"最大复活次数"]
     */
    public function getEasterInfo($uid,$aid,$t=0){
        $aInfo = $this->getActivity($aid);
        $key = okeys::easterEggInfo($uid,$aid);
        $limit = intval(oo::commonOprRedis('activity')->hGet($key,'easterLimit'));//当前已复活次数
        $reward_conf = json_decode($aInfo['reward_conf'],true);
        if(empty($reward_conf)){
            $reward_conf =[["limit"=>$limit,"bet"=>5,"ce"=>1]];
        }
        $limit2 = $t?$limit+1:$limit;
        $easterConf = array_column($reward_conf,'bet','limit');
        $ceConf = array_column($reward_conf,'ce','limit');
        $bet = $easterConf[$limit2]?intval($easterConf[$limit2]):(end($easterConf)?end($easterConf):5);
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $coin = $this->getCoinRewardByTypeAndLevel('easter_egg',$userInfo['levelId']);
        $money = $bet*$coin;
        $data = ["money"=>$money,"limit"=>$limit?$limit:0,"ce"=>$ceConf[$limit]?$ceConf[$limit]:1,"maxLimit"=>count($easterConf),"coins"=>$coin,"haveMoney"=>$userInfo['money']];
        if($t==2){
            $needMoney = $money-$userInfo['money'];//加身上金币复活还差金币数
            $extraData = json_decode($aInfo['extraData'],true);
            if(empty($extraData)){
                $extraData=[["stage"=>1,"bet"=>5,"sku"=>'com.gworld.cc.gift07',"price"=>1.99]];
            }
            $extraData = array_column($extraData,null,'stage');
            foreach ($extraData as $k=>$v){
                if($v['bet']*$coin>=$needMoney&&$needMoney>$extraData[$k-1]['bet']*$coin){//归档此次复活礼包
                    $data['giftBag']=$v;
                    $data['giftBag']['buyMoney']=$v['bet']*$coin;
                    continue;
                }
            }
            if(empty($data['giftBag'])){//防止时间差及异常配置导致发货异常(默认配置)
                $data['giftBag']=$extraData[0];
                $data['giftBag']['buyMoney']=$extraData[0]['bet']*$coin;
            }
        }
        return $data;
    }

    /**
     * Notes:获取复活礼包配置
     * User: wsc
     * Time: 2021/3/8 18:33
     * @param $uid
     * @return array
     */
    public function getEasterGiftBag($uid,$gid=''){
        $good =[];
        $aInfo = $this->getBindActivity($uid,'easter_egg',true);
        $aid = $aInfo['id'];
        if(empty($aid)){
            return $good;
        }
        $info = $this->getEasterInfo($uid,$aid,2);
        if(empty($info['giftBag'])||empty($info['giftBag']['stage'])){
            return $good;
        }
        $reward =$info['giftBag'];
        $sgsid = oo::getDefinedSid($uid);
        $good =[
            'gid'              =>$reward['stage']+750,
            'priceDollar'      =>"$",
            'priceCurrencyCode'=>"USD",
            'sku'              =>($sgsid == 1)?oo::commonOprModel('goods')->googleSkuToAndroid($reward['sku']):oo::commonOprModel('goods')->googleSkuToIosSku($reward['sku']),
            'price'            =>'$'.$reward['price'],
            'priceNum'         =>(string)$reward['price'],
            'props'            =>[["propsId"=>14, "num"=>intval($reward['buyMoney'])]],
        ];
        if(!empty($gid)&&$gid!=$good['gid']){//特殊情况,买礼包的时候被偷,钱不够,发货根据当前金币状况发货
            $extraData = json_decode($aInfo['extraData'],true);
            $extraData = array_column($extraData,null,'stage');
            $reward = $extraData[$gid-750];
            $sendMoney = $info['coins']*$reward['bet'] - $info['haveMoney'];
            $sendMoney = $sendMoney>0?$sendMoney:$info['coins']*$reward['bet'];
            $good =[
                'gid'              =>$reward['stage']+750,
                'priceDollar'      =>"$",
                'priceCurrencyCode'=>"USD",
                'sku'              =>($sgsid == 1)?oo::commonOprModel('goods')->googleSkuToIosSku($reward['sku']):oo::commonOprModel('goods')->googleSkuToIosSku($reward['sku']),
                'price'            =>'$'.$reward['price'],
                'priceNum'         =>(string)$reward['price'],
                'props'            =>[["propsId"=>14, "num"=>$sendMoney]],
            ];
        }
        return $good;
    }

    /**
     * Notes:过关
     * User: wsc
     * Time: 2021/3/5 17:58
     * @param $uid
     * @param $aid
     * @return int
     */
    public function passEasterEggLv($uid,$aid){
        $key = okeys::easterEggInfo($uid,$aid);
        $lv = oo::commonOprRedis('activity')->hIncrBy($key,'thisLv',1);
        return $lv;
    }

    /**
     * Notes:敲蛋
     * User: wsc
     * Time: 2021/3/5 19:04
     * @param $uid
     * @return string
     */
    public function strikeEgg($uid,$n=0){
        $data=[];
        $aid = $this->getBindActivity($uid,'easter_egg');
        if(!$aid){
            return  oo::response(errorCode::NOT_FOUND_ACTIVITY,$data);
        }
        $key = okeys::easterEggInfo($uid,$aid);
        $userActInfo = oo::commonOprRedis('activity')->hGetAll($key);//用户个人游戏信息记录
        if($userActInfo['lockLv']){//尚在锁定中,无法继续敲,需先复活(保护措施)
            $data['giftBag'] = $this->getEasterGiftBag($uid);
            return  oo::response(errorCode::CONDITION_NOT_RNOUGH,$data);
        }
        $lastEasterLv = $userActInfo['lastEasterLv'];
        $easterInfo = $this->getEasterInfo($uid,$aid,1);//当前关,复活相关信息

        $lvInfoCfg = array_column($this->getActReward($aid)['extra_reward'],null,'star');
        if($userActInfo['thisLv']>count($lvInfoCfg)){
            return  oo::response(errorCode::OVER_RECEIVE_REWARD,$data);
        }
        $thisWeightCfg = $lvInfoCfg[$userActInfo['thisLv']]['list'];//当前关配置
        foreach ($thisWeightCfg as $k=>$v){
            if(empty($v['prize'])&&$lastEasterLv==$userActInfo['thisLv']){//最后一次复活在本关,此次为复活后敲蛋,3选一过滤无奖励的蛇
                continue;
            }
            $prop[$v['stage']] = $v['stepnum'];
            if(empty($v['prize'])){
                $prop[$v['stage']] = $v['stepnum']*$easterInfo['ce'];
            }
            $reward[$v['stage']] = $v['prize'];
        }
        $stage = funs::get_randByProb($prop);//当前结果蛋id
        if($n){//指定敲具体蛋
            $stage =  $n;
        }
        $data['thisLv'] = $userActInfo['thisLv'];
        $data['stage'] = $stage;
        $data['over'] =0;
        $data['easterMoney'] = $easterInfo['money'];
        if(!empty($reward[$stage])){//敲出奖励
            //记录奖励
            $userGetRewardList = $userActInfo['getReward']?json_decode($userActInfo['getReward'],true):[];
            array_push($userGetRewardList,["lv"=>$userActInfo['thisLv'],"stage"=>$stage]);
            oo::commonOprRedis('activity')->hSet($key,'getReward',json_encode($userGetRewardList));
            if($userActInfo['thisLv']==count($lvInfoCfg)){//到达最大关
                $data['over']=1;
            }
            $this->passEasterEggLv($uid,$aid);//过关
            $result=2;
        }else{//死亡
            oo::commonOprRedis('activity')->hSet($key,'lockLv',$userActInfo['thisLv']);//锁定,不复活无法再敲
            $giftBag = $this->getEasterGiftBag($uid);
            $data['giftBag'] = !empty($giftBag)?$giftBag:null;
            $result=1;
        }
        //数数事件-彩蛋敲蛋
        $field = oo::commonOprModel('ta')->events['activity_egg_knock'];
        unset($field['activity_egg_knock_layer'],$field['activity_egg_knock_result']);
        $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        $bet =$this->getCoinRewardByTypeAndLevel('easter_egg',$lv);
        $props[] = !empty($reward[$stage])?$this->getFormattingProps($uid,$aid,$reward[$stage][0],$bet):[];
        $eventData = oo::commonOprModel('ta')->getPropsSSEventData($props,$field);
        $eventData['activity_egg_knock_layer']= $userActInfo['thisLv'];
        $eventData['activity_egg_knock_result']= $result;
        oo::commonOprModel('ta')->setEventData($uid,'activity_egg_knock',$eventData);

        return oo::response(1,$data);
    }

    /**
     * Notes:复活-彩蛋游戏
     * User: wsc
     * Time: 2021/3/5 19:01
     * @param $uid
     * @return string
     */
    public function easterGame($uid){
        $data = [];
        $aid = $this->getBindActivity($uid,'easter_egg');
        if(!$aid){
            return  oo::response(errorCode::NOT_FOUND_ACTIVITY,$data);
        }

        $info = $this->getEasterInfo($uid,$aid,1);//limit+1的复活信息
        if($info['limit']>=$info['maxLimit']){//当前复活次数达上限
            $data['limit'] = $info['limit'];
            return  oo::response(errorCode::LIMIT_NOT_RNOUGH,$data);
        }
        //扣钱
        $key = okeys::easterEggInfo($uid,$aid);
        $lv = oo::commonOprRedis('activity')->hGet($key,'thisLv');
        $coin =oo::commonOprModel('member')->optProperty($uid,["money"=>$info['money']],'-',221,"在{$lv}关,第{$info['limit']}次复活");
        if(!$coin){//金币不足
            $data['coins'] = oo::commonOprModel('member')->getUserAssetsInfo($uid)['money'];
            return  oo::response(errorCode::MONEY_NOT_RNOUGH,$data);
        }

        //统计关卡消耗
//        $key2 = okeys::todaySta('easterEgg_lost_'.$lv);
//        oo::commonOprRedis('Statistics')->hIncrBy($key2,13,$info['money']);//统计关卡消耗
//        oo::commonOprRedis('Statistics')->expire($key2,86400*2);

        //累计复活次数
        $limit = oo::commonOprRedis('activity')->hIncrBy($key,'easterLimit',1);
        //记录最后一次复活所在关卡
        oo::commonOprRedis('activity')->hSet($key,'lastEasterLv',$lv);
        //消除锁定
        oo::commonOprRedis('activity')->hSet($key,'lockLv',0);
        //复活记录
        $easterLogJson = oo::commonOprRedis('activity')->hGet($key,'easterLog');
        $easterLog = $easterLogJson?json_decode($easterLogJson,true):[];
        array_push($easterLog,$lv);
        oo::commonOprRedis('activity')->hSet($key,'easterLog',json_encode($easterLog));

        $data['limit'] = $limit;
        $data['coins'] = $coin;
        //数数事件-彩蛋复活
        $eventData= [
            "activity_egg_rebirth_layer"=>$lv,
            "activity_egg_rebirth_times"=>$limit,
            "activity_egg_rebirth_coin_cost"=>$info['money'],
        ];
        oo::commonOprModel('ta')->setEventData($uid,'activity_egg_rebirth',$eventData);
        return  oo::response(1,$data);
    }

    /**
     * Notes:领奖离开
     * User: wsc
     * Time: 2021/3/8 10:43
     * @param $uid
     * @return string
     */
    public function rewardEasterEgg($uid){
        $data=[];
        $userActInfo =$this->getUserEasterEggInfo($uid,1);
        $data['rewardInfo'] = $userActInfo['rewardInfo'];
        $aid = $userActInfo['aid'];
        if(!$aid){
            return  oo::response(errorCode::NOT_FOUND_ACTIVITY,$data);
        }
        if(intval($userActInfo['lockLv'])>0){//存在锁,非法领奖
            return  oo::response(errorCode::CONDITION_NOT_RNOUGH,$data);
        }
        if(empty($userActInfo['rewardInfo'])){//没有可领取的奖励
            return  oo::response(errorCode::NONE_REWARD,$data);
        }
        //清理活动缓存
        oo::commonOprRedis('activity')->delete(okeys::easterEggInfo($uid,$aid));
        $this->clearUserSpeciaAct($uid,$aid);
        //发奖
        foreach ($userActInfo['rewardInfo'] as $k=>$v){
            $value =oo::commonOprModel('member')->sendReward($uid,$v['propsId'],$v['num'],221,"领奖离开-当前关卡:{$userActInfo['thisLv']}",$v['value'],$v);
            if($value&&in_array($v['propsId'],[13,18,19,20,21,29,30])){
                $data['rewardInfo'][$k]['value'] = $value;
            }
        }
        $logs= $userActInfo;
        unset($logs['rewardInfo'],$logs['lockLv']);
        $logs['status'] = 2;
        $logs['uid'] = $uid;
        $logs['ts'] =time();
        oo::commonOprRedis('Statistics')->lPush(okeys::easterEggGameLog(),json_encode($logs));
        //数数事件-彩蛋结束
        $lvInfoCfg = array_column($this->getActReward($aid)['extra_reward'],null,'star');
        $field = oo::commonOprModel('ta')->events['activity_egg_end'];
        unset($field['activity_egg_end_layer'],$field['activity_egg_end_type']);
        $eventData = oo::commonOprModel('ta')->getPropsSSEventData($data['rewardInfo'],$field);
        $eventData['activity_egg_end_layer']=intval($userActInfo['thisLv']);
        $eventData['activity_egg_end_type']=2;
        oo::commonOprModel('ta')->setEventData($uid,'activity_egg_end',$eventData);

        return  oo::response(1,$data);
    }

    /**
     * Notes:放弃游戏离开
     * User: wsc
     * Time: 2021/3/8 10:43
     * @param $uid
     * @param $status int 0主动离开 1到时间被动离开
     * @return string
     */
    public function overEasterEgg($uid,$status=0){
        $data=[];
        $userActInfo =$this->getUserEasterEggInfo($uid,1);
        if(empty($userActInfo)||empty($userActInfo['aid'])){
            return oo::response(errorCode::NOT_FOUND_ACTIVITY,$data);
        }
        //清理缓存
        $aid =$userActInfo['aid'];
        oo::commonOprRedis('activity')->delete(okeys::easterEggInfo($uid,$aid));
        $this->clearUserSpeciaAct($uid,$aid);
        //写砸蛋日志 ["uid"=>"用户id","thisLv"=>"当前关卡","getReward"=>"获取的奖励关卡及关卡内已敲奖励蛋的id","easterLimit"=>"复活次数","easterLog"=>"复活记录"]
        $logs= $userActInfo;
        unset($logs['rewardInfo'],$logs['lockLv']);
        $logs['status'] = $status;
        $logs['uid'] = $uid;
        $logs['ts'] =time();
        oo::commonOprRedis('Statistics')->lPush(okeys::easterEggGameLog(),json_encode($logs));
        //数数事件-彩蛋结束
        $eventData['activity_egg_end_layer']=intval($userActInfo['thisLv']);
        $eventData['activity_egg_end_type']=3;
        oo::commonOprModel('ta')->setEventData($uid,'activity_egg_end',$eventData);
        return  oo::response(1,$data);
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


    //<<<<<<<<<<<<<<<<<<<<每日小丑宝箱活动<<<<<<<<<<<<<<<
    /**
     * 获取档期每日小丑宝箱进度
     */
    public function getDailyChestStep($uid) {
        $key = okeys::userDailyChest($uid);
        //获取当前购买到哪一步
        $step = (int)oo::commonOprRedis('user')->get($key);
        if(empty($step)){
            //23小时重置一次
            oo::commonOprRedis('user')->setex($key, 1, oo::redisRandomExpire(23 * 3600));
            $step = 1;
        }
        return $step;
    }
    /**
     * 获取商城每日小丑宝箱信息
     * @param int $uid
     * @return array
     */
    public function getDailyChest($uid, $cached = false) {
        $step = $this->getDailyChestStep($uid);
        //过期时间
        $expire = (int)oo::commonOprRedis('user')->get(okeys::daliyChestNextTime($uid));
        $actInfo = $this->getBindActivity($uid,'daily_chest',true);
        $info = ['step' => $step, 'expire'=> $expire, 'aid' => $actInfo['id']];
        if(empty($actInfo) && !$cached){
            return [];
        }

        if(empty($actInfo)){//防止活动结束后，玩家又买了宝箱不发货的问题
            $tmp = oo::commonOprRedis('user')->get(okeys::dailyChest($uid));
            return (array)json_decode($tmp, true);
        }
        $tmp = isset($actInfo['reward_conf']) ? (array)json_decode($actInfo['reward_conf'], true) : [];
        $prize = !empty($tmp['prize'])?$tmp['prize']:[];
        $list = [];
        foreach($prize as $v){
            if($v['id'] == $step){
                $info['currenty'] = $this->getFormattingProps($uid,$actInfo['id'],$v);
            }
            if($v['id'] == $step+1){
                $info['next'] = $this->getFormattingProps($uid,$actInfo['id'],$v);
                $info['nextStep'] = $v['id'];
            }
        }
        if(!oo::commonOprRedis('user')->get(okeys::dailyChest($uid))){ //保留3天
            oo::commonOprRedis('user')->setex(okeys::dailyChest($uid), json_encode($info), 3 * 24 * 3600);
        }
        return $info;
    }

    /**
     * 更新每日宝箱购买记录
     * @param int $uid
     */
    public function setDailyChestBuy($uid) {
        $chestInfo = $this->getDailyChest($uid);
        $aid = empty($chestInfo['aid']) ? 0 : $chestInfo['aid'];
        $step = empty($chestInfo['step']) ? 1 : $chestInfo['step'];
        //发放奖励
        $upStep = true;
        $key = okeys::userDailyChest($uid);
        $expire = IS_DEBUF ? 10 * 60 : 23 * 3600;
        $result = [];
        if(!empty($chestInfo['currenty'])){
            $rewards = $chestInfo['currenty'];
            $skin = isset($rewards['value'], $rewards['value']['skin']) ? $rewards['value']['skin'] : 0;
            $result = oo::commonOprModel('props')->rewardChest($uid,$rewards['propsId'], '商店购买每日宝箱:'.$step, 410, $skin);
            if(!empty($result['joker'])){ //开出小丑卡，直接重置步骤
                oo::commonOprRedis('user')->setex($key, 1, oo::redisRandomExpire($expire + 600));
                $upStep = false;
            }
        }

        //获取当前购买到哪一步
        if(!empty($chestInfo['nextStep'])){
            if($upStep){ //23小时重置一次
                oo::commonOprRedis('user')->setex($key, $chestInfo['nextStep'], oo::redisRandomExpire($expire + 600));
            }
            //更新购买倒计时,每23小时更新一次
            $expire = (int)oo::commonOprRedis('user')->setex(okeys::daliyChestNextTime($uid), $expire+time(), $expire+600);
        }
        //删除缓存记录
        oo::commonOprRedis('user')->delete(okeys::dailyChest($uid));

        //统计记录
        oo::commonOprRedis('statistics')->hIncrBy(okeys::daliyChestLog(date('Ymd')), $step, 1);
        if(oo::commonOprRedis('statistics')->ttl(okeys::daliyChestLog(date('Ymd'))) == -1){ //保留3天
            oo::commonOprRedis('statistics')->expire(okeys::daliyChestLog(date('Ymd')), oo::redisRandomExpire(3 * 24 * 3600));
        }
        $data = [
            'treasureChest' => $result,
            'chestInfo'     => $this->getDailyChest($uid),
        ];
        return $data;
    }
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //>>>>>>>>>>>>>>>>>>>>>>小玩法收集>>>>>>>>>>>>>>>>>>>>>
    /**
     * Notes:新增空闲的小玩法收集物
     * User: wsc
     * Time: 2021/4/6 17:56
     * @param $aid
     * @param $uid
     * @param int $num
     * @param int $bet
     * @return bool|array
     */
    public function addCollectChangeItem($aid,$uid,$num=0,$bet=1){
        if(!$num||!$aid){
            return false;
        }
        $key = okeys::activityUserCollectChangeInfo($uid,$aid);
        $aInfo = $this->getActivity($aid);
        $rewardCfg = json_decode($aInfo['reward_conf'],true);
        $count = $num==1?$rewardCfg['one_hit']:($num==2?$rewardCfg['two_hit']:$rewardCfg['three_hit']);
        $count = $count*$bet;
        $spareNum = oo::commonOprRedis('activity')->hIncrBy($key,'spareNum',$count);
        $data =["count"=>$count,"spareNum"=>$spareNum,"place"=>0];
        if($rewardCfg['item']==1){
            $prace = oo::commonOprRedis('activity')->hGet($key,'place');
            $data['place'] = intval($prace);
        }
        return $data;
    }

    /**
     * Notes:埋雷/回收(只需第一次设置雷位置)
     * User: wsc
     * Time: 2021/4/6 20:15
     * @param $uid
     * @param int $place
     * @return array
     */
    public function buryItem($uid,$place=0,$levelId=0){
        $aid = $this->activityLock($uid,'change_collect');
        if(!$aid){
            return null;
        }
        $key = okeys::activityUserCollectChangeInfo($uid,$aid);
        $info = oo::commonOprRedis('activity')->hGetAll($key);
        if($info['itemType']!=1){//收集不是埋雷返回 null
            return null;
        }
        if(!$place&&$levelId){//升级回收
            oo::commonOprRedis('activity')->hSet($key,'levelId',$levelId);
            $info['levelId'] = $levelId;
        }
        oo::commonOprRedis('activity')->hSet($key,'place',$place);
        $info['place'] =  $place;
        return $info;
    }

    /**
     * Notes:发放雷坑奖励
     * User: wsc
     * Time: 2021/4/7 11:37
     * @param $uid
     * @param $touid
     * @param $place
     * @param $t 0主动触发 1被动触发(老版本偷新版本)
     * @return string
     */
    public function sendItemReward($uid,$toUid,$place,$t=0){
        $aid = $this->activityLock($toUid,'change_collect');
        if(!$aid){
            return oo::response(errorCode::NOT_FOUND_ACTIVITY,[],'被偷用户活动不存在');
        }
        $key = okeys::activityUserCollectChangeInfo($toUid,$aid);
        $info = oo::commonOprRedis('activity')->hGetAll($key);
        if($t==1){
            $place = $info['place'];
        }
        if($info['place']!=$place||!$info['spareNum']){
            return oo::response(errorCode::NONE_REWARD,[],'坑位无奖励');
        }
        //挖坑者领奖
        $coins = $this->getCoinRewardByTypeAndLevel('rank',$info['levelId']);
        if(!$t){
            oo::commonOprModel('member')->sendReward($uid,14,$coins,225,"挖{$toUid}坑{$place}雷{$info['spareNum']}个");
        }
        //被挖者发奖
        $coin2 = $coins*intval($info['spareNum']);
        $uidInfo = oo::commonOprModel('member')->getUserInfo($uid);
        oo::commonOprModel('member')->sendReward($toUid,14,$coin2,226,"被{$uid}挖坑{$place}雷{$info['spareNum']}个");
        //减雷
        oo::commonOprRedis('activity')->hSet($key,'spareNum',0);
        oo::commonOprRedis('activity')->hSet($key,'place',0);//重置位
        //推送
        $nick = oo::commonOprModel('member')->getUserFirstName($uidInfo['nick']);
        $data = ["uid"=>$uid,"nick"=>$nick, "coins"=>$coin2,"s_picture"=>$uidInfo['s_picture'],'u_flag'=>$uidInfo['u_flag'],'avatar'=>$uidInfo['avatar']];
        if(oo::commonOprModel('Workerman')->isUidOnline($toUid)){//在线
            oo::commonOprModel('Workerman')->push($toUid,ocmd::$send['BuryItemReward'],$data);
        }else{//不在线
            oo::commonOprModel('message')->addMessage($toUid,$uid,$nick,$uidInfo['s_picture'],$coin2,12,0,[]);
        }
        return oo::response(1,["coins"=>$coins]);
    }
    //=====================兼容新key兼容======================

    /**
     * Notes:获取购买超级连环礼包次数记录
     * User: wsc
     * Time: 2021/9/22 12:29
     * @param $aid
     * @param $uid
     * @param int $gid
     */
    public function getBuySuperSerialPackLimit($aid,$uid,$gid){
        $key =okeys::buySuperSerialPackTimes($aid,$uid);
        $limit = oo::commonOprRedis('activity')->hGet($key,$gid);
        if(!$limit){
            $limit = intval(oo::commonOprRedis('activity')->hGet(okeys::buySuperSerialPackLimit($aid),$uid.'_'.$gid));
            if($limit>0){
                oo::commonOprRedis('activity')->hSet($key,$gid,$limit);
            }
        }
        return  $limit;
    }

    /**
     * Notes:设置超级连环礼包购买记录
     * User: wsc
     * Time: 2021/9/22 14:15
     * @param $aid
     * @param $uid
     * @param $gid
     * @return int
     */
    public function addBuySuperSerialPackLimit($aid,$uid,$gid){
        $key = okeys::buySuperSerialPackTimes($aid,$uid);
        $key2= okeys::buySuperSerialPackLimit($aid);
        $limit2=0;
        $limit1 = oo::commonOprRedis('activity')->hIncrBy($key,$gid,1);
        if(time()<strtotime('2021-09-29')) {
            $limit2 = oo::commonOprRedis('activity')->hGet($key2, $uid . '_' . $gid);
        }
        if($limit2>$limit1){
            oo::commonOprRedis('activity')->hSet($key,$gid,$limit2);
            oo::commonOprRedis('activity')->expire($key,3*86400);
            $limit1 =$limit2;
        }
        return $limit1;
    }

    /**
     * Notes:获取用户宝藏活动数据缓存
     * User: wsc
     * Time: 2021/9/23 15:20
     * @param $aid
     * @param $uid
     * @param $type
     * @return mixed
     */
    public function getUserTreasureCacheLog($aid,$uid,$type){
        $key = okeys::TreasureGameLog($aid,$uid);
        $type2 = $this->treasureCacheKey[$type];
        $ret = oo::commonOprRedis('activity')->hGet($key,$type2);
        switch ($type){
            case "GiftReceiveStatus"://入门礼物领奖状态(okeys::TreasureTaskGift)
                if(!$ret){//老版本
                    $ret = oo::commonOprRedis('Activity')->hGet(okeys::TreasureTaskGift($aid),$uid);
                    if($ret){
                        $this->setUserTreasureCacheLog($aid,$uid,$type,$ret);
                    }
                }
                break;
            case "GiftPackBuyStatus"://礼包购买状态(okeys::treasureQuestGiftLog)
                if(!$ret){//老版本
                    $ret =oo::commonOprRedis('activity')->hGet(okeys::treasureQuestGiftLog($aid), $uid);
                    if($ret){
                        $this->setUserTreasureCacheLog($aid,$uid,$type,$ret);
                    }
                }
                break;
            case "TaskOverLimit"://任务完成次数(okeys::TreasureTaskNum)
                if(!$ret){
                    $ret = oo::commonOprRedis('User')->hGet(okeys::TreasureTaskNum($aid),$uid);
                    if($ret){
                        $this->setUserTreasureCacheLog($aid,$uid,$type,$ret);
                    }
                }
                break;
            case "TaskCurTaskId"://当前任务id(okeys::TreasureTaskId)
                if(!$ret){
                    $ret =oo::commonOprRedis('User')->hGet(okeys::TreasureTaskId($aid),$uid);
                    if(!$ret){
                        $this->setUserTreasureCacheLog($aid,$uid,$type,1);
                        $ret=1;
                    }else{
                        $this->setUserTreasureCacheLog($aid,$uid,$type,$ret);
                    }
                }
                break;
            case "TaskCurType"://当前任务类型(okeys::TreasureCurTaskType)
                if(!$ret){
                    $ret = oo::commonOprRedis('Activity')->hGet(okeys::TreasureCurTaskType($aid),$uid);
                    if($ret){
                        $this->setUserTreasureCacheLog($aid,$uid,$type,$ret);
                    }
                }
                break;
        }
        return $ret;
    }

    /**
     * Notes:设置用户宝藏活动数据缓存
     * User: wsc
     * Time: 2021/9/23 15:21
     * @param $aid
     * @param $uid
     * @param $type
     * @param int $d
     * @return bool|int
     */
    public function setUserTreasureCacheLog($aid,$uid,$type,$d=1){
        $type = $this->treasureCacheKey[$type];
        $key = okeys::TreasureGameLog($aid,$uid);
        $ret = oo::commonOprRedis('activity')->hSet($key,$type,$d);
        if(time()<strtotime('2021-09-29')){
            oo::commonOprRedis('activity')->expire($key,86400);
        }
        return $ret;
    }
    public function addUserTreasureCacheLog($aid,$uid,$type,$d=1){
        if(!in_array($type,["TaskOverLimit","TaskCurTaskId","GiftPackBuyStatus"])){

        }
        $type2 = $this->treasureCacheKey[$type];
        $key = okeys::TreasureGameLog($aid,$uid);
        if(time()<strtotime('2021-09-29')){
            oo::commonOprRedis('activity')->expire($key,86400);
        }
        $ret = oo::commonOprRedis('activity')->hIncrBy($key,$type2,$d);
        return $ret;
    }

    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    /**
     * Notes:获取活动个人数据
     * User: wsc
     * Time: 2020/7/24 12:01
     * @param $uid
     * @param $aid
     * @return array|boolean
     */
    public function getUserActData($uid,$type,$aid='',$actData=''){
        $aid = $aid?$aid:$this->getBindActivity($uid,$type);
        if(!$aid){
            return false;
        }
        $info =[];
        //收集偷打
        if(in_array($type,["super_collect"])){
            $reward = $this->getBindActivityRewardCfg($uid,$aid);//奖励配置
            $stageInfo = $this->getUserActStageInfo($uid,$aid);//阶段信息
            $this_rate = intval($stageInfo['rate']);
            $this_stage = intval($stageInfo['stage']);
            $prize = $reward['list'][$stageInfo['stage']]['prize'];
            $total = array_column(array_column($reward['list'],"prize"),"num");
            if(count($reward['list'])<intval($stageInfo['stage'])){
                $this_stage = intval(count($reward['list']));
                $this_rate = $reward['list'][$this_stage]['stepnum'];
                $prize = null;
            }
            $info = [
                "stage"     =>$this_stage,
                "num"       =>$this_rate,
                "maxNum"    => $reward['list'][$this_stage]['stepnum'], //当前阶段最大值
                "total"     => $total, //最大值
                "spinRange" => [$reward['star'],$reward['end']], //体力范围
            ];
            $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
            $value = $this->getCoinRewardByTypeAndLevel($type,$lv);//等级奖励配置
            //过度模式
            $oPrize = [];
            if(!empty($prize)&&is_array($prize)){
                $unsetArr = ['rtype', 'id', 'type', 'ts', 'is_ts'];
                foreach ($prize as $k=>$v){
                    $prize[$k] = array_merge($prize[$k],$this->getFormattingProps($uid,$aid,$v,$value));
                    $is_ts = $v['is_ts'];
                    foreach ($unsetArr as $s){
                        unset($prize[$k][$s]);
                    }
                    if($is_ts==1){
                        $oPrize[] = $prize[$k];
                        unset($prize[$k]);
                        continue;
                    }
                }
                $down_ts = intval(oo::commonOprRedis('config')->ttl(okeys::timeLimitAct($aid)));
                $info['ts'] =$down_ts>0?$down_ts + time():0;
            }
            $info['prize'] = $prize?array_values($prize):null;
            $info['oprize'] = array_values($oPrize);
            if($type=='super_collect'){
                $actData = $this->getActivity($aid);
                $down_bet_ts = intval(oo::commonOprRedis('config')->ttl(okeys::timeLimitBetAct($aid)));
                $info['bet_ts'] =$down_bet_ts>0?$down_bet_ts + time():0;//收集限时bet
                $extraData =!empty($actData['extraData'])?json_decode($actData['extraData'],true):[];
                $info['bet'] = isset($extraData['bet'])&&intval($extraData['bet'])>1?intval($extraData['bet']):1;//限时收集bet值
            }
        }
        //体力加速
        else if($type=='speed_spins'){
            $info =[
                'bet'      => intval(oo::commonOprRedis('common')->get(okeys::SpeedUpSpins($uid))),//加速的倍数
                'lastTime' => max(0,oo::commonOprRedis('common')->ttl(okeys::SpeedUpSpins($uid))),//加速到什么时候
            ];
            $refreshSpinsTime = max(oo::commonOprModel('user')->refreshSpins($uid,0),0);
            $dts =0;
//            $dts = $info['lastTime'];
//            if($refreshSpinsTime<$dts){
//                $dts = $refreshSpinsTime/2;
//            }
            $info['spinNextTime'] = $refreshSpinsTime +time()-$dts;
        }
        //排行榜
        else if($type=="rank" || $type=="rank2"){
            $info = $this->getUserRankData($uid,$aid,$type);
        }
        //连环礼包
        else if($type=="chain_gift"){
            $SerialPackGid = [710,711,712];
            foreach ($SerialPackGid as $row){
                $times = intval(oo::commonOprRedis('activity')->hGet(okeys::buyChainGiftLimit($aid),$uid.'_'.$row));
                $info["useTimes"][] = [
                    'gid'  => $row,
                    'times'=> $times,
                ];
            }
        }
        //气球活动
        else if(in_array($type,["balloon","balloon_tg"])){
            $info['waves'] = $this->setUserActRate($uid,$aid,0);//当前第几波气球
        }
        else if($type=='architecture'){//建筑大师
            $info =  $this->getUserBuildConf($uid,$aid);
        }
        else if($type=='crazy_card_group'){
            $info = [];
        }
        //限时邀请
        else if($type=='time_limit_invite'){
            $info['inviteList'] = $this->getUserInviteActData($uid,$aid);
            $info['reward'] = $this->getInviteReward($uid,$aid);
            $info['applyStatus'] =$this->applyActivity($uid,$aid,1);
        }
        else if($type=='shop_promotion'){
            $info['joinStatus'] = $this->applyActivity($uid,$aid,1);
            $info['buyNum'] = intval(oo::commonOprRedis('common')->hget(okeys::ShopPromotionBuyNumber(),$uid));
        }
        //累计充值
        else if($type=='accumulated_pay'){
            $info['reward'] = $this->getSumPayActReward($uid,$aid);
            $lastNum = oo::commonOprRedis('activity')->get(okeys::activitySumPayNum($aid,$uid));
            $info['progressNum'] = intval($lastNum/1000);
            $info['betNum'] = 100;
        }
        else if($type == "treasure"){
            $info['baseData']  = [
                "openLv"    => 6,
                "reward"    => $this->getTreasureGift($uid,true),
//                "isReward"  => intval(oo::commonOprRedis('Activity')->hGet(okeys::TreasureTaskGift($aid),$uid)),
                "isReward"  => intval($this->getUserTreasureCacheLog($aid,$uid,"GiftReceiveStatus")),
                "protectTime"     => 180,
//                "pointGiftStatus" => intval(oo::commonOprRedis('activity')->hGet(okeys::treasureQuestGiftLog($aid), $uid)),
                "pointGiftStatus" => intval($this->getUserTreasureCacheLog($aid,$uid,"GiftPackBuyStatus")),
            ];
            $info['curData'] = [
                "taskId"  => $this->getUserTreasureCurTaskId($aid,$uid),
//                "taskNum" => intval(oo::commonOprRedis('User')->hGet(okeys::TreasureTaskNum($aid),$uid)),
                "taskNum"=>intval($this->getUserTreasureCacheLog($aid,$uid,"TaskOverLimit"))
            ];
        }
        //通行證
        else if($type=='traffic_permit'){
            $passInfo = oo::commonOprRedis('activity')->hGetAll(okeys::GamePassInfo($aid, $uid));
            $info['curNum'] = $passInfo['exp'];
            $info['normalList'] = $passInfo['receive_normal'];
            $info['specialList'] = $passInfo['receive_special'];
            $info['isBuy'] = $passInfo['buy'];
        }
        else if($type=='discounts_architecture'){
            $info['conf']=$this->getActReward($aid)['reward'];

        }
        //超级连环礼包
        else if($type=='super_serial_pack'||$type=='super_serial_pack2'){
            $reawrd = $this->getCGReward($uid,$aid);
            foreach ($reawrd as $v){
                $times = $this->getBuySuperSerialPackLimit($aid,$uid,$v['gid']);
                $info["useTimes"][] = [
                    'gid'  => $v['gid'],
                    'times'=> $times,
                ];
            }
        }
        //体力存钱罐
        else if($type=='spin_safe'){
            $info['extraData']  = $this->getSteelSafeLimitReward($aid,$uid);
            $info['curCollect'] = $this->getSteelSafeCurNum($aid,$uid);
            $info['state']      = $this->getSteelSafeCurProgress($aid,$uid);
        }
        //体力大师
        else if($type=='spins_master'){
            $info['reward'] = $this->getCommonRateReward($uid,$aid,'spins_master');
            $lastNum = oo::commonOprRedis('activity')->get(okeys::activityCommonRateSumScore($aid,$uid));
            $info['progressNum'] = intval($lastNum);
        }
        //基金活动
        else if($type=='fund'){
            $info['buyNum']       = $this->getBuyFundStatus($aid,$uid);
            $info['rewardStatus'] = $this->getTodayRewardStatus($aid,$uid);
            $info['rewardId']     = $this->getFundRewardDayId($aid,$uid);
            $info['rewardList']   = $this->getFundRewardList($aid,$uid);
            $info['reissueList']  = $this->getFundReissue($aid,$uid);
        }
        //宝藏活动
        else if($actData['type']=='treasure'){
            $extraData = json_decode($actData['extraData'],true);
            $actInfo['userData']['baseData']['openLv'] = $extraData['openLv'];
        }
        //四选一活动活动
        else if($type=='easter_egg'){
            $info = $this->getUserEasterEggInfo($uid);
        }
        //好友召回活动
        else if($type == 'callback_score'){
            $info = oo::commonOprModel('Callback')->getUserCallbackList($uid);
        }
        //每日宝箱
        else if($type == 'daily_chest'){
            $info = $this->getDailyChest($uid);
        }
        //小玩法收集
        else if($type=='change_collect'){
            $uinfo = oo::commonOprRedis('activity')->hGetAll(okeys::activityUserCollectChangeInfo($uid,$aid));
            $info = [
                "spareNum"=>intval($uinfo['spareNum']),
                "place"=>intval($uinfo['place']),
                "itemType"=>intval($uinfo['itemType']),
            ];
        }else if($type == 'one_plus_gift'){
            //1+1礼包
            $info['buyNum'] = intval(oo::commonOprRedis('activity')->hGet(okeys::onePlusGiftBuyNum($aid),$uid));//已购买次数
            $info['freeStatus'] = intval(oo::commonOprRedis('Activity')->hGet(okeys::onePlusGiftBuyStatus($aid),$uid));//免费状态
        }else if($type == 'safe_surprise'){
            //惊喜礼包
            $info['buyStatus'] = intval(oo::commonOprRedis('Activity')->hGet(okeys::safeSurpriseBuyStatus($aid),$uid));//购买状态
        }
        return $info?$info:false;
    }

    /**
     * Notes:获取兼容格式的活动数据
     * User: wsc
     * Time: 2020/7/24 12:01
     * @param $uid
     * @param $aid
     * @return array
     */
    public function getActivityData($uid,$aid){
        $actInfo = [];
        $actData = $this->getActivity($aid);
        $type = $actData['type'];
        $actInfo['activityData'] = [
            "aid"=>$aid,
            "name"=>$actData['name'],
            "activityType"=>$actData['cid'],
            "activityName"=>$actData['imgName'],
            "start"=>$actData['start']?$actData['start']:$actData['start_time'],
            "end" =>$actData['end']?$actData['end']:$actData['end_time'],
            "rewardTime" =>$actData['reward_time']?$actData['reward_time']:$actData['end_time']-120,
            "actType"=>$actData['type'],
            "showInCenter"=>$this->isShow($this->act_type[$actData['type']]['rcid'],1), //显示再奖励中心
            "showInButton"=>$this->isShow($this->act_type[$actData['type']]['rcid'],2), //显示右边按钮
            "showCountdown"=>$this->isShow($this->act_type[$actData['type']]['rcid'],3), //是否显示倒计时
            "isDirectShow"=>0
        ];
        if(in_array($type,$this->beOutShow)||$actData['uc_type']==1){//必显外部按钮
            $actInfo['activityData']['isDirectShow'] = 1;
        }
        $actInfo['activityData']['uc_type']=$actData['uc_type'];
        //排行榜
        if($actData['type']=="rank"){
            if(in_array($this->getCollectGroupType($uid),[1,2])){//有三个收集物时
                $actInfo['activityData']['model'] = 3;//兼容收集模式
            }else{
                $actInfo['activityData']['model'] = 2;//兼容偷打模式
            }
            $actInfo['activityData']['curNum'] = $this->getUserActStageInfo($uid,$aid)['rate'];//当前值
            $actInfo['activityData']['startNum']=5;//门槛
            $actInfo['activityData']['rankData'] = $this->getRankData($uid,$aid);//获取排行榜数据
            $config = $this->getRankStageRewardConf($uid,$aid,1);
            $actInfo['activityData']['config'] = $config?array_values($config):null;//阶段奖励配置
            $version = oo::commonOprModel('user')->getUserVersion($uid);
            //1.8.5排行榜添加礼包
            if(oo::compareVersion($version,'1.8.5')){
                $giftPath = isset($this->act_type[$actData['type']]['gift_name']) ? $this->act_type[$actData['type']]['gift_name'] : '';
                $actInfo['activityData']['rankingPackName'] = $giftPath;
            }
        }
        //排行榜无进度
        if($actData['type']=="rank2"){
            if(in_array($this->getCollectGroupType($uid),[1,2])){//有三个收集物时
                $actInfo['activityData']['model'] = 3;//兼容收集模式
            }else{
                $actInfo['activityData']['model'] = 2;//兼容偷打模式
            }
            $actInfo['activityData']['curNum'] = intval(oo::commonOprRedis('activity')->zScore(okeys::activityUserRankList($aid,0),$uid));//当前值
            $actInfo['activityData']['startNum']=5;//门槛
            $actInfo['activityData']['rankData'] = $this->getRankData($uid,$aid);//获取排行榜数据
        }
        //在bg里加入spine动画
        if($actData['type']=="super_collect"){
            $extraData = json_decode($actData['extraData'],true);
            $actInfo['activityData']['isShowSpine'] = empty($extraData['isShowSpine']) ? 0 : 1;
        }
        if(in_array($actData['type'],["rank","super_collect","rank2"])){
            $reward_conf = json_decode($actData['reward_conf'],true);
            $actInfo['activityData']['getNum'] =[
                0=>intval($reward_conf['attack_success']),
                1=>intval($reward_conf['attack_break']),
                2=>intval($reward_conf['steal_success']),
                3=>intval($reward_conf['steal_break']),
                4=>intval($reward_conf['three_hit']),
            ];
            $actInfo['activityData']['colorType'] = $actData['bcolor'];
            if($actData['type']=="super_collect"){
                $actInfo['activityData']['getNum'][] = intval($reward_conf['two_hit'])?intval($reward_conf['two_hit']):intval($reward_conf['tow_hit']);//过度错误字母
                $actInfo['activityData']['getNum'][] = intval($reward_conf['one_hit']);
                $actInfo['activityData']['groupId'] = intval($reward_conf['groupId']);//收集子类型
                if(in_array($reward_conf['groupId'],[8,9])){
                    $actInfo['activityData']['getNum'][] = intval($reward_conf['one_steal']);
                    $actInfo['activityData']['getNum'][] = intval($reward_conf['two_steal']);
                    $actInfo['activityData']['getNum'][] = intval($reward_conf['one_attack']);
                    $actInfo['activityData']['getNum'][] = intval($reward_conf['two_attack']);
                }
            }
        }
        //气球类
        if(in_array($actData['type'],["balloon","balloon_tg"])){
            $actInfo['activityData']['activityType'] =$actData['type']=='balloon'?1:2;
            $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
            if($lv==3){
                $actInfo['activityData']['end'] = strtotime('23:59:59');
            }
        }
        //倍率活动
        if(in_array($actData['type'],["crazy_bet","supper_bet"])){
            $configTemp  = $this->getActReward($aid);
            $config2     = $configTemp['reward']['conf'];
            $actInfo['activityData']['config'] = $config2?array_values($config2):null;
            if(!empty($configTemp['reward']['init']['spinsRange'])){
                foreach ($configTemp['reward']['init']['spinsRange'] as $row){
                    $actInfo['activityData']['spinsRanges'][] = [$row['spins'],$row['bet']];
                }
            }
        }
        //海报
        if(in_array($actData['type'],['poster_1','poster_2','poster_3'])){
            $actInfo['activityData']['config'] =
                [
                    'title'=>json_decode($actData['show_title'],true),
                    'btnName'=>json_decode($actData['bname'],true),
                    "btnImgId"=>$actData['bcolor'],//按钮颜色图片id
                    "jumpId"=>$actData['bskip'],//跳转位置
                    "jumpUrl"=>$actData['burl'] //跳转url
                ];
        }

        if($actData['type']=='crazy_card_group'){
            $config3 =$this->getCrazyCardGroupBet($uid,$aid);
            $actInfo['activityData']['config'] = $config3?$config3:[];
        }

        if($actData['type']=='architecture'){
            $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
            if($lv==2){
                $actInfo['activityData']['end'] = strtotime('23:59:59');
            }
        }
//        if($actData['type']=="jackpot"){//jackpot活动
//            $actInfo['activityData']['protectTime'] = 300;//保护时间
//            $actInfo['activityData']['curNum'] = oo::commonOprModel('activity')->getJackPotPool();//奖池起始值
//        }
        if($actData['type']=='golden_card_trade'){
            $actInfo['activityData']['cards'] = json_decode($actData['extraData'],true);
        }
        if($actData['type']=='time_limit_invite'){
            $actInfo['activityData']['rank']=$this->getInviteRank($aid);
            $actInfo['activityData']['config'] = json_decode($actData['reward_conf'],true);
        }
        if($actData['type']=='shop_promotion'){
            $rewardConf = $this->getActReward($aid);//奖励配置
            $actInfo['activityData']['config'] = $rewardConf['reward'];
        }
        if($actData['type']=='accumulated_pay'){//累充活动

        }
        if($actData['type']=='traffic_permit'){//通行證
            $extraData = json_decode($actData['extraData'],true);
            $rewarded = $this->getTrafficPermitRewarded($aid,$uid,"normal");
            if(in_array(0,$rewarded)){
                $actInfo['activityData']['openLv']    = $extraData['openLv'];
            }else{
                $version = oo::commonOprModel('user')->getUserVersion($uid);
                if(oo::compareVersion($version,'1.8.1')){
                    $actInfo['activityData']['openLv'] = $extraData['openLv'];
                }else{
                    $actInfo['activityData']['openLv'] = 6;
                }
            }
            $actInfo['activityData']['upLvDiamondNum'] = $extraData['upLvDiamondNum'];
            $actInfo['activityData']['guideLv']        = $extraData['guideLv'];
            $actInfo['activityData']['passExp']        = $extraData['passExp'];
            $actInfo['activityData']['itemColor']      = $extraData['itemColor'];
            $actInfo['activityData']['iconColor']      = $extraData['iconColor'];
            $actInfo['activityData']['maxLevelExpGap'] = $extraData['maxLevelExpGap'];
            $actInfo['activityData']['maxLevelReward'] = $this->makeTrafficPermitRewardConf($uid,$aid,$extraData['maxReward'],$this->getCoinRewardByTypeAndLevel('rank',oo::commonOprModel('member')->getUserLevel($uid)['levelId']));
            $actInfo['activityData']['rewardConfig']   = $this->getTrafficPermitRewardConf($aid,$uid);
            $actInfo['activityData']['taskConfig']     = $this->getTrafficPermitRewardConf($aid,$uid,"task",$extraData['task']??[]);
            $curSpendSpins = intval(oo::commonOprRedis('activity')->get(okeys::TrafficPermitSpendSpins($uid)));
            $actionTtl = false;
            $maxSpendSpins = [12=>200,13=>800,14=>2000];
            foreach ($actInfo['activityData']['taskConfig'] as $key=>$row){
                if(in_array($row['type'],[12,13,14])){
                    $actInfo['activityData']['taskConfig'][$key]['curSpendSpins'] = min($maxSpendSpins[$row['type']],$curSpendSpins);
                    $actionTtl = true;
                }
            }
            if($actionTtl){
                $ttl = intval(oo::commonOprRedis('activity')->ttl(okeys::TrafficPermitSpendSpins($uid)));
                if($ttl <= 0){
                    $lv = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
                    if($lv >= $actInfo['activityData']['openLv']){
                        oo::commonOprRedis('activity')->setex(okeys::TrafficPermitSpendSpins($uid),0,oo::todayDeadline());
                    }
                }
            }
        }

        if($actData['type']=='spin_safe'){
            $rewardConf = $this->getActReward($aid);
            $rewardConfig = [];
            foreach ($rewardConf['extra_reward']['config'] as $row){
                //$coins = intval(oo::commonOprModel('goods')->getGoodCoins($uid,$row['coins']) * $row['bet']);
                $spins = empty($row['spins']) ? 3 : $row['spins'];
                $rewardConfig[] = [
                    'progress' => $row['progress'],
                    'props' => [['propsId'=>15,'num'=>$spins,'value'=>$spins]],
                ];
            }
            $actInfo['activityData']['config'] = $rewardConfig;
        }

        if($actData['type']=='coin_blast'){
            $rewardConf = $this->getActReward($aid);
            $actInfo['activityData']['config'] = $rewardConf['reward'];
        }

        if($actData['type']=='premium'){
            $reward_conf = json_decode($actData['reward_conf'],true);
            $gidArr      = array_column($reward_conf['groupArr'],"gid");
            $userDynamicsData = oo::commonOprModel('member')->getUserDynamicsData($uid);
            $userGidArr  = array_filter(explode(',',$userDynamicsData['groupId2']));
            if(!array_intersect($gidArr,$userGidArr)){
                oo::commonOprRedis('activity')->delete(okeys::userBindActivity($type,$uid));
                return false;
            }
            $actInfo['activityData']['config']['spins'] = $reward_conf['spins'];
        }

        //超级气球
        if($actData['type']=='super_balloon'){
            $extraData =  json_decode($actData['extraData'],true);
            $actInfo['activityData']['config'] =["speed"=>$extraData['speed'],"moveType"=>$extraData['moveType']];
        }
        //通行证倍率
        if($actData['type']=='traffic_permit_bet'){
            $extraData =  json_decode($actData['extraData'],true);
            $actInfo['activityData']['config']["bet"] = $extraData['bet'];
        }
        //二选一活动
        if($actData['type']=='choose_one'){
            if(oo::commonOprRedis('Activity')->hGet(okeys::ChooseOneStatus($aid),$uid)){
                return false;
            }
        }
        //1+1礼包
        if($actData['type']=='one_plus_gift'){
            $reward_conf = json_decode($actData['reward_conf'],true);
            $actInfo['activityData']["maxNum"] = $reward_conf['maxNum'];//最大购买次数
            $buyNum = intval(oo::commonOprRedis('activity')->hGet(okeys::onePlusGiftBuyNum($aid),$uid));//已购买次数
            if($buyNum >= $actInfo['activityData']["maxNum"] && empty(intval(oo::commonOprRedis('activity')->hGet(okeys::onePlusGiftBuyStatus($aid),$uid)))){
                return false;
            }
            $onePlusGift = oo::commonOprModel('activitynew')->getActivityGoods($uid,"one_plus_gift");
            $actInfo['activityData']['freeInfo'] = $onePlusGift[1]['props'];
        }
        //二选一活动
        if($actData['type']=='safe_surprise'){
            if(oo::commonOprRedis('Activity')->hGet(okeys::safeSurpriseBuyStatus($aid),$uid)){
                return false;
            }
        }
        //基金活动
        if($actData['type']=='fund'){
            $actInfo['activityData']['config'] = $this->getFundConfig($aid,$uid);
            $ttl = oo::commonOprRedis("Activity")->ttl(okeys::FundAid($uid));
            if($ttl > 0){
                $actInfo['activityData']['end'] = $ttl + time();
            }
        }
        if($actData['type']=='collect_bet'){
            $reward_conf = json_decode($actData['reward_conf'],true);
            $actInfo['activityData']['bet'] = $reward_conf['bet']?$reward_conf['bet']:2;
        }
        if($actData['type']=='easter_egg'){
            $actInfo['activityData']['config'] = array_values($this->getEggInfo($uid,$aid));
        }
        //宝藏
        if($actData['type']=='treasure'){
            $actInfo['activityData']['pointData'] = oo::commonOprModel('config')->getTreasureQuestPointConfig();
        }
        //体力大师
        if($actData['type']=='spins_master'){
            $actInfo['activityData']['rewardTime'] = $actInfo['activityData']['end'];//兼容1.8.5之前的版本不加积分问题
        }

        //个人特殊时限活动(道具活动)
        if($this->isInSpecialAct($uid,$type)){
            $ts = intval(oo::commonOprRedis('activity')->ttl(okeys::userSpecialAct($uid,$type)));
            $ts = $ts>0?$ts:0;
            $actInfo['activityData']['end'] = time()+$ts-1;
        }
        //四选一活动(特殊处理)
        if($actData['type']=='easter_egg'){
            $actInfo['activityData']['end'] = $actInfo['activityData']['end']-60;
        }

        $actInfo['userData'] = $this->getUserActData($uid,$actData['type'],$aid,$actData);//不能先于activityData生成

        if($actData['type']=='treasure'){//宝藏活动
            $extraData = json_decode($actData['extraData'],true);
            $actInfo['userData']['baseData']['openLv'] = $extraData['openLv'];
            $actInfo['activityData']['pointData'] = oo::commonOprModel('config')->getTreasureQuestPointConfig();
        }

        if($actData['type'] == 'callback_score'){
            $actInfo['userData'] = oo::commonOprModel('callback')->getUserCallbackList($uid);
        }
        if($actData['type'] == 'daily_chest'){
            $actInfo['userData'] = $this->getDailyChest($uid);
        }

        $actInfo['activityData']['jumpId'] =$actData['bskip'];//跳转位置
        return $actInfo;
    }

    /**
     * Notes:当前活动的外部显示按钮，内部显示，内部倒计时，等显示状态
     * User: wsc
     * Time: 2020/10/29 15:03
     * @param $id
     * @param int $type
     * @return int|mixed
     */
    public function isShow($id,$type=1){
        $show = oo::commonOprRedis('common')->hGet(okeys::actCenterShowType($type),$id);
        return ($show == false)?0:$show;
    }

    /**
     * Notes:活动是否开放 （针对人群）
     * User: wsc
     * Time: 2020/7/22 12:23
     * @param $uid  -用户id
     * @param $type -活动类型
     * @param $info -是否显示活动详情
     * @return array|bool
     */
    public function activityLock($uid,$type,$info=false){
        $types = array_keys($this->act_type);
        if(!in_array($type,$types)){
            return false;
        }
        $aid = $this->getBindActivity($uid,$type);
        if($type == "fund"){
            $lastAid = intval(oo::commonOprRedis("Activity")->get(okeys::FundAid($uid)));
            $lastAid && $aid = $lastAid;
        }
        if(empty($aid)){
            return false;
        }
        if(!$info){
            return $aid;
        }
        $actInfo= $this->getActivityData($uid,$aid);
        return $actInfo;
    }

    // 通过等级范围获取通行证奖励
    public static function findPassRewardConfByLvRange($uid, $aid)
    {
        $key = okeys::activityUserStageKey($uid, $aid);
        $stage       = oo::commonOprRedis('activity')->get($key);
        $reward_conf = oo::commonOprRedis('activity')->hget(okeys::activityInfo($aid), 'reward_pro');
        $reward_conf = json_decode($reward_conf ?: "[]", true);
        return $reward_conf[$stage] ?? [];
    }

}
