123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- <?php
- /**
- * 排行榜相关
- */
- class ModelRank
- {
- protected $moneyRankLimit = 200; //世界排行榜
- protected $friMoneyRankLimit = 200; //好友排行榜人数限制
- protected $friNumLimit = 500; //好友人数限制
- protected $worldRankSum =1000;//最大世界排行
- protected $countryRankSum = 50;//最大国家排行
- protected $countryMaster =['RO','US','DE','GB','ES','FR','IN'];//主要国家:罗马尼亚,美国,德国,英国,西班牙,法国,印度,其他
- protected $rankMinStar = 2000; //正式服排行榜最小上榜值
- /**
- * Notes:获取排行榜信息
- * User: wsc
- * Time: 2020/5/6 19:26
- * @param $uid
- * @param bool $falg
- * @return array
- */
- public function getStaRank($uid,$falg=false){
- $my_friend_num = $my_country_num = 0;
- //好友榜
- $friendRankList = $this->getFriendRank($uid);
- //世界排行
- $friends = oo::commonOprModel('friend')->getUserAllFriend($uid);
- $worldRankList = $this->getWorldStaRank();
- foreach ($worldRankList as $k=>$v){
- $worldRankList[$k]['isFri'] = in_array($v['uid'],$friends)?1:0;
- }
- //国家排行
- $countryList = $this->getCountryRank($uid);
- $myRank = $this->getMyRank($uid);
- foreach ($friendRankList as $k=>$v){
- if($v['uid']==$uid){
- $my_friend_num = $k+1;
- }
- }
- $myRank['my_friend_rank'] = $my_friend_num;
- if(!empty($countryList)){
- foreach ($countryList as $k=>$v){
- if($v['uid']==$uid){
- $my_country_num = $k+1;
- }
- }
- $myRank['my_country_rank'] = $my_country_num<=$this->countryRankSum&&$my_country_num>0?$my_country_num:">".$this->countryRankSum;
- $countryList = array_values($countryList);
- }else{
- $countryList = [];
- $myRank['my_country_rank'] =0;
- }
- $myRank['max_worldRank'] = $this->worldRankSum;
- $myRank['max_countryRank'] = $this->countryRankSum;
- $data = [
- "code"=>1,
- "list"=>[
- "fir"=>$friendRankList,
- "world"=>array_values($worldRankList),
- "self"=>$myRank,
- "country"=>$countryList,
- ]
- ];
- oo::commonOprRedis('User')->setex(okeys::UserRankData($uid),json_encode([
- 'friend' => $myRank['my_friend_rank'],
- 'country' => $myRank['my_country_rank'],
- 'world' => $myRank['pos'],
- ]),oo::redisRandomExpire(3*24*60*60));
- return $data;
- }
- /**
- * Notes:获取我的世界排名
- * User: wsc
- * Time: 2020/5/6 19:25
- * @param $uid
- * @return array
- */
- public function getMyRank($uid){
- $data = [];
- $info = oo::commonOprModel('member')->getUserBasic($uid);
- $stakey = okeys::worldStaRank();
- $res = oo::commonOprRedis('common')->zRevRank($stakey,$uid);
- $data['pos'] = $res?$res:">".$this->worldRankSum;
- $data['star'] = $info['star'];
- $data['nick'] = oo::commonOprModel('member')->getUserFirstName($info['nick']);
- $data['s_picture'] = $info['s_picture'];
- $data['u_flag'] = $info['u_flag'];
- return $data;
- }
- /**
- * Notes:获取我的好友排行榜
- * User: wsc
- * Time: 2020/5/6 19:25
- * @param $uid
- * @return array
- */
- public function getFriendRank($uid){
- $friends = oo::commonOprModel('friend')->getUserAllFriend($uid);
- $fbList = oo::commonOprModel('friend')->getUserAllFriend($uid,'fb');
- array_push($friends,$uid);
- $friends = array_unique($friends);
- foreach ($friends as $k=>$v){
- $friendRankList[$k] = oo::commonOprModel('member')->getUserBasic($v);
- $infoArr = oo::commonOprModel('member')->getAccount($friendRankList[$k]['siteuid']);
- $friendRankList[$k]['isFb'] =!empty($infoArr) && $infoArr['uid'] == $v?1:0;
- unset($friendRankList[$k]['spins']);
- unset($friendRankList[$k]['shield']);
- // unset($friendRankList[$k]['coins']);
- unset($friendRankList[$k]['siteuid']);
- $friendRankList[$k]['isFbFriend'] = in_array($v,$fbList)?1:0;
- $friendRankList[$k]['build'] = oo::commonOprModel('member')->getUserLevel($v)['element'];
- }
- array_multisort(array_column($friendRankList,'star'),SORT_DESC,array_column($friendRankList,'money'),SORT_DESC,$friendRankList);
- $friendRankList =count($friendRankList)>$this->friMoneyRankLimit? array_slice($friendRankList,0,$this->friMoneyRankLimit):$friendRankList;
- return $friendRankList;
- }
- /**
- * Notes:获取世界排行(定时传参true刷新)
- * User: wsc
- * Time: 2020/5/6 19:24
- * @param bool $db
- * @return array
- */
- public function getWorldStaRank($db=false){
- $cache= [];
- $wkey = okeys::worldRankInfo();
- if(!$db){
- $jsonStr =oo::commonOprRedis('common')->hGetAll($wkey);
- $cache = funs::getArrFromJsonArr($jsonStr);
- array_multisort(array_column($cache,'star'),SORT_DESC,array_column($cache,'money'),SORT_DESC,$cache);
- }
- if(empty($cache)){
- oo::commonOprRedis('common')->delete($wkey);
- $rankList = $this->newWorldStaRank($db);
- $i=0;
- foreach ($rankList as $k=>$v){
- $cache[$i] = $this->getUserSomeInfo($k);
- $data[$i] = json_encode($cache[$i]);
- $i++;
- }
- oo::commonOprRedis('common')->hMset($wkey,$data);
- }
- return $cache;
- }
- /**
- * Notes:更新世界排行
- * User: wsc
- * Time: 2020/5/20 19:49
- * @param bool $db
- * @return array
- */
- public function newWorldStaRank($db=false){
- $cache = [];
- $max = oo::commonOprModel('readconfig')->getCon('Rank','maxNum');
- $stakey = okeys::worldStaRank();
- if(!$db){
- $cache =oo::commonOprRedis('common')->zRevRange($stakey,0,49,true);
- }
- if(empty($cache)){
- $tb = otable::gh_gameserver(1);
- $sql = "SELECT mid as uid,star FROM {$tb} ORDER BY star DESC,money DESC LIMIT {$this->worldRankSum}";
- $arr = oo::commonOprDb('common')->getAll($sql,MYSQLI_ASSOC);
- if(!empty($arr)){
- oo::commonOprRedis('common')->delete($stakey);
- foreach ($arr as $k=>$v){
- oo::commonOprRedis('common')->zAdd($stakey,$v['star'],$v['uid']);
- $cache[$v['uid']] = $v['star'];
- }
- $cache = array_slice($cache,0,50,true);
- // oo::logs()->debug3(["do"=>'update worldRank is success',"data"=>$cache],'worldRank.log');
- }
- }
- return $cache;
- }
- /**
- * Notes:获取个人国家排行榜
- * User: wsc
- * Time: 2020/5/20 19:59
- * @param $uid
- * @return array
- */
- public function getCountryRank($uid){
- $info = oo::commonOprModel('ipaddress')->getUserCountry($uid);
- $ckey = okeys::countryRank($info['showCode']);
- $jsonStr =oo::commonOprRedis('common')->hGetAll($ckey);
- $cache = funs::getArrFromJsonArr($jsonStr);
- if(empty($cache)){
- return [];
- }
- array_multisort(array_column($cache,'star'),SORT_DESC,array_column($cache,'money'),SORT_DESC,$cache);
- return $cache;
- }
- /**
- * Notes:更新国家排行(新版)
- * User: richard
- * Time: 2021/3/30 18:29
- * @return array
- */
- public function newCountryRank(){
- $tb = otable::useraddress();
- $tb2 = otable::gh_gameserver(1);
- $minStar = IS_DEBUF ? 500 : $this->rankMinStar; //最小星星上榜值
- $min = 0;
- //设置主要国家排行
- foreach ($this->countryMaster as $country_code){
- $ckey = okeys::countryRank($country_code);
- $tmp = oo::commonOprRedis('common')->hGet($ckey, 49); //找到最后一名的数据
- if(empty($tmp)){ //如果没有50名排行,找最小的一个
- $tmpArr = oo::commonOprRedis('common')->hGetAll($ckey);
- krsort($tmpArr);
- $tmp = $tmpArr ? current($tmpArr) : [];
- }
- $lastRank = $tmp ? (array)json_decode($tmp, true) : [];
- $star = !empty($lastRank['star']) ? $lastRank['star'] : $this->rankMinStar;
- if(empty($min) || $min > $star){
- $min = $star;
- }
- }
- $ckey2 = okeys::countryRank("OTHER");
- $tmp = oo::commonOprRedis('common')->hGet($ckey2, 49); //找到最后一名的数据
- $lastRank = $tmp ? (array)json_decode($tmp, true) : [];
- $star = !empty($lastRank['star']) ? $lastRank['star'] : $this->rankMinStar;
- $min = $min > $star ? $star : $min;
- $min = empty($min) ? $minStar : $min;
- $sql = "SELECT mid,star FROM {$tb2} WHERE star >= {$min} ORDER BY star DESC";
- $tmpList = oo::commonOprDb('common')->getAll($sql,MYSQLI_ASSOC);
- $rankUids = $tmpList ? array_column($tmpList, 'mid') : [];
- if(empty($rankUids)){
- return [[], []];
- }
- $cache = $data = [];
- foreach ($this->countryMaster as $country_code){
- $uidList = [];
- for($i = 0; $i < count($rankUids); $i=$i+5000){
- $tmpUids = array_slice($rankUids, $i, 5000);
- $uidStr = implode(',', $tmpUids);
- $sql = "SELECT uid FROM {$tb} WHERE country_code = '{$country_code}' AND uid IN({$uidStr})";
- $tmpUids = oo::commonOprDb('common')->getAll($sql,MYSQLI_ASSOC);
- $uidList = array_merge($uidList, $tmpUids);
- }
- if(empty($uidList)){
- return [];
- }
- $ckey = okeys::countryRank($country_code);
- $uids = array_column($uidList, 'uid');
- oo::commonOprRedis('common')->delete($ckey);
- $index = 0;
- $cache = $data = [];
- foreach($rankUids as $uid){
- if(!in_array($uid, $uids)){
- continue;
- }
- $cache[$index] = $this->getUserSomeInfo($uid);
- $data[$index] = json_encode($cache[$index]);
- $index++;
- if($index > 49){
- break;
- }
- }
- oo::commonOprRedis('common')->hMset($ckey,$data);
- }
- //设置其他国家排行
- $masterStr = '"'.implode('","',$this->countryMaster).'"';
- $sql = "SELECT uid FROM {$tb} WHERE country_code NOT IN($masterStr) AND uid IN({$uidStr})";
- $uidList = oo::commonOprDb('common')->getAll($sql,MYSQLI_ASSOC);
- if(empty($uidList)){
- return [$data, []];
- }
- $uids = array_column($uidList, 'uid');
- oo::commonOprRedis('common')->delete($ckey2);
- $index = 0;
- $cache2 = $data2 = [];
- foreach($rankUids as $uid){
- if(!in_array($uid, $uids)){
- continue;
- }
- $cache2[$index] = $this->getUserSomeInfo($uid);
- $data2[$index] = json_encode($cache[$index]);
- $index++;
- if($index > 49){
- break;
- }
- }
- oo::commonOprRedis('common')->hMset($ckey2,$data2);
- return [$data,$data2];
- }
- /**
- * Notes:更新国家排行(旧版)
- * User: wsc
- * Time: 2020/5/20 19:59
- * @return array
- */
- public function newCountryRankOld(){
- $tb = otable::useraddress();
- $tb2 = otable::gh_gameserver(1);
- //设置主要国家排行
- foreach ($this->countryMaster as $country_code){
- $sql = "SELECT a.uid,a.country_code,b.star FROM {$tb} a LEFT JOIN {$tb2} b ON a.uid=b.mid WHERE a.country_code='{$country_code}' order by b.star DESC LIMIT 50";
- $list = oo::commonOprDb('common')->getAll($sql,MYSQLI_ASSOC);
- $ckey = okeys::countryRank($country_code);
- if(!empty($list)){
- $i=0;
- oo::commonOprRedis('common')->delete($ckey);
- foreach ($list as $k=>$v){
- $cache[$i] = $this->getUserSomeInfo($v['uid']);
- $data[$i] = json_encode($cache[$i]);
- $i++;
- }
- oo::commonOprRedis('common')->hMset($ckey,$data);
- }
- }
- //设置其他国家排行
- $masterStr = '"'.implode('","',$this->countryMaster).'"';
- $sql = "SELECT a.uid,a.country_code,b.star FROM {$tb} a LEFT JOIN {$tb2} b ON a.uid=b.mid WHERE a.country_code NOT IN({$masterStr}) ORDER BY b.star DESC LIMIT 50";
- $list2 = oo::commonOprDb('common')->getAll($sql,MYSQLI_ASSOC);
- $ckey2 = okeys::countryRank("OTHER");
- $i=0;
- foreach ($list2 as $k=>$v){
- oo::commonOprRedis('common')->delete($ckey2);
- $cache[$i] = $this->getUserSomeInfo($v['uid']);
- $data2[$i] = json_encode($cache[$i]);
- $i++;
- oo::commonOprRedis('common')->hMset($ckey2,$data2);
- }
- return [$data,$data2];
- }
- public function getUserSomeInfo($uid){
- $cache = oo::commonOprModel('member')->getUserBasic($uid);
- $infoArr = oo::commonOprModel('member')->getAccount($cache['siteuid']);
- $cache['isFb'] =!empty($infoArr) && $infoArr['uid'] == $uid?1:0;
- $cache['fbId'] = $cache['siteuid'];
- $cache['build'] = oo::commonOprModel('member')->getUserLevel($uid)['element'];
- unset($cache['spins']);
- unset($cache['shield']);
- // unset($cache['coins']);
- unset($cache['siteuid']);
- return $cache;
- }
- }
|