123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- <?php
- /**
- * 排行榜
- * Created by PhpStorm.
- * User: guanxl
- * Date: 2018/3/27
- * Time: 9:13
- */
-
- namespace App\Services;
-
- use App\Models\User;
- use App\Traits\Singleton;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Redis;
-
- class TopService
- {
- use Singleton;
- const KNOWLEDGE_TOP = "bs_top:km";
- const JOIN_TOP = "bs_top:join";
- const JOIN_RATE_TOP = "bs_top:joinrate";
- const KM_AVG_TOP = "bs_top:kmavg";
- const PK_TOP = "bs_top:users:pk";
- const KM_TOP = "bs_top:users:km";
- const TOP_USERS = "bs_top:users";
-
- /**
- * @param $activityId
- */
- protected function cacheDepartmentTop($activityId){
-
- $datas = DB::select("select count(*) as user_num,sum(is_blockade_success_copy) as sum_is_blockade_success,sum(knowledge_money)as sum_knowledge_money,department_id,avg(knowledge_money) as avg_knowledge_money from bs_users where department_id>0 and status=1 and activity_id={$activityId}
- GROUP BY department_id");
-
- foreach ($datas as $data){
- $joinRate = 0;
- if($data->user_num>0){
- $joinRate = ($data->sum_is_blockade_success/$data->user_num)*100;
- }
- Redis::zAdd(self::KNOWLEDGE_TOP.":".$activityId,$data->sum_knowledge_money,$data->department_id);
- Redis::zAdd(self::JOIN_TOP.":".$activityId,$data->sum_is_blockade_success,$data->department_id);
- Redis::zAdd(self::JOIN_RATE_TOP.":".$activityId,$joinRate,$data->department_id);
- Redis::zAdd(self::KM_AVG_TOP.":".$activityId,$data->avg_knowledge_money,$data->department_id);
- }
-
- Redis::expire(self::KNOWLEDGE_TOP.":".$activityId,300);
- Redis::expire(self::JOIN_RATE_TOP.":".$activityId,300);
- Redis::expire(self::JOIN_TOP.":".$activityId,300);
- Redis::expire(self::KM_AVG_TOP.":".$activityId,300);
-
- }
-
- /**
- * 个人知识币全行排行榜信息
- * @param $activityId
- * @param string $limit
- * @return mixed
- */
- public function personKmTop($activityId,$limit = "")
- {
- return $this->getKmTop($activityId,$limit);
- }
-
- /**
- * 得到用户在全行的排名
- * @param $activityId
- * @param $userId
- * @return mixed
- */
- public function personKmRank($activityId,$userId)
- {
- return $this->getKmRank($activityId,$userId);
- }
-
- /**
- * 所有用户在全行的PK排名
- * @param $activityId
- * @param string $limit
- * @return mixed
- */
- public function personPktop($activityId,$limit=""){
- return $this->getPkTop($activityId,$limit);
- }
-
- /**
- * 当前用户在全行的排名
- * @param $activityId
- * @param $userId
- * @return int
- */
- public function personPkRank($activityId,$userId)
- {
- return $this->getPkRank($activityId,$userId);
- }
-
- /**
- * 现在1000名的知识币
- * 可以获得奖项的知识币
- * @param $activityId
- * @param int $rank
- * @return int
- */
- public function prizeKmRank($activityId,$rank = 1000)
- {
- $users = User::where("activity_id",$activityId)->where("status",1)
- ->where("is_blockade_success",1)
- ->orderBy("knowledge_money","desc")
- ->pluck("knowledge_money","user_id");
- $users = collect($users)->toArray();
- $i=0;
- foreach ($users as $key=>$knowledgeMoney){
- $i++;
- if($i==$rank){
- return $knowledgeMoney;
- }
- }
- return 0;
- }
-
- /**
- * 个人知识币分行排行榜信息
- * @param $activityId
- * @param $departmentId
- * @param string $limit
- * @return mixed
- */
- public function personKmDepartmentTop($activityId,$departmentId,$limit = "")
- {
-
- $userIds = DepartmentService::getInstance()->getUserIdsByDepartmentId($departmentId);
- $users = [];
- if($userIds){
- $users = $this->getUsers($activityId,collect($userIds)->toArray());
- }
- if($limit>0){
- $users = collect($users)->sortByDesc("knowledge_money")->values()->take($limit);
- }else{
- $users = collect($users)->sortByDesc("knowledge_money")->values()->all();
- }
-
- return $users;
-
- }
-
-
- /**
- * 得到用户在分行的排名
- * @param $activityId
- * @param $userId
- * @param $departmentId
- * @return mixed
- */
- public function personKmDepartmentRank($activityId,$userId, $departmentId)
- {
- $userIds = DepartmentService::getInstance()->getUserIdsByDepartmentId($departmentId);
- $users = [];
- if($userIds){
- $users = $this->getUsers($activityId,collect($userIds)->toArray());
- }
- $users = collect($users)->sortByDesc("knowledge_money")->values()->all();
- $i=0;
- foreach ($users as $user){
- $i++;
- if($user["user_id"]==$userId){
- return $i;
- }
- }
- }
-
- /**
- * 获取所有分行员工完成必答排行
- * @param $activityId
- * @param string $limit
- * @return mixed
- */
- public function departmentJoinTop($activityId,$limit = "")
- {
- $redisKey = self::JOIN_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $this->cacheDepartmentTop($activityId);
- }
- $options = array('withscores' => true);
- if ($limit) {
- $options["limit"] = $limit;
- }
- return Redis::zRevrangebyscore($redisKey, "+inf", "-inf", $options);
- }
-
- /**
- * 获取所有分行的总知识币
- * @param $activityId
- * @param string $limit
- * @return mixed
- */
- public function departmentKmTop($activityId,$limit="")
- {
- $redisKey = self::KNOWLEDGE_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $this->cacheDepartmentTop($activityId);
- }
- $options = array('withscores' => true);
- if ($limit) {
- $options["limit"] = $limit;
- }
- return Redis::zRevrangebyscore($redisKey, "+inf", "-inf", $options);
- }
-
- /**
- * 获取分行参与率的排行榜
- * @param $activityId
- * @param string $limit
- * @return
- */
- public function departmentJoinRateTop($activityId,$limit = "")
- {
- $redisKey = self::JOIN_RATE_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $this->cacheDepartmentTop($activityId);
- }
- $options = array('withscores' => true);
- if ($limit) {
- $options["limit"] = $limit;
- }
- return Redis::zRevrangebyscore($redisKey, "+inf", "-inf", $options);
- }
-
- /**
- * 获取分行平均分排行榜
- * @param $limit
- * @return mixed
- */
- public function departmentKmAvgTop($activityId,$limit = "")
- {
- $redisKey = self::KM_AVG_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $this->cacheDepartmentTop($activityId);
- }
- $options = array('withscores' => true);
- if ($limit) {
- $options["limit"] = $limit;
- }
- return Redis::zRevrangebyscore($redisKey, "+inf", "-inf", $options);
- }
-
- /**
- * 某分行的排名
- * @param $activityId
- * @param $departmentId
- * @return array
- */
- public function departmentJoinRateRank($activityId,$departmentId)
- {
- $redisKey = self::JOIN_RATE_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $this->cacheDepartmentTop($activityId);
- }
-
- $rank = Redis::zRevrank($redisKey, $departmentId);
- if (is_null($rank)) {
- return ["index" => 0, "rate" => 0];
- } else {
- $rate = Redis::zScore($redisKey, $departmentId);
- return ["index" => $rank + 1, "rate" => $rate];
- }
- }
-
- /**
- * 某分行的排名
- * @param $departmentId
- * @return array
- */
- public function departmentKmAvgRank($activityId,$departmentId)
- {
- $redisKey = self::KM_AVG_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $this->cacheDepartmentTop($activityId);
- }
-
- $rank = Redis::zRevrank($redisKey, $departmentId);
- if (is_null($rank)) {
- return ["index" => 0, "avg_knowledge_money" => 0];
- } else {
- $avgKm = Redis::zScore($redisKey, $departmentId);
- return ["index" => $rank + 1, "avg_knowledge_money" => round($avgKm,2)];
- }
- }
-
- /**
- * 获得用户排行信息
- * @param $activityId
- * @param array $userIds
- * @return array
- */
- public function getUsers($activityId,$userIds=[]){
- $redisKey = self::TOP_USERS.":".$activityId;
- if(!Redis::exists($redisKey)){
- $departments = DepartmentService::getInstance()->all($activityId);
- $pagesize = 5000;
- $count = User::where("activity_id",$activityId)->where("status",1)->count();
- $pageCount = ceil($count/$pagesize);
- for ($page=0;$page<$pageCount;$page++){
- $users = User::where("activity_id",$activityId)->where("status",1)->offset($page*$pagesize)->limit($pagesize)->get([
- "user_id","name","avatar","department_id","knowledge_money","user_level","user_star"
- ]);
-
- $redisData = [];
- foreach ($users as $user){
- $user = collect($user)->toArray();
- $user["department_name"] = empty($departments[$user["department_id"]])? "":$departments[$user["department_id"]];
- $redisData[$user["user_id"]] = json_encode($user,256);
- }
- if($redisData){
- Redis::hmset($redisKey,$redisData);
- }
- }
- Redis::expire($redisKey,864000);
- }
- if(empty($userIds)){
- $users = Redis::hgetall($redisKey);
- }else{
- $users = Redis::hmget($redisKey,$userIds);
- }
- $datas = [];
- foreach ($users as $key=>$val){
- $datas[$key] = json_decode($val,true);
- }
- return $datas;
- }
-
-
- /**
- * 更新用户的排名信息
- * @param $userId
- * @return mixed
- */
-
- public function updateUserTop($userId){
- $user = UserService::getInstance()->getUser($userId,"",true);
- if($user){
- $activityId = $user["activity_id"];
- $redisData = [
- "user_id" => $userId,
- "name" => $user["name"],
- "avatar" => $user["avatar"],
- "department_id" => $user["department_id"],
- "department_name" => DepartmentService::getInstance()->getDepartmentName($user["department_id"]),
- "knowledge_money" => $user["knowledge_money"],
- "user_level" => $user["user_level"],
- "user_star" => $user["user_star"]
- ];
- if(Redis::exists(self::TOP_USERS . ":".$activityId)) {
- Redis::hset(self::TOP_USERS . ":" . $activityId, $userId, json_encode($redisData, 256));
- }
- if(Redis::exists(self::KM_TOP . ":".$activityId)){
- Redis::zadd(self::KM_TOP . ":".$activityId,$user["knowledge_money"],$userId);
- }
- if(Redis::exists(self::PK_TOP . ":".$activityId)) {
- Redis::zadd(self::PK_TOP . ":" . $activityId, $user["user_level"] * 1000 + $user["user_star"], $userId);
- }
- return true;
- }
- return false;
- }
-
-
- /**
- * 取用户的km段位排名
- * @param $activityId
- * @param $userId
- * @return int
- */
- public function getKmRank($activityId,$userId){
- $redisKey = self::KM_TOP . ":".$activityId;
- $this->getKmTop($activityId,1);
- $rank = Redis::zRevrank($redisKey, $userId);
- if (is_null($rank)) {
- return 0;
- } else {
- return $rank + 1;
- }
- }
-
-
- /**
- * 取用户的PK段位排名
- * @param $activityId
- * @param $userId
- * @return int
- */
- public function getPkRank($activityId,$userId){
- $redisKey = self::PK_TOP . ":".$activityId;
- $this->getPkTop($activityId,1);
- $rank = Redis::zRevrank($redisKey, $userId);
- if (is_null($rank)) {
- return 0;
- } else {
- return $rank + 1;
- }
- }
-
- /**
- * PK段位排行榜
- * @param $activityId
- * @param int $limit
- * @return mixed
- */
- public function getPkTop($activityId,$limit=100){
- $redisKey = self::PK_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $users = $this->getUsers($activityId);
- foreach ($users as $key=>$val){
- Redis::zadd($redisKey,$val["user_level"]*1000+$val["user_star"],$key);
- }
- Redis::expire($redisKey,84600);
- }
-
- $options = [];
- if ($limit) {
- $options["limit"] = [0,$limit];
- }
- $datas = [];
- $userIds = Redis::zRevrangebyscore($redisKey, "+inf", "-inf", $options);
- if($userIds){
- $datas = $this->getUsers($activityId,$userIds);
- }
- return $datas;
- }
-
- /**
- * 知识币排行
- * @param $activityId
- * @param int $limit
- * @return mixed
- */
- public function getKmTop($activityId,$limit=100){
- $redisKey = self::KM_TOP . ":".$activityId;
- if(!Redis::exists($redisKey)){
- $users = $this->getUsers($activityId);
- foreach ($users as $key=>$val){
- Redis::zadd($redisKey,$val["knowledge_money"],$key);
- }
- Redis::expire($redisKey,84600);
- }
-
- $options = [];
- if ($limit) {
- $options["limit"] = [0,$limit];
- }
- $userIds = Redis::zRevrangebyscore($redisKey, "+inf", "-inf", $options);
- $datas = [];
- if($userIds){
- $datas = $this->getUsers($activityId,$userIds);
- }
- return $datas;
- }
- }
|