<?php
defined( 'IN_WEB') or die( 'Include Error!');
class ModelCard{
    CONST MAX_ACCEPT_TIME  = 5; //每日接受卡片最大上限
    CONST CARD_LIMIT = 5;

    /**
     * @param $uid
     * @return Array
     * Created by: Cassie Lee
     * Created on: 2019/5/15 21:40
     * Description:获取卡片信息
     */
    public function getInfo($uid){
        $res = [];
        $cards = $this->getCardInfo();
        foreach ($cards as $items){
            $card[$items['ciid']] = $items['cgposition'];//ciid->位置
        }
        foreach ($cards as $items){
            $group[$items['ciid']] = $items['cgid'];//ciid->卡组id
        }
        $userCardInfo = self::getUserCardInfo($uid);
        if(!empty($userCardInfo)) {
            $cardNumData = $userCardInfo['ciid'];
            $groupTemp = [];
            foreach ($card as $ciid => $pos) {
                foreach ($group as $ci => $cgid) {
                    if(!in_array($cgid,$groupTemp)){
                        $res[$cgid][1] = -1;
                        $groupTemp[] = $cgid;
                    }
                    if($ciid == $ci) {
                        if (key_exists($ciid, $cardNumData)) {
                            $res[$cgid][$card[$ciid]] = intval($cardNumData[$ciid]);
                        }
                    }
                }
            }
            foreach ($res as $key => $row) {
                foreach ($row as $x => $y) {
                    if($y == -1){
                        unset($res[$key][$x]);
                        if(empty($res[$key])){
                            unset($res[$key]);
                        }
                    }
                }
            }
            return $res;
        }else{
            return [];
        }
    }

    /**
     * 根据Ciid 获取卡片信息
     * @param $ciid
     * @return mixed|void
     * Created by: Owen
     * Created on: 2021/3/9 17:55
     */
    public function getCardInfoByCiid($ciid){
        $arrJson = oo::commonOprRedis('config')->hGet(okeys::CardConfig(),$ciid);
        if(!empty($arrJson)){
            return json_decode($arrJson,true);
        }
        $tb  = otable::cardinfo_config();
        $ret = oo::commonOprDb('cardinfo')->getOne("SELECT * FROM {$tb} WHERE ciid={$ciid} LIMIT 1", MYSQLI_ASSOC);
        return $ret;
    }

    /**
     * @param $cgid
     * @param $pos
     * @return mixed
     * Created by: Cassie Lee
     * Created on: 2019/5/15 21:41
     * Description:根据卡片位置及卡组信息返回卡片id ciid
     */
    private function getCardId($cgid, $pos){
        $cardInfo = otable::cardinfo_config();
        $sql = "SELECT ciid FROM {$cardInfo} WHERE cgid = {$cgid} AND cgposition = {$pos}";
        $list = oo::commonOprDb('cardinfo')->getOne($sql, MYSQLI_ASSOC);
        $ciid = $list['ciid'];
        return $ciid;
    }

    /**
     * @param $uid 用户uid
     * @param $cgid 卡片组id
     * @param $pos  组id
     * @param $sendToUid 对方uid
     * @param $num 数量
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/14 10:52
     * Description:赠送卡片
     */
    public function sendTo($uid, $cgid, $pos , $sendToUid, $num)
    {
        $ciid = $this->getCardId($cgid,$pos);
        //获取自己的卡片信息
        $cardInfoList = $this->getInfo($uid);
        //获取卡片数量
        $totalCardNum = intval($cardInfoList[$cgid][$pos]) - 1; //自己必须保留一张

        if($totalCardNum < 1){
            return array("code"=> -1,"msg"=>"您的卡片数量不足",'data'=>[]);
        }
        //1 获取已赠送卡片数量
        $sendNum = $this->getSendNumber($uid,$ciid,$sendToUid);
        if($sendNum && ($sendNum > self::CARD_LIMIT || $sendNum == self::CARD_LIMIT ))
        {
            return array("code"=> -1,"msg"=>"只能赠送".self::CARD_LIMIT."张卡片");
        }

        //我向好友赠送礼物  添加到队列里面去 领取了就prop
        $key = okeys::userGiftList($sendToUid);
        //要记录 谁送的 时间 赠送卡组 赠送卡片 数量 {"fromId":327,"time":1558076971,"pos":6,"cgid":8,"num":1}
        $recordData =  json_encode(['fromId'=>$uid,'time'=>time(),'pos'=>intval($ciid),'cgid'=>intval($cgid),'num'=>1]);
        $res = $this->updateOwnCardQuantity($uid,$ciid,$num,$sendToUid);
        //添加成功后在扣用户的卡
        if($res['code'] < 0)
        {
            return array("code"=> $res['code'],"msg"=>$res['msg']);
        }
        oo::commonOprRedis('common')->lPush($key, $recordData);
        $cardInfo = $this->getInfo($uid);

        ////赠送卡片排行榜,取消该统计
        //oo::commonOprModel('statistics')->giveCardSta($ciid);

        return array("code"=>1,"msg"=>1,"data"=>['card'=>$cardInfo]);
    }

    /**
     * @param $uid
     * @param $ciid
     * @param $sendToUid
     * @return int
     * Created by: Cassie Lee
     * Created on: 2019/5/14 12:11
     * Description:获取赠送卡片的数量
     */
    public function getSendNumber($uid, $ciid, $sendToUid)
    {
        $cardInfo = self::getUserCardInfo($uid);
        if(!empty($cardInfo)){
            if(!empty($cardInfo['send_card'])){
                $sendcard = $cardInfo['send_card'];
                return $sendcard[$sendToUid][$ciid]??0;
            }else{
                return 0;
            }
        }else{
            return 0;
        }
    }

    /**
     * @param $uid
     * @param $ciid
     * @param $askForUid
     * @param $num
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/14 11:41
     * Description:索要卡片
     */
    public function askFor($uid, $ciid, $askForUid, $num)
    {
        $flag = $this->validateCard($ciid,$uid);
        if(!$flag)
        {
            return array("code"=> -1,"msg"=>"不符合索要条件");
        }
        $res = $this->sendMessageTo($uid,$askForUid,5);
        if($res)
        {
            return array('code'=> 1,'msg'=>"success");
        }
        return array('code'=> -1,'msg'=>"failed");
    }

    /**
     * @param $uid
     * @param $toUid
     * @param $type
     * @return mixed
     * Created by: Cassie Lee
     * Created on: 2019/5/14 11:37
     * Description:$uid 当前用户uid $toUid 被索要用户uid $type  所属类型 1被偷钱  2防御成功  3损坏建筑  4摧毁建筑 5索要卡片
     */
    public function sendMessageTo($uid, $toUid, $type){
        $uidInfo = oo::commonOprModel('member')->getUserInfo($uid);
        $is_read = 0;//是否已读
        //******  存入数据库提供查询  ******
        $toTable = otable::messageLog($toUid);
        $start_time = time();
        $end_time = strtotime('+30day');
        $nick = $uidInfo['nick'];
        $s_picture = $uidInfo['s_picture'];
        $sql = " INSERT INTO $toTable VALUES($toUid,$uid,'$nick','$s_picture', 0,$type,$is_read , $start_time,$end_time,0)";
        $res = oo::commonOprDb('message_log')->query($sql);
        return $res;
    }

    /**
     * 更新卡片赠送者的卡片数量
     * @param $uid
     * @param $ciid
     * @param $num
     * @param $sendToUid
     * @return array
     * Created by: Owen
     * Created on: 2020/3/25 16:46
     */
    public function updateOwnCardQuantity($uid, $ciid,$num,$sendToUid){
        $userCardInfo = self::getUserCardInfo($uid);
        $sendCard = $userCardInfo['send_card'];
        $obj      = $userCardInfo['ciid'];
        if(intval($obj[$ciid]) >= (intval($num) + 1)) {
            $obj[$ciid] = intval($obj[$ciid]) - intval($num);//对应卡片数量 - num
            $sendCard[$sendToUid][$ciid] += $num;
            self::updateUserCardInfo($uid,['ciid'=>$obj,'send_card'=>$sendCard]);
            return array("code"=>1,"msg"=>"update success");
        }else {
            return array("code"=> -3,"msg"=>"卡片不足");
        }
    }

    /**
     * @param $uid
     * @param $ciid
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/13 11:44
     * Description:更新被赠送者卡片数量
     */
    public function updateFriendsCardQuantity($uid, $ciid,$num){
        $userCardInfo = self::getUserCardInfo($uid);
        $obj = $userCardInfo['ciid'];
        $obj[$ciid] = strval(intval($obj[$ciid]) + intval($num));//对应卡片数量+num
        $res = self::updateUserCardInfo($uid,['ciid'=>$obj]);
//        return array("code"=>$res['code'],"msg"=>"success");
        return array("code"=>$res?1:0,"msg"=>"success");
    }

    /**
     * @param $uid
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/10 14:44
     * Description:获取好友列表
     */
    public function getFriendList($uid)
    {
        $data = [];
        $friendList = [];
        oo::commonOprModel('friend')->getUserFriends($uid, $friendList);
        $Info = $this->getUserWatchmeInfoNew($friendList);
        foreach ($Info as $key => $value)
        {
            $data[] = $value;
        }
        if (!empty($friendList['game_list']) || !empty($friendList['poker'])) {
            $res = array('code' => 1,'msg'=>'success','data'=>$data);
            return $res;
        }else{
            $res = array('code' => -1,'msg'=>'failed','data'=>array());
            return $res;
        }
    }

    /**
     * 获取用户信息
     * @param $userWatchmeList
     * @return array
     * Created by: Owen
     * Created on: 2019/8/29 11:37
     * Description:
     */
    private function getUserWatchmeInfoNew($userWatchmeList)
    {
        $data = [];
        if(empty($userWatchmeList['game_list'])){
            return $data;
        }
        $userWatchme = explode(",",$userWatchmeList['game_list']);
        $userWatchme = array_filter($userWatchme);
        $arr = ['uid','nick','s_picture','u_flag','siteuid'];
        foreach ($userWatchme as $key => $value)
        {
            //玩家基本信息
            $memberInfo = oo::commonOprModel('member')->getUserInfo($value,$arr,false,NULL);
            //检测是否可以领取
            $accept = $this->checkAcceptAuth($memberInfo['uid']);
            //组成新的array
            $data[$memberInfo['uid']]['url'] = $memberInfo['s_picture'];
            $data[$memberInfo['uid']]['nick'] = $memberInfo['nick'];
            $data[$memberInfo['uid']]['isSended'] = $accept;
            $data[$memberInfo['uid']]['uid'] = intval($memberInfo['uid']);
            $data[$memberInfo['uid']]['flag'] = intval($memberInfo['u_flag']);
            $isVisitor = oo::commonOprModel('member')->isVistor($memberInfo['uid']);
            if($isVisitor != 1){
                $data[$memberInfo['uid']]['fbId'] = (string)$memberInfo['siteuid'];
            }
        }

        $poker = explode(",",$userWatchmeList['poker']);
        $poker = array_filter($poker);
        foreach ($poker as $key => $value)
        {
            //玩家基本信息
            $memberInfo = oo::commonOprModel('member')->getUserInfo($value,$arr,false,NULL);
            //检测是否可以领取
            $accept = $this->checkAcceptAuth($memberInfo['uid']);
            //组成新的array
            $data[$memberInfo['uid']]['url'] = $memberInfo['s_picture'];
            $data[$memberInfo['uid']]['nick'] = $memberInfo['nick'];
            $data[$memberInfo['uid']]['isSended'] = $accept;
            $data[$memberInfo['uid']]['uid'] = intval($memberInfo['uid']);
            $data[$memberInfo['uid']]['flag'] = intval($memberInfo['u_flag']);
            $isVisitor = oo::commonOprModel('member')->isVistor($memberInfo['uid']);
            if($isVisitor != 1){
                $data[$memberInfo['uid']]['fbId'] = (string)$memberInfo['siteuid'];
            }
        }
        return $data;
    }

    /**
     * @param $fuid
     * @return bool
     * Created by: Cassie Lee
     * Created on: 2019/5/10 15:20
     * Description:检测是否領過卡片
     */
    private function checkAcceptAuth($fuid)
    {
        $time = 0;//写死
        if($time <= self::MAX_ACCEPT_TIME)
        {
            return false;
        }
        return true;
    }

    /**
     * @param $uid
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/13 20:18
     * Description:卡片集满获取奖励
     */
    public function calCardReward($uid){
        $data = [];
        $result = [];
        $list = $this->getCardInfo(); //获取所有的卡片信息
        foreach ($list as $key => $value)
        {
            $data[intval($value['cgid'])][] = intval($value['ciid']);  //根据卡组分组
        }
        //未领取奖励的卡组 $result[0,1,2,3]
        foreach ($data as $key => $value)
        {
            $tempKey = okeys::userCardReward($uid,$key);
            $flag = oo::commonOprRedis('common')->get($tempKey);
            if(!$flag)
            {
                $result[] = $key;
            }
        }

        //查询自己的卡片信息 看看是否满足条件
        $userCardInfo = $this->getInfo($uid);  //当前用户的卡片信息
        $totalCoins = 0;
        $totalSpins = 0;
        foreach ($userCardInfo as $key => $value)
        {
            if(in_array($key,$result))//只有未领取奖励的卡组才能领取
            {
                if(count($value) == count($data[$key]))//卡片集满9张
                {
                    //获取奖励配置
                    $list = self::getCardGroupInfo($key);
                    if(!empty($list))
                    {
                        //更新卡组进度
                        $this->updateCardGroupTotal($uid);
                        $coins = intval($list['cg_coin_reward']);
                        $spins = intval($list['cg_spin_reward']);
                        oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'+',30,'卡组收集满奖励金币:卡组'.$key);
                        oo::commonOprModel('member')->optProperty($uid,array('spins'=>$spins),'+',30,'卡组收集满奖励体力:'.$key);
                        oo::commonOprRedis('common')->set(okeys::userCardReward($uid,$key),1);
                        $totalCoins += $coins;
                        $totalSpins += $spins;
                    }
                }
            }
        }
        if($totalCoins != 0 || $totalSpins != 0){
            return ['cg_coin_reward'=>$totalCoins,'cg_spin_reward'=>$totalSpins];
        }
        return [];
    }

    /**
     * 卡组进度配置
     * @param bool $progress
     * @return mixed
     * Created by: Owen
     * Created on: 2020/3/25 20:03
     */
    public function getCardGroupRewardConfig($progress = false){
        $cacheKey = okeys::CardGroupProgressConfig();
        $arrJson = oo::commonOprRedis('config')->hGetAll($cacheKey);
        $arr = funs::getArrFromJsonArr($arrJson);
        if(empty($arr)||(!$progress&&empty($arr[$progress]))){
            $tb = otable::cardgroupreward_config();
            $sql = "SELECT * FROM {$tb}";
            $ret = oo::commonOprDb('config')->getAll($sql,1);
            if(!empty($ret)){
                foreach ($ret as $k=>$v){
                    $arr[$v['progress']] = $v;
                    $cache[$v['progress']] = json_encode($v);
                }
                oo::commonOprRedis('config')->hMset($cacheKey,$cache);
                oo::commonOprRedis('config')->expire($cacheKey,oo::redisRandomExpire(7*86400));
            }
        }
        $data = !$progress?$arr:$arr[$progress];
        return $data;
    }

    /**
     * @param $card
     * @param $rank
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/14 17:42
     * Description:返回已解锁卡组下等于 $rank 星级的卡片
     * 增加一个要过滤的卡片id参数，从解锁的卡池里去掉需要过滤的卡，卡包开卡去重
     */
    private function getCardRank($card, $rank, $filteredCards= []){
        if(IS_DEBUF)oo::logs()->debug2(['rank' => $rank], 'cardRank.log');
        $data = $noRepeatCards = $noRepeatRankCards = [];
        foreach ($card as $item){
            if(!in_array($item['ciid'], $filteredCards)){   #从已解锁的卡池获取全部未抽出的卡
                $noRepeatCards[] = $item;

                if(intval($item['ci_star_rank']) == $rank) {    #从已解锁的卡池获取当前星级,未抽出的卡
                    $noRepeatRankCards[] = $item;
                }
            }
            if(intval($item['ci_star_rank']) == $rank) {    #从已解锁的卡池获取当前星级的卡
                $data[] = $item;
            }
        }
        if(count($noRepeatRankCards) > 0)return $noRepeatRankCards; #已解锁卡池,当前星级还有未抽出的卡，就返回未抽出的卡组
        if(count($noRepeatCards) > 0)return $noRepeatCards; #已解锁卡池还有未抽出的卡，就返回未抽出的卡组
        return $data;   #否则返回当前星级卡组
    }

    /**
     * @param $card
     * @param $rank
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/14 17:43
     * Description:返回已解锁卡组下小于 $rank 星级的卡片
     */
    private function getCard($card, $rank){
        $woodenCard = [];
        foreach ($card as $item) {
            if(intval($item['ci_star_rank']) <= $rank) {
                $woodenCard[] = $item;
            }
        }
        return $woodenCard;
    }

    /**
     * @param $uid
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/14 15:35
     * Description:返回已解锁的卡组
     */
    public function getUnlockCardGroup($uid)
    {
        $group = [];
        $memberAssets  = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $levelId = $memberAssets['levelId'];
        $cardGroupInfo = $this->getCardGroupInfo();
        foreach ($cardGroupInfo as $key => $value) {
            if(intval($value['cg_lock_rank']) <= intval($levelId)) {
                $group[] = $value['cgid'];
            }
        }
        return $group;
    }

    /**
     * @param $uid
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/14 15:55
     * Description:返回已解锁的卡片
     */
    public function getUnlockCard($uid)
    {
        $group = self::getUnlockCardGroup($uid);
        $card = [];
        $cardInfo = $this->getCardInfo();
        foreach ($cardInfo as $key => $value) {
            if(in_array(intval($value['cgid']),$group)) {
                $card[] = $value;
            }
        }
        return $card;
    }

    public function cardReward($uid,$gid){
        $userCardInfo = self::getUserCardInfo($uid);
        $cgreward = $userCardInfo['cgreward'];
        $userCard = $userCardInfo['ciid'];
        if(in_array($gid,$cgreward)){
            return false;
        }
        $list = self::getCardInfo(); //获取所有的卡片信息
        $groupCard = [];
        foreach ($list as $key => $value) {
            if($value['cgid'] == $gid){
                $groupCard[] = $value['ciid'];
            }
        }
        foreach ($groupCard as $cardId){
            if($userCard[$cardId] < 1){
                return false;
            }
        }

        $reward = self::getCardGroupInfo($gid); //获取所有的卡片信息
        $coins  = intval($reward['cg_coin_reward']);
        $spins  = intval($reward['cg_spin_reward']);
        $feed   = intval($reward['cg_petFeed_reward']);
        $exp    = intval($reward['cg_petExp_reward']);

        $coins && oo::commonOprModel('member')->optProperty($uid,array('money' => $coins),'+',30,'卡组收集满奖励金币:卡组'.$gid);
        $spins && oo::commonOprModel('member')->optProperty($uid,array('spins' => $spins),'+',30,'卡组收集满奖励体力:卡组'.$gid);
        $feed  && oo::commonOprModel('props')->addUserProps($uid,9,$feed,0,30);
        $exp   && oo::commonOprModel('props')->addUserProps($uid,8,$exp,0,30);
        $groupCardNames=['TW'=> $reward['cg_name_tw'], 'ZH'=> $reward['cg_name_zh'], 'FR'=> $reward['cg_name_fr'], 'DE'=> $reward['cg_name_de'], 'EN'=> $reward['cg_name']];
        oo::async()->add('oo::commonOprModel("notice")->sendNoticeMsg',[$uid,"fulCardGroup",[$groupCardNames]]);//集齐卡组跑马灯消息

        //----领奖记录----
        $rewardProps=[
            ["propsId"=>14,"num"=>$coins],
            ["propsId"=>15,"num"=>$spins],
            ["propsId"=>8,"num"=>$exp],
            ["propsId"=>9,"num"=>$feed],
        ];
        $dataLog = [
            "uid"=>$uid,
            "gid"=>$gid,
            "ts"=>time(),
            "reward"=>json_encode($rewardProps)
        ];
        oo::async()->add('oo::commonOprModel("card")->cardRewardLog',[$dataLog]);

        $bet = 0;
        //卡组活动额外奖励
        $aid = oo::commonOprModel('activitynew')->activityLock($uid,'crazy_card_group');
        if($aid){
            $bet = intval(oo::commonOprModel('activitynew')->getCrazyCardGroupBet($uid,$aid)['rate'])*0.01;
            $bcoin = intval($bet*$coins);$coins += $bcoin;
            $bspins = intval($bet*$spins);$spins += $bspins;
            $bfeed = intval($bet*$feed);$feed += $bfeed;
            $bexp = intval($bet*$exp);$exp += $bexp;
            oo::commonOprModel('member')->optProperty($uid,array('money'=>$bcoin),'+',216,'疯狂卡组：'.$aid);
            oo::commonOprModel('member')->optProperty($uid,array('spins'=>$bspins),'+',216,'疯狂卡组：'.$aid);
            intval($bet*$feed)  && oo::commonOprModel('props')->addUserProps($uid,9, $bfeed,0,216);
            intval($bet*$exp)   && oo::commonOprModel('props')->addUserProps($uid,8,$bexp,0,216);
        }
        $cgreward[] = intval($gid);
        $cgreward   = array_unique($cgreward);
        $taCgId     = [];
        foreach ($cgreward as $gid){
            $taCgId[] = "".$gid;
        }
        self::updateUserCardInfo($uid,['ciid'=>$userCard,'cgreward'=>$cgreward]);
        oo::commonOprModel('ta')->setEventData($uid,'user_set',['cardset_complete_num'=>count($cgreward),"cardset_complete_list"=>$taCgId]);
        /**
         * ta 事件--卡组完成
         */
        oo::commonOprModel('ta')->setEventData($uid,"cardset_complate",[
            "cardset_id"                    =>$gid,
            "cardset_activity_ratio"        =>$bet,
            "cardset_reward_spin"           =>$spins,
            "cardset_reward_coin"           =>$coins,
            "cardset_reward_petfood"        =>$feed,
            "cardset_reward_petexp"         =>$exp,
        ]);
        return ['coins'=>$coins,'spins'=>$spins,'petfeed'=>$feed,'petexp'=>$exp];
    }

    public function cardRewardLog($data){
        $tb = otable::cardRewardLog();
        oo::logs()->commlog($data,"cardlog");
        $sql = funs::db_insertSQL($tb,$data);
        $res = oo::commonOprDb("log")->query($sql,1);
    }
    /**
     * 卡组进度奖励
     * @param $uid
     * @return array|bool
     * Created by: Owen
     * Created on: 2019/11/4 17:15
     */
    public function progressReward($uid){
        $total = count(self::getCardProgress($uid));
        $list  = self::getCardGroupRewardConfig();
        foreach ($list as $row){
            $progress = $row['progress'];
            if($progress <= $total){
                $tempKey = okeys::userCardGroupReward($uid,$progress);
                if(!oo::commonOprRedis('common')->get($tempKey)) {
                    $coins = intval($row['coin_reward']);
                    $spins = intval($row['spin_reward']);
                    //查询到当前卡组进度奖励
                    $add   = ['money'=>$coins,'spins'=>$spins];
                    oo::commonOprRedis('common')->set($tempKey, 1);
                    $userCard = self::getUserCardInfo($uid);
                    $cpreward = $userCard['cpreward'];
                    $cpreward[] = intval($progress);
                    self::updateUserCardInfo($uid,['cpreward'=>array_unique($cpreward)]);
                    oo::commonOprModel('member')->optProperty($uid,$add,'+',31,'卡组进度奖励:'.$progress);
                    $add['coins'] = $coins;
                    return $add;
                }
            }else{
                return false;
            }
        }
        return false;
    }

    /**
     * 已经领取过的卡组
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/3/25 20:07
     */
    public function getCardProgress($uid){
        $ret  = self::getUserCardInfo($uid);
        return $ret['cgreward'];
    }

    /**
     * 已经领取到的卡组进度
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2020/3/25 20:08
     */
    public function getRewardProgress($uid){
        $ret  = self::getUserCardInfo($uid);
        $cpreward = count($ret['cpreward']);
        return ($cpreward == 0)? -1 :$cpreward;
    }

    /**
     * 获得限定卡片信息
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2019/11/20 17:06
     */
    public function getExclusiveInfo($uid){
        $res = [];
        $cards = $this->getExclusiveCardInfo();
        foreach ($cards as $items)
        {
            $card[$items['ciid']] = $items['cgposition'];//ciid->位置
        }
        foreach ($cards as $items)
        {
            $group[$items['ciid']] = $items['cgid'];//ciid->卡组id
        }
        $userCardInfo = self::getUserCardInfo($uid);
        if(!empty($userCardInfo)) {
            $cardNumData = $userCardInfo['csid'];//ciid->数量
            if(empty($cardNumData)){
                return [];
            }
            $groupTemp = [];
            foreach ($card as $ciid => $pos) {
                foreach ($group as $ci => $cgid) {
                    if(!in_array($cgid,$groupTemp)){
                        $res[$cgid][1] = 0;
                        $groupTemp[] = $cgid;
                    }
                    if($ciid == $ci) {
                        if (key_exists($ciid, $cardNumData)) {
                            $res[$cgid][$card[$ciid]] = intval($cardNumData[$ciid]);
                        }
                    }
                }
            }
            foreach ($res as $key=>$row){
                $res[$key] = array_filter($row);
            }
            $res = array_filter($res);
            return $res;
        }else{
            return [];
        }
    }

    /**
     * 领取限定卡片
     * @param $uid
     * @param $scardId
     * Created by: Owen
     * Created on: 2019/11/22 11:12
     */
    public function rewardExclusiveCard($uid,$scardId){
        $userCardInfo = self::getUserCardInfo($uid);
        $cardNumData = $userCardInfo['csid'];
        $cardNumData[$scardId] += 1;
        self::updateUserCardInfo($uid,['csid'=>$cardNumData]);
    }

    /**
     * 获得限定卡片信息
     * @param bool $gid
     * @return mixed
     * Created by: Owen
     * Created on: 2019/11/22 11:10
     */
    public function getExclusiveCardInfo($gid = false){
        $cacheKey = okeys::SpecialCardConfig();
        $arrJson = oo::commonOprRedis('config')->hGetAll($cacheKey);
        $arr = funs::getArrFromJsonArr($arrJson);
        if(empty($arr)||(!$gid&&empty($arr[$gid]))){
            $tb = otable::specialCardInfoConfig();
            $sql = "SELECT * FROM {$tb}";
            $ret = oo::commonOprDb('config')->getAll($sql,1);
            if(!empty($ret)){
                foreach ($ret as $k=>$v){
                    $arr[$v['ciid']] = $v;
                    $cache[$v['ciid']] = json_encode($v);
                }
                oo::commonOprRedis('config')->hMset($cacheKey,$cache);
                oo::commonOprRedis('config')->expire($cacheKey,oo::redisRandomExpire(7*86400));
            }
        }
        $data = !$gid?$arr:$arr[$gid];
        return $data;
    }

    /**
     * 根据ID获得限定卡片
     * @param $id
     * @return mixed
     * Created by: Owen
     * Created on: 2019/11/22 17:58
     */
    public function getExclusiveCardInfoById($id){
        $ret = self::getExclusiveCardInfo();
        foreach ($ret as $row){
            if($row['ciid'] == $id){
                return $row;
            }
        }
        return false;
    }

    /**
     * 限定卡组信息
     * @param bool $gid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/3/25 19:46
     */
    public function getExclusiveCardGroupInfo($gid = false){
        $cacheKey = okeys::SpecialCardGroupConfig();
        $arrJson = oo::commonOprRedis('config')->hGetAll($cacheKey);
        $arr = funs::getArrFromJsonArr($arrJson);
        if(empty($arr)||($gid!==false&&empty($arr[$gid]))){
            $tb = otable::specialCardgroup_config();
            $sql = "SELECT * FROM {$tb}";
            $ret = oo::commonOprDb('config')->getAll($sql,1);
            if(!empty($ret)){
                foreach ($ret as $k=>$v){
                    $arr[$v['cgid']] = $v;
                    $cache[$v['cgid']] = json_encode($v);
                }
                oo::commonOprRedis('config')->hMset($cacheKey,$cache);
                oo::commonOprRedis('config')->expire($cacheKey,oo::redisRandomExpire(7*86400));
            }
        }
        $data = $gid===false?$arr:$arr[$gid];
        return $data;
    }

    /**
     * 领取限定卡片奖励--头像框
     * @param $uid
     * @param $sGroupId
     * @return bool
     * Created by: Owen
     * Created on: 2019/11/22 11:07
     */
    public function rewardExclusiveGroup($uid,$sGroupId){
        $userCardInfo = self::getUserCardInfo($uid);
        $cardNumData = $userCardInfo['csid'];
        $cardNumData = array_keys($cardNumData);
        $cardList = self::getExclusiveCardInfo($sGroupId);
        if(!in_array($cardList['ciid'],$cardNumData)){
            return false;
        }
        $ret = self::getExclusiveCardGroupInfo($sGroupId);
        if(!empty($ret)){
            return oo::commonOprModel('user')->rewardAvatarBox($uid,$ret['cg_avatar']);
        }
    }

    /**
     * 获得已领取的卡片组
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2019/11/22 11:18
     */
    public function getExclusiveGroupEd($uid){
        $userAvatarData = oo::commonOprModel('user')->getAvatar($uid);
        $avatarBox = $userAvatarData['avatarBox'];
        if(empty($avatarBox)){
            return [];
        }
        $ret = self::getExclusiveCardGroupInfo();
        $list= [];
        foreach ($ret as $row){
            if(in_array($row['cg_avatar'],$avatarBox)){
                $list[] = $row;
            }
        }
        return array_column($list,'cgid');
    }

    /**
     * 卡祝福
     * @param $uid
     * @param $gid
     * @return bool
     * Created by: Owen
     * Created on: 2019/12/20 17:53
     */
    public function getCardBless($uid,$bless){
        $gid = self::blessTurnToGid($bless);
        $flag = oo::commonOprRedis('usercache')->get(okeys::cardBless($uid,$gid));
        if($flag === 0){
            return false;
        }else if(!empty($flag)){
            return json_decode($flag,true);
        }
        $tb  = otable::payment($uid);
        $sql = " SELECT * FROM {$tb} WHERE uid = {$uid} AND gid={$gid} AND use_time is null AND status = 2 LIMIT 1";
        $ret = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        if(empty($ret)){
            oo::commonOprRedis('usercache')->setex(okeys::cardBless($uid,$gid),0,oo::redisRandomExpire(3*24*60*60));
            return false;
        }else{
            $buff = json_decode($ret['buff'],true);
            oo::commonOprRedis('usercache')->setex(okeys::cardBless($uid,$gid),json_encode($buff),oo::redisRandomExpire(3*24*60*60));
            return $buff;
        }
    }

    /**
     * 祝福列表
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2019/12/26 16:15
     */
    public function getCardBlessList($uid){
        $tb  = otable::payment($uid);
        $sql = " SELECT * FROM {$tb} WHERE uid = {$uid} AND gid IN (1101,1102) AND use_time is null AND status = 2";
        $ret = oo::commonOprDb('payment')->getAll($sql,MYSQLI_ASSOC);
        if(empty($ret)){
            return [];
        }else{
            foreach ($ret as $key=>$row){
                $buff = json_decode($row['buff'],true);
                $ret[$key] = [
                    'chestId'  => $buff['id'],
                    'blessTo'  => $buff['blessTo'],
                    'blessType'=> $buff['bless'],
                ];
            }
            return $ret;
        }
    }

    /**
     * 使用祝福
     * @param $uid
     * @param $gid
     * Created by: Owen
     * Created on: 2019/12/20 17:56
     */
    public function useCardBless($uid,$id,$bless){
        $gid = self::blessTurnToGid($bless);
        $time = time();
        $tb  = otable::payment($uid);
        $like = '\'%"id":'.$id.',"bless":'.$bless.'%\'';
        $sql = " UPDATE {$tb} SET use_time='{$time}' WHERE uid='{$uid}' AND gid='{$gid}' AND status=2 AND use_time is null AND buff LIKE {$like} LIMIT 1";
        oo::commonOprDb('payment')->query($sql);
        oo::commonOprRedis('usercache')->delete(okeys::cardBless($uid,$gid));
    }

    public function blessTurnToGid($bless){
        $data =[
            1=>1101,
            2=>1102,
        ];
        return $data[$bless]??0;
    }

    //---------------------------------------------------- 1.3.7 改版---------------------------------------------------//


    /**
     * 卡片信息 -- 1.3.7 改版
     * @param $uid
     * @param $interface
     * @return mixed
     * Created by: Owen
     * Created on: 2020/3/24 19:56
     */
    public function info($uid,$interface = true){
        $userCardInfo = self::getUserCardInfo($uid);
        $userBasic     = (array)$userCardInfo['ciid'];
        $userExclusive = (array)$userCardInfo['csid'];
        $cards = [];
        foreach ($userBasic as $key=>$row){
            $cards[$key] = $row;
        }
        foreach ($userExclusive as $key=>$row){
            $cards[$key + 100000] = $row;
        }

        $jokerTime = max(oo::commonOprRedis('User')->ttl(okeys::JokerCard($uid)),0);
        $data = [
            'cardList'     => $cards,
            'cardRewardRecord' => [
                'basic'    => ($userCardInfo['cgreward'] == 'null' || empty($userCardInfo['cgreward'])) ? [] : $userCardInfo['cgreward'],
                'exclusive'=> self::getExclusiveGroupEd($uid)
            ],
            'taskRewardRecord' => [
                'basic'    => ($userCardInfo['cpreward'] == 'null' || empty($userCardInfo['cpreward'])) ? 0 : count($userCardInfo['cpreward']),
                'exclusive'=> 0
            ],
            'joker' => $jokerTime > 0 ? $jokerTime + time() : 0
        ];
        if($interface){
            return oo::response(1,$data,"",true);
        }else{
            return $data;
        }
    }

    /**
     * 获取卡组信息
     * @param bool $gid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/3/25 17:45
     */
    public function getCardGroupInfo($gid = false){
        $cacheKey = okeys::CardGroupConfig();
        $arrJson = oo::commonOprRedis('config')->hGetAll($cacheKey);
        $arr = funs::getArrFromJsonArr($arrJson);
        if(empty($arr)||($gid!==false&&empty($arr[$gid]))){
            $tb = otable::cardgroup_config();
            $sql = "SELECT * FROM {$tb}";
            $ret = oo::commonOprDb('config')->getAll($sql,1);
            if(!empty($ret)){
                foreach ($ret as $k=>$v){
                    $arr[$v['cgid']] = $v;
                    $cache[$v['cgid']] = json_encode($v);
                }
                oo::commonOprRedis('config')->hMset($cacheKey,$cache);
                oo::commonOprRedis('config')->expire($cacheKey,oo::redisRandomExpire(7*86400));
            }
        }
        $data = $gid===false?$arr:$arr[$gid];
        return $data;
    }

    /**
     * 获取卡片信息
     * @return array
     * Created by: Owen
     * Created on: 2020/3/25 11:33
     */
    public function getCardInfo($ciid=false){
        $arrJson = oo::commonOprRedis('config')->hGetAll(okeys::CardConfig());
        $arr = funs::getArrFromJsonArr($arrJson);
        if(empty($arr)||($ciid!==false&&empty($arr[$ciid]))){
            $tb = otable::cardinfo_config();
            $sql = "SELECT * FROM {$tb}";
            $ret = oo::commonOprDb('config')->getAll($sql,1);
            if(!empty($ret)){
                foreach ($ret as $k=>$v){
                    $arr[$v['ciid']] = $v;
                    $cache[$v['ciid']] = json_encode($v);
                }
            }
        }
        if($ciid===false){
            array_multisort(array_column($arr,'ciid'),SORT_ASC,$arr);
            $data = $arr;
        }else{
            $data = $arr[$ciid];
        }
        return $data;
    }

    /**
     * 根据等级Id获取解锁的卡组
     * @param $levelId
     * @return array
     * Created by: Owen
     * Created on: 2020/3/25 11:33
     */
    public function getUnlockCardGroupByLevelId($levelId){
        $group = [];
        $cardGroupInfo = $this->getCardGroupInfo();
        foreach ($cardGroupInfo as $key => $value) {
            if(intval($value['cg_lock_rank']) <= intval($levelId)) {
                $group[] = $value['cgid'];
            }
        }
        return $group;
    }

    /**
     * 根据等级Id获取解锁的卡片
     * @param $levelId
     * @return array
     * Created by: Owen
     * Created on: 2020/3/25 11:34
     */
    public function getUnlockCardByLevelId($levelId){
        $group = self::getUnlockCardGroupByLevelId($levelId);
        $card = [];
        $cardInfo = self::getCardInfo();
        foreach ($cardInfo as $key => $value) {
            if(in_array($value['cgid'],$group) && $value['ci_lockRank'] <= $levelId) {
                $card[] = $value;
            }
        }
        return $card;
    }

    /**
     * 随机生成星级卡片
     * @param $card
     * @param $num
     * @param $type
     * @return array
     * Created by: Owen
     * Created on: 2019/12/20 19:19
     */
    public function generateCard($userCard,$card, $num, $type,$skin = 0, $levelId = 0){
        $userCardCiid = array_keys($userCard);
        $array  = [];
        $config = [];
        if($skin){
            $temp = oo::commonOprModel('config')->getChestSkinStarProConfig($skin);
            if(!empty($temp)){
                $config  = $temp["pro"];
                $goldNum = $temp["maxGoldCard"];
            }
        }
        if(empty($config)){
            $config  = self::getCardTypeProConfig($type);
            $goldNum = self::getMaxGoldCardByType($type);
        }
        if($levelId <= 7) $goldNum = min($goldNum, 1); #7级以下，每次最多一张金卡
        $coConfig= oo::commonOprModel('config')->cardCoefficient();
        $curGoldNum = 0;
        $log =[];
        $ce =1;
        $delGoldCard = false;
        $whiteCards = [];
        for($i = 0; $i < $num; ++$i) {
            $data = self::getCardRank($card,oo::commonOprModel('slot')->get_rand($config), $whiteCards);
            if($delGoldCard || $curGoldNum >= $goldNum){    #需要剔除金卡 或者 金卡已到上限
                foreach ($data as $k => $v){
                    if($v['grade'] == 2) unset($data[$k]);
                }
            }
            #剔除卡组中，当前已经重复的卡
            $countCards = array_count_values($whiteCards);
            $this->changeCardWeights($coConfig,$userCard,$data);
            if(count($data) > 0){
                $total = array_sum(array_column($data,'weights'));
                if($total > 0){

                    $random = rand(0,$total);
                    $addAction = false;
                    foreach ($data as $row){
                        $ce =pow(1/5,intval($log[$row['ciid']]));//修正系数随卡片出现次数变更
                        $random -= intval($row['weights']);//降低已出现的卡片出现权重
                        if(!($goldNum != -1 && $goldNum <= $curGoldNum && $row['grade'] == 2) && ($random <= 0)){
                            $whiteCards[] = $row['ciid'];
                            $log[$row['ciid']]++;//记录 卡组id_卡片id 出现次数
                            $array[] = $row;
                            $userCard[$row['ciid']] += 1;
                            $row['grade'] == 2 && $curGoldNum += 1;
                            $addAction = true;
                            break;
                        }
                    }
                    if(!$addAction){
                        $data = self::getCardRank($card,rand(1,3), $whiteCards);
                        $randCard = $data[array_rand($data,1)];
                        $whiteCards[] = $randCard['ciid'];
                        $userCard[$randCard['ciid']] += 1;
                        $array[] = $randCard;
                    }
                }else{
                    $randCard = $data[array_rand($data,1)];
                    $whiteCards[] = $randCard['ciid'];
                    $userCard[$randCard['ciid']] += 1;
                    $array[] = $randCard;
                }
            }else{
                $userWhiteCards = [];
                foreach ($card as $item){
                    if(
                        $item['grade'] == 1     #白卡
                        && in_array($item['ciid'], $userCardCiid)   #用户已拥有
                        && $countCards[$item['ciid']] < 2       #当前未重复
                    ){
                        $userWhiteCards[] = $item;
                    }
                }
                if(!empty($userWhiteCards))
                    $array[] = $userWhiteCardsTemp = $userWhiteCards[array_rand($userWhiteCards,1)];
                else
                    $array[] = $userWhiteCardsTemp = self::getCardInfo()[0];
                $whiteCards[] = $userWhiteCardsTemp['ciid'];
            }
//            oo::logs()->debug3(["ts"=>date("H:i:s"), "whiteCards"=>$whiteCards,"countData"=>count($data),"random"=>$random],'cardLoop.log');
        }
//        oo::logs()->debug3(["ts"=>date("H:i:s"), "whiteCards"=>array_values(array_unique($whiteCards)),"countData"=>count($data),"type"=>$type,"skin"=>$skin],'cardLoop.log');
        return $array;
    }

    /**
     * @param $type
     * @return array
     * Created by: Cassie Lee
     * Created on: 2019/5/15 17:16
     * Description:获取卡片概率配置
     */
    public function getCardTypeProConfig($type){
        $cacheKey = okeys::CardTypePro($type);
        $cache    = oo::commonOprRedis('config')->hGetAll($cacheKey);
        if($cache){
            return $cache;
        }
        $tb = otable::cardPro_Config();
        $sql = "select * from {$tb} where type ={$type} limit 1";
        $data = oo::commonOprDb('config')->getOne($sql, MYSQLI_ASSOC);
        $config = json_decode($data['star_pro'],true);
        $arr = [];
        foreach ($config as $key => $val) {
            $arr[$val['star']] = intval($val['v']);
        }
        oo::commonOprRedis('config')->hMset($cacheKey,$arr);
        oo::commonOprRedis('config')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
        return $arr;
    }

    /**
     * 最大金卡数量
     * @param $type
     * @return false
     * Created by: Owen
     * Created on: 2020/9/1 17:42
     */
    public function getMaxGoldCardByType($type){
        $cacheKey = okeys::MaxGoldCard($type);
        $cache    = oo::commonOprRedis('config')->get($cacheKey);
        if(empty($cache)){
            $tb = otable::cardPro_Config();
            $sql = "select * from {$tb} where type ={$type} limit 1";
            $data = oo::commonOprDb('config')->getOne($sql, MYSQLI_ASSOC);
            $cache = $data['maxGoldCard'];
            oo::commonOprRedis('config')->setex($cacheKey,$cache,oo::redisRandomExpire(7*86400));
        }
        return $cache;
    }

    /**
     * 获取卡片信息 -- 兼容旧代码
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2020/3/24 19:49
     */
    public function getUserCardInfo($uid){
        $cacheKey = okeys::UserCardInfo($uid);
        $cache    = oo::commonOprRedis('common')->get($cacheKey);
        if($cache){
            $ret = json_decode($cache,true);
            $ret['ciid']        = (array)$ret['ciid'];
            $ret['send_card']   = (array)$ret['send_card'];
            $ret['csid']        = (array)$ret['csid'];
            $ret['cgreward']    = (array)$ret['cgreward'];
            $ret['cpreward']    = (array)$ret['cpreward'];
            $ret['sended_card'] = (array)$ret['sended_card'];
            return $ret;
        }
        $tb  = otable::usercard_config($uid);
        $sql = "SELECT * FROM {$tb} WHERE uid={$uid} ";
        $ret = oo::commonOprDb('cardinfo')->getOne($sql, MYSQLI_ASSOC);
        if(!empty($ret)){
            $ret['ciid']        = json_decode($ret['ciid'],true)??[];
            $ret['send_card']   = json_decode($ret['send_card'],true)??[];
            $ret['csid']        = json_decode($ret['csid'],true)??[];
            $ret['cgreward']    = json_decode($ret['cgreward'],true)??[];
            $ret['cpreward']    = json_decode($ret['cpreward'],true)??[];
            $ret['sended_card'] = json_decode($ret['sended_card'],true)??[];
            oo::commonOprRedis('common')->setex($cacheKey,json_encode($ret),oo::redisRandomExpire(7*24*60*60));
        }else{
            oo::commonOprDb('cardinfo')->query("INSERT INTO {$tb} (`uid`,`cgid`,`ciid`,`reward_type`,`reward_amount`,`gtime`,`gchannel`,`gid`,`expire`,`receive_time`) VALUES ({$uid},'', '{}', '0', '0', '0', '0', '0', '0', '0');");
            $ret = oo::commonOprDb('cardinfo')->getOne("SELECT * FROM {$tb} WHERE uid={$uid} ", MYSQLI_ASSOC);
            if(!empty($ret)){
                $ret['ciid']        = json_decode($ret['ciid'],true)??[];
                $ret['send_card']   = json_decode($ret['send_card'],true)??[];
                $ret['csid']        = json_decode($ret['csid'],true)??[];
                $ret['cgreward']    = json_decode($ret['cgreward'],true)??[];
                $ret['cpreward']    = json_decode($ret['cpreward'],true)??[];
                $ret['sended_card'] = json_decode($ret['sended_card'],true)??[];
                oo::commonOprRedis('common')->setex($cacheKey,json_encode($ret),oo::redisRandomExpire(7*24*60*60));
            }else{
                return [];
            }
        }
        return $ret;
    }

    /**
     * 更新用户卡片信息
     * @param $uid
     * @param $info
     * @return bool
     * Created by: Owen
     * Created on: 2020/3/25 16:28
     */
    public function updateUserCardInfo($uid,$info){
        $cacheKey     = okeys::UserCardInfo($uid);
        $userCardInfo = self::getUserCardInfo($uid);
        foreach ($info as $key=>$row){
            $userCardInfo[$key] = $row;
        }
        oo::commonOprRedis('common')->setex($cacheKey,json_encode($userCardInfo),oo::redisRandomExpire(7*24*60*60));
        /** 数据落地标识 */
        oo::commonOprRedis('common')->zAdd(okeys::Landing("CARD", $uid),time(),$uid);
        return true;
    }

    /**
     * 获得卡片
     * @param $uid
     * @param $type 1木质宝箱 2白银宝箱 3黄金宝箱 4魔法宝箱 5 挖矿【挖到金币为0才有机会触发】,6任务奖励, 7活动奖励 10绿宝箱11蓝宝箱12红宝箱
     * @param int $setNum 强制设定宝箱数量
     * @param int $skin 强制设定宝箱数量
     * @return array|bool
     * Created by: Owen
     * Created on: 2019/12/20 18:13
     */
    public function getCardByType($uid, $type,$setNum = 0,$getCardArray = [],$skin = 0){
        $assetsInfo  = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $card        = self::getUnlockCardByLevelId($assetsInfo['levelId']);
        $cardNum     = $setNum != 0 ? $setNum : [1=>2,2=>4,3=>8,4=>10,7=>1][$type] ?? 1;
        oo::commonOprModel('statistics')->cardSourceSta($type,$cardNum);//卡片来源统计
        $userCardInfo = self::getUserCardInfo($uid);
        if($type == 5){
            $temp      = [20,15,25,10,30];
            $starRank  = oo::commonOprModel('slot')->get_rand($temp);
            if($temp[$starRank] == $temp[0]){
                $array = self::generateCard($userCardInfo['ciid'],$card,$cardNum,$type, 0, $assetsInfo['levelId']);
            }else{
                return [];
            }
        }else if($type == 7){
            foreach ($getCardArray as $ciid){
                $array[] = self::getCardInfoByCiid($ciid);
            }
        }else{
            if(oo::commonOprModel('activitynew')->activityLock($uid,'card')){
                $cardNum = ceil($cardNum*1.5);
            }
            $array = self::generateCard($userCardInfo['ciid'],$card,$cardNum,$type,$skin,  $assetsInfo['levelId']);
        }
        if(!empty($array)){
            $userCardData = $userCardInfo['ciid'];
            $userCard     = array_keys($userCardData);
            $newCardStar  = 0;
            $newCard      = [];
            $cardLog      = [];
            foreach ($array as $key=>$item){
                $flag = true;
                if(in_array($item['ciid'],$userCard)){
                    $flag = false;
                    $userCardData[$item['ciid']] += 1;
                }else{
                    $userCardData[$item['ciid']]  = 1;
                    if(!in_array($item['ciid'],$newCard)){
                        $newCardStar+= $item['ci_star_rank'];
                        $newCard[]   = $item['ciid'];
                    }
                }
                $cardLog[] = $item['ciid'];
                $cardInfo['card'][] = [
                    'id'    => $item['ciid'],
                    'isNew' => $flag,
                ];
            }
            self::updateUserCardInfo($uid,['ciid'=>$userCardData]);
            $newCardStar > 0 && oo::commonOprModel('member')->optProperty($uid,array('star'=>$newCardStar),'+',32,'获取新卡片星星:'.implode(',',array_unique($newCard)));
            $propsName = [5=>"偷取获得",6=>"任务获得",7=>"活动获得"][$type] ?? oo::commonOprModel('props')->getPropsConfig()[$type]['name'];
            oo::commonOprModel('currency')->log($uid,"card","+",count($array),count($userCardData),3001,"{$propsName}:".implode(',',$cardLog));
            oo::commonOprModel('currency')->setUserDayData($uid,'obtain_card',count($cardInfo['card']));//用户每日数据-卡片数获得
            return $cardInfo;
        }else{
            return [];
        }
    }

    // ------------------------------------------1.5.0 改版 -----------------------------------------------------//

    /**
     * 赠送卡片
     * @param $uid
     * @param $toUid
     * @param $cids
     * @param int $num
     * @return mixed
     * Created by: Owen
     * Created on: 2020/3/28 14:20
     */
    public function sendCardToFriend($uid,$toUid,$cids,$num = 1){
        $todayCacheKey  = okeys::SendCardTodayTotal($uid);
        $todayTimer     = intval(oo::commonOprRedis('User')->get($todayCacheKey));
        $dayLimit = oo::commonOprModel('readconfig')->getCon('Game','sendCardTotalLimit');
        if($todayTimer >= $dayLimit){
            return oo::response(-3,[],"当天次数不足");
        }
        $singlePersonLimit   = oo::commonOprModel('readconfig')->getCon('Game','sendCardPlayerLimit');
        $todayPersonCacheKey = okeys::SendCardTodayPerson($uid,$toUid);
        $todayPersonTimer    = intval(oo::commonOprRedis('User')->get($todayPersonCacheKey));
        if($todayPersonTimer >= $singlePersonLimit){
            return oo::response(-3,[],"当天次数不足");
        }
        $userCardInfo = self::getUserCardInfo($uid);
        $userCurCard  = $userCardInfo['ciid'];
        $userSendCard = $userCardInfo['send_card'];
        $toUserCardInfo   = self::getUserCardInfo($toUid);
        $toUserSendedCard = $toUserCardInfo['sended_card'];
        $cardNum = 0;
        $actionCard = [];
        foreach ($cids as $cid){
            if(intval($userCurCard[$cid]) < 2){
                return oo::response(-2,[],"卡片不足");
            }
            // 扣除赠送方卡片
            $userCurCard[$cid] -= 1;
            $userSendCard[$toUid][$cid] += 1;
            // 追加待领取卡片
            $toUserSendedCard[$uid][$cid] += 1;
            $cardNum += 1;
            $actionCard[] = $cid;
        }
        oo::commonOprRedis('User')->setex($todayCacheKey,$todayTimer+$cardNum,oo::todayDeadline());
        oo::commonOprRedis('User')->setex($todayPersonCacheKey,$todayPersonTimer+$cardNum,oo::todayDeadline());
        self::updateUserCardInfo($uid,['ciid'=>$userCurCard,'send_card'=>$userSendCard]);
        self::updateUserCardInfo($toUid,['sended_card'=>$toUserSendedCard]);
        oo::commonOprModel('currency')->log($uid,"card","-",count($actionCard),array_sum($userCurCard),3001,"赠送好友 {$toUid}卡片：".implode(',',$actionCard));
        oo::commonOprModel('currency')->setUserDayData($uid,'cost_card',count($actionCard));//用户每日数据-卡片数消耗
        //赠送卡片
        oo::commonOprModel('callback')->doTask($uid, 11, 1);

        oo::commonOprModel('Workerman')->push($toUid,ocmd::$redPoint,['type'=>5]);

        //卡片赠送游戏推送
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        if(oo::compareVersion($version,'1.14.1') && oo::commonOprRedis('User')->setex(okeys::cardSendlog($uid,$toUid),1,60)){
            $userInfo = oo::commonOprModel('member')->getUserBasic($uid);
            $sendData = [
                'nick'=>$userInfo['nick'],
                's_picture'=>$userInfo['s_picture'],
                'sex'=>$userInfo['sex'],
                'signature'=>$userInfo['signature'],
                'u_flag'=>$userInfo['u_flag'],
                'uid'=>$userInfo['uid'],
            ];
            oo::commonOprModel('Workerman')->push($toUid,ocmd::$send['SendCard'],['userinfo'=>$sendData]);

            //离线推送
            oo::commonOprModel('push')->pushNews($toUid, 'push.title.shareCard', 'push.content.shareCard', [$userInfo['nick']],'shareCard');
        }

        //// 赠送卡片排行榜,取消该统计
        //foreach ($cids as $cid){
        //    oo::commonOprModel('statistics')->giveCardSta($cid);
        //}

        oo::commonOprModel('ta')->setEventData($uid,"card_send",["card_list"=>$cids,"card_send_object_user"=>$toUid]);

        return oo::response(1);
    }

    /**
     * 领取卡片
     * @param $uid
     * @param $toUid
     * @param bool $all
     * @param int $rcid
     * @return string
     * Created by: Owen
     * Created on: 2020/3/28 15:38
     */
    public function receiveCardFromFriend($uid,$toUid,$all = false,$rcid=0){
        $userCardInfo = self::getUserCardInfo($uid);
        $userCurCard  = $userCardInfo['ciid'];
        $userSendedCard  = $userCardInfo['sended_card'];
        if(empty($userSendedCard[$toUid])){
            return oo::response(-2,[],'卡片已领取');
        }
        $receiveCard = [];
        $newCard = [];
        if($all && $rcid==0){
            foreach ($userSendedCard[$toUid] as $cid=>$num){
                if(empty($userCurCard[$cid])){
                    $newCard[] = $cid;
                }
                $userCurCard[$cid] += $num;
                $receiveCard[$cid] = $num;
            }
            unset($userSendedCard[$toUid]);
        }else{
            foreach ($userSendedCard[$toUid] as $cid=>$num){
                if($rcid != 0 && $cid != $rcid){
                    continue;
                }
                if(empty($userCurCard[$cid])){
                    $newCard[] = $cid;
                }
                $userCurCard[$cid] += 1;
                $receiveCard[$cid] = 1;
                if($userSendedCard[$toUid][$cid] == 1){
                    unset($userSendedCard[$toUid][$cid]);
                }else{
                    $userSendedCard[$toUid][$cid] -= 1;
                }
                break;
            }
        }
        $newCardStar = 0;
        $cardList = self::getCardInfo();
        foreach ($cardList as $row){
            if(in_array($row['ciid'],$newCard)){
                $newCardStar+= $row['ci_star_rank'];
            }
        }
        if($newCardStar != 0){
            oo::commonOprModel('member')->optProperty($uid,array('star'=>$newCardStar),'+',32,'获取新卡片星星:'.implode(',',array_unique($newCard)));
        }
        self::updateUserCardInfo($uid,['ciid'=>$userCurCard ,'sended_card'=>$userSendedCard]);
        $out   = [];
        $actionCard = [];
        foreach($receiveCard as $cid=>$row){
            $first = true;
            for ($i=0;$i<$row;$i++){
                $actionCard[] = $cid;
                $isNew = in_array($cid,$newCard) && $first;
                $first = false;
                $out[] = [
                    "id"    => $cid,
                    "isNew" => $isNew
                ];
                oo::commonOprModel('ta')->setEventData($uid,"card_accept",["card_id"=>$cid,"card_accept_from_user"=>$toUid]);
            }
        }
        oo::commonOprModel('currency')->setUserDayData($uid,'obtain_card',count($out));//用户每日数据-卡片数获得
        oo::commonOprModel('currency')->log($uid,"card","+",count($actionCard),array_sum($userCurCard),3001,"领取好友 {$toUid}卡片：".implode(',',$actionCard));
        return oo::response(1,['card'=>$out]);
    }

    /**
     * 星星兑换
     * @param $uid
     * @param $propsId
     * @param $cards
     * @return string
     * Created by: Owen
     * Created on: 2020/6/10 15:46
     */
    public function starExchange($uid,$propsId,$cards){
        $cards = json_decode(base64_decode($cards),true);
        if(empty($cards)){
            return oo::response(-2,"","兑换数据异常");
        }
        $refreshTimeCacheKey = okeys::StarExchange($uid,$propsId);
        if(oo::commonOprRedis('User')->ttl($refreshTimeCacheKey) > 0){
            return oo::response(-3);
        }
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $config = oo::commonOprModel('config')->getStarExchange($propsId);
        if(empty($config)){
            return oo::response(-4,"","配置异常");
        }
        if($userAssetsInfo['levelId'] < $config['lockLevel']){
            return oo::response(-5,"","等级不足");
        }
        $totalStar    = 0;
        $cardsInfo    = array_column(self::getCardInfo(),NULL,'ciid');
        $userCardInfo = self::getUserCardInfo($uid);
        $userCardInfo = $userCardInfo['ciid'];
        foreach ($cards as $cid=>$row){
            $cardInfo = $cardsInfo[$cid];
            $totalStar+= $cardInfo['ci_star_rank'] * $row;
            if($userCardInfo[$cid] - $row >= 1){
                $userCardInfo[$cid] -= $row;
            }else{
                return oo::response(-6,"","卡片数据异常");
            }
        }
        if($totalStar < $config['starNum']){
            return oo::response(-7,"","卡片星星不足");
        }
        self::updateUserCardInfo($uid,['ciid'=>$userCardInfo]);
        oo::commonOprRedis('User')->setex($refreshTimeCacheKey,1,$config['refreshTime']);
        oo::commonOprModel('currency')->log($uid,"card","-",count($cards),count($userCardInfo),3002,"星星兑换".json_encode($cards));
        oo::commonOprModel('currency')->setUserDayData($uid,'cost_card',count($cards));//用户每日数据-卡片数消耗
        $data = oo::commonOprModel('props')->rewardChest($uid,19,"星星兑换",33,$propsId);
        return oo::response(1,$data);
    }

    /**
     * joker卡兑换
     * @param $uid
     * @param $cid
     * @return string
     * Created by: Owen
     * Created on: 2020/6/11 18:04
     */
    public function jokerExchange($uid,$cid){
        $cacheKey = okeys::JokerCard($uid);
        $ttl = intval(oo::commonOprRedis('User')->ttl($cacheKey));
        if($ttl <= 0){
            return oo::response(-2,[],'无小丑卡');
        }
        $unLockCard    = array_column(self::getUnlockCard($uid),NULL,'ciid');
        if(empty($unLockCard[$cid])){
            return oo::response(-2,[],'卡片未解锁');
        }
        $userCardInfo = self::getUserCardInfo($uid)['ciid'];
        $userCardInfo[$cid] += 1;
        self::updateUserCardInfo($uid,['ciid'=>$userCardInfo]);
        //小丑卡兑换流水
        oo::commonOprModel('currency')->log($uid,"card","+",1,count($userCardInfo),3003,"小丑卡兌換：".$cid);
        oo::commonOprModel('currency')->setUserDayData($uid,'obtain_card',1);//用户每日数据-卡片数获得
        $deleteFlag = true;
        $expireTime = time();
        if(oo::compareVersion(oo::commonOprModel('user')->getUserVersion($uid),'1.8.1')){
            $expire = (ceil($ttl/86400) - 1) * 86400;
            if($expire > 0){
                $deleteFlag  = false;
                $expireTime += $expire ;
                oo::commonOprRedis('User')->setex($cacheKey,1,$expire);
            }
        }
        $deleteFlag && oo::commonOprRedis('User')->delete($cacheKey);
        return oo::response(1,['expireTime'=>$expireTime]);
    }

    /**
     * 根据卡组获取卡片
     * @param $gid
     * @return array
     * Created by: Owen
     * Created on: 2020/9/17 17:33
     */
    public function getCardByGroup($gid){
        $cards  = self::getCardInfo();
        $output = [];
        foreach ($cards as $card){
            if($card['cgid'] == $gid){
                $output[] = $card;
            }
        }
        return $output;
    }

    /**
     * 卡组是否收集满
     * @param $uid
     * @param $gid
     * @return bool
     * Created by: Owen
     * Created on: 2020/9/17 17:20
     */
    public function isGetAllCardByGroup($uid,$gid){
        $userCardInfo = self::getUserCardInfo($uid);
        $userCardGroup= $userCardInfo['cgreward'];
        if(!in_array($gid,$userCardGroup)){
            return false;
        }
        return true;
    }

    /**
     * Notes:获取随机金卡
     * User: wsc
     * Time: 2021/9/9 11:02
     * @param $uid
     * @return array
     */
    public function getRandomCard($uid){
        $data=$card=[];
        $levelId = oo::commonOprModel('member')->getUserLevelId($uid);
        //获取已解锁的卡组
        $openCardGroupIdList = $this->getUnlockCardGroupByLevelId($levelId);
        //获取所有已解锁的卡组及金卡
        $cardInfo =$this->getCardInfo();
        foreach ($cardInfo as $key => $value) {
            if(in_array($value['cgid'],$openCardGroupIdList) && $value['ci_lockRank'] <= $levelId&&$value['grade']==2) {
                $card[$value['cgid']][] = $value;
            }
        }
        //用户已拥有卡片id list
        $userCardInfo = oo::commonOprModel('card')->getUserCardInfo($uid);
        $userCardTemp = array_keys($userCardInfo['ciid']);
        //排除已获得的金卡
        $lockCardGroupWeight = $allUnlockCard=$lockCardNum=[];
        foreach ($card as $cgid=>$val){
            foreach ($val as $k=>$v){
                if(!in_array($v["ciid"],$userCardTemp)){
                    $lockCardGroupWeight[$cgid][$v["ciid"]]= $v["weights"];
                    $lockCardNum[$cgid]++;
                }
                $allUnlockCardWeight[$v["ciid"]] = $v["weights"];
            }
        }
        
        $randCards=[];
        if(!empty($lockCardGroupWeight)){
            arsort($lockCardNum);
            foreach ($lockCardNum as $cgid=>$num){
                $randCards = $lockCardGroupWeight[$cgid];
                break;
            }
            $isNew =1;
        }else{
            $randCards = $allUnlockCardWeight;
            $isNew=0;
        }
        $data['id'] = oo::commonOprModel('slot')->get_rand($randCards);
        $data['isNew'] = $isNew;
        return $data;
    }

    /**
     * 获取随机金卡
     * @param $type 1普通卡 2金卡
     * @return array
     * Created by: Hss
     * Created on: 2020/9/17 17:33
     */
    public function getRandomCard_old($uid,$num = 1,$type = 2){
        $type = $type != 2 ?1:$type;
        $assetsInfo  = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $unlockCard = self::getUnlockCardByLevelId($assetsInfo['levelId']);

        $userCardInfo = oo::commonOprModel('card')->getUserCardInfo($uid);
        $userCardTemp = array_keys($userCardInfo['ciid']);

        $out = $randCards = [];
        $treasureCardConfig = oo::commonOprModel('config')->treasureCardConfig();
        $ce=1;$notHaveCard=0;
        $activateCfg = oo::commonOprModel('config')->cardCoefficient()['activate'];
        foreach($unlockCard as $key => $row){
            if($row['grade'] == $type){
                if(!in_array($row['ciid'],$userCardTemp)){//未激活的金卡
                    $notHaveCard++;//未拥有的未激活的金卡数
                }
            }
        }
        foreach($unlockCard as $key => $row){
            if($row['grade'] == $type){
                $ce =1;
                if(in_array($row['ciid'],$userCardTemp)) {//未激活的金卡
//                    $ce = $this->getHaveCardWeightCe($userCardInfo['ciid'][$row['ciid']]);//已经激活金卡权重修正系数
                    $ce = $userCardInfo['ciid'][$row['ciid']]==0?1:0.001;
                }
//                if(!in_array($row['ciid'],$userCardTemp)) {//未激活的金卡
//                    $ce = $activateCfg[$notHaveCard][1] ? $activateCfg[$notHaveCard][1] : 1;//未激活金卡权重修正系数
//                }
                $randCards[$row['ciid']] = $treasureCardConfig[$row['ciid']]*$ce*10000;//设置权重
            }
        }
        $i = $num;
        while($i--){
            $temp = [];
            $temp['id'] = oo::commonOprModel('slot')->get_rand($randCards);
            $temp['isNew'] = in_array($temp['ciid'],$userCardTemp);
            $out[] = $temp;
        }

        if($num == 1){
            return $out[0];
        }else{
            return $out;
        }
    }
    public function getHaveCardWeightCe($num){
        if ($num==0){
            return 1;
        }
        $arr=[1=>0.4,2=>0.3,3=>0.2,4=>0.1,5=>0.05,6=>0.02];
        if( isset($arr[$num])&&$arr[$num]!=0){
            return $arr[$num];
        }
        return 0.01;
    }
    /**
     * 根据用户调整卡片权重
     * @param $uid
     * @param $card
     * @return mixed
     * Created by: Owen
     * Created on: 2020/10/24 14:30 -- 20210121 弃用
     */
    public function changeCardWeightsByUserId($uid,$card){
        $oddNum = $uid % 2 == 1 ? true : false;
        $n = 0.6;
        $m = 0.6;
        foreach ($card as $key=>$row){
            if($row['cgid'] < 3 || $row['ci_star_rank'] >= 5){
                continue;
            }
            if($oddNum){ // 奇数
                ($row['cgid'] % 2 ==1 ) ? $card[$key]['weights'] = ceil($row['weights'] * (1+$m)) : $card[$key]['weights'] = ceil($row['weights'] * (1-$n));
            }else{ // 偶数
                ($row['cgid'] % 2 ==1 ) ? $card[$key]['weights'] = ceil($row['weights'] * (1-$n)) : $card[$key]['weights'] = ceil($row['weights'] * (1+$m));
            }
        }
        return $card;
    }

    /**
     * 卡组格式
     * @param $cardArr
     * @return array
     * Created by: Owen
     * Created on: 2021/1/21 20:34
     */
    public function userCardGroupFormat($cardArr){
        $format = [];
        foreach ($cardArr as $cid=>$num){
            if(!$cid&&$cid!==0){
                continue;
            }
            $gid = intval(($cid - 1) / 9);
            $pid = intval(($cid - 1) % 9);
            $format[$gid][$pid] = $num;
        }
        return $format;
    }

    /**
     * 根据用户调整卡片权重
     * @param $config
     * @param $userCard
     * @param $data
     * Created by: Owen
     * Created on: 2021/1/21 20:34
     */
    public function changeCardWeights($config,&$userCard,&$data){
        $formatArr = $this->userCardGroupFormat($userCard);
        $numCoArr = [0 => 1, 1 => 0.5, 2 => 0.4, 3 => 0.3, 4 => 0.2, 5 => 0.1];
        $activateCoArr = [
            0 => [1,0  ],
            1 => [1,0.1],
            2 => [1,0.6],
            3 => [1,0.5],
            4 => [1,0.4],
            5 => [1,0.5],
            6 => [1,1  ],
            7 => [0,1  ],
            8 => [0,1  ],
            9 => [0,1  ]];
        if(!empty($config['num'])){
            $numCoArr = $config['num'];
        }
        if(!empty($config['activate'])){
            $activateCoArr = $config['activate'];
        }
        foreach ($data as $key=>$row){
            $cardNum  = min(intval($userCard[$row['ciid']]),max(count($numCoArr) - 1,0));
            $groupNum = empty($formatArr[$row['cgid']]) ? 9 : max(9 - count($formatArr[$row['cgid']]),0);
            $activateCo = $activateCoArr[$groupNum];
            $isActivate = isset($userCard[$row['ciid']]) ? 0 : 1;
            $data[$key]['weights'] = $row['weights'] * $numCoArr[$cardNum] * $activateCo[$isActivate];
        }
    }

    /**
     * 设置小丑卡
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2021/2/20 11:47
     */
    public function setJokerCard($uid){
        $cacheKey = okeys::JokerCard($uid);
        $ttl      = oo::commonOprRedis('User')->ttl($cacheKey);
        $default  = 86400;
        if($ttl > 0){
            $default = $default + $ttl;
        }
        oo::commonOprRedis('User')->setex($cacheKey,1,$default);
        oo::async()->add('oo::commonOprModel("notice")->sendNoticeMsg',[$uid,"getCard"]);//获得小丑卡跑马灯消息
        return time() + $default;
    }

}

