Przeglądaj źródła

修复房屋排行榜功能:限制前100名、增加10分钟缓存、处理用户不在排名中的情况

- 修复Handler中pageSize参数为0的问题,当getPerPage()返回0时使用默认值20
- 限制排行榜只显示前100名,超出范围返回空结果
- 增加10分钟缓存机制,提高查询性能
- 优化用户排名查询,超出前100名返回0表示未上榜
- 移除调试代码dd()语句,确保数据正常返回
- 修复分页信息计算,确保total不超过100
notfff 7 miesięcy temu
rodzic
commit
fda9514c

+ 6 - 6
app/Module/AppGame/Handler/House/RankHandler.php

@@ -32,25 +32,25 @@ class RankHandler extends BaseHandler
     {
         try {
             $userId = $this->user_id;
-            
+
             // 获取分页参数
             $page = $data->getPage();
             $pageNum = $page ? $page->getPage() : 1;
-            $pageSize = $page ? $page->getPerPage() : 20;
-            
+            $pageSize = $page && $page->getPerPage() > 0 ? $page->getPerPage() : 20;
+
             // 调用服务层获取排行榜数据
             $rankData = HouseService::getHouseRankList($userId, $pageNum, $pageSize);
-            
+
             // 转换为Protobuf格式并返回
             return HouseRankDto::toProtobuf($rankData);
-            
+
         } catch (\Exception $e) {
             Log::error('获取房屋排行榜失败', [
                 'user_id' => $this->user_id ?? 0,
                 'error' => $e->getMessage(),
                 'trace' => $e->getTraceAsString()
             ]);
-            
+
             throw new LogicException('获取排行榜数据失败');
         }
     }

+ 66 - 21
app/Module/Farm/Logics/HouseLogic.php

@@ -269,24 +269,48 @@ class HouseLogic
     public function getHouseRankList(int $userId, int $page = 1, int $pageSize = 20): HouseRankDto
     {
         try {
-            // 计算偏移量
+            // 限制只显示前100名
+            $maxRankLimit = 100;
             $offset = ($page - 1) * $pageSize;
 
-            // 查询排行榜数据,按房屋等级降序排列
-            $rankList = DB::table('farm_users as fu')
-                ->join('users as u', 'fu.user_id', '=', 'u.id')
-                ->select([
-                    'fu.user_id',
-                    'fu.house_level',
-                    'u.username as nickname', // 使用username作为昵称
-                    'fu.last_upgrade_time'
-                ])
-                ->orderBy('fu.house_level', 'desc')
-                ->orderBy('fu.last_upgrade_time', 'asc') // 同等级按升级时间排序
-                ->offset($offset)
-                ->limit($pageSize)
-                ->get()
-                ->toArray();
+            // 如果请求的数据超出前100名,返回空结果
+            if ($offset >= $maxRankLimit) {
+                return new HouseRankDto([], 0, 1, [
+                    'page' => $page,
+                    'per_page' => $pageSize,
+                    'total' => min($maxRankLimit, $this->getTotalHouseRankCount())
+                ]);
+            }
+
+            // 调整查询限制,确保不超过前100名
+            $actualLimit = min($pageSize, $maxRankLimit - $offset);
+
+            // 尝试从缓存获取排行榜数据
+            $cacheKey = $this->cachePrefix . 'house_rank:top100';
+            $cachedRankList = Cache::get($cacheKey);
+
+            if (!$cachedRankList) {
+                // 查询前100名排行榜数据,按房屋等级降序排列
+                $cachedRankList = DB::table('farm_users as fu')
+                    ->join('users as u', 'fu.user_id', '=', 'u.id')
+                    ->select([
+                        'fu.user_id',
+                        'fu.house_level',
+                        'u.username as nickname', // 使用username作为昵称
+                        'fu.last_upgrade_time'
+                    ])
+                    ->orderBy('fu.house_level', 'desc')
+                    ->orderBy('fu.last_upgrade_time', 'asc') // 同等级按升级时间排序
+                    ->limit($maxRankLimit)
+                    ->get()
+                    ->toArray();
+
+                // 缓存10分钟
+                Cache::put($cacheKey, $cachedRankList, 600);
+            }
+
+            // 从缓存数据中获取当前页的数据
+            $rankList = array_slice($cachedRankList, $offset, $actualLimit);
 
             // 转换为DTO对象
             $rankItems = [];
@@ -302,7 +326,7 @@ class HouseLogic
             $pageInfo = [
                 'page' => $page,
                 'per_page' => $pageSize,
-                'total' => $this->getTotalHouseRankCount()
+                'total' => min($maxRankLimit, $this->getTotalHouseRankCount())
             ];
 
             return new HouseRankDto($rankItems, $userRank, 1, $pageInfo);
@@ -324,14 +348,23 @@ class HouseLogic
      * 获取用户的房屋排名
      *
      * @param int $userId 用户ID
-     * @return int 排名,0表示未上榜
+     * @return int 排名,0表示未上榜或超出前100名
      */
     private function getUserHouseRank(int $userId): int
     {
         try {
+            // 尝试从缓存获取用户排名
+            $cacheKey = $this->cachePrefix . 'user_house_rank:' . $userId;
+            $cachedRank = Cache::get($cacheKey);
+
+            if ($cachedRank !== null) {
+                return $cachedRank;
+            }
+
             // 获取用户的房屋等级
             $userFarm = FarmUser::where('user_id', $userId)->first();
             if (!$userFarm) {
+                Cache::put($cacheKey, 0, 600); // 缓存10分钟
                 return 0;
             }
 
@@ -349,7 +382,17 @@ class HouseLogic
                 })
                 ->count();
 
-            return $rank + 1;
+            $finalRank = $rank + 1;
+
+            // 如果用户排名超出前100名,返回0表示未上榜
+            if ($finalRank > 100) {
+                $finalRank = 0;
+            }
+
+            // 缓存用户排名10分钟
+            Cache::put($cacheKey, $finalRank, 600);
+
+            return $finalRank;
 
         } catch (\Exception $e) {
             Log::error('获取用户房屋排名失败', [
@@ -362,14 +405,16 @@ class HouseLogic
     }
 
     /**
-     * 获取房屋排行榜总数
+     * 获取房屋排行榜总数(限制前100名)
      *
      * @return int
      */
     private function getTotalHouseRankCount(): int
     {
         try {
-            return FarmUser::count();
+            // 获取实际用户总数,但最多返回100
+            $actualCount = FarmUser::count();
+            return min($actualCount, 100);
         } catch (\Exception $e) {
             Log::error('获取房屋排行榜总数失败', [
                 'error' => $e->getMessage()

+ 1 - 1
config/proto_route.php

@@ -91,7 +91,7 @@ return array (
       7 => 'query_data',
     ),
   ),
-  'generated_at' => '+08:00 2025-06-10 13:57:34',
+  'generated_at' => '+08:00 2025-06-10 16:44:10',
   'conventions' => 
   array (
     'handler_namespace' => 'App\\Module\\AppGame\\Handler',

+ 1 - 1
protophp/GPBMetadata/Proto/Game.php

@@ -408,7 +408,7 @@ PublicLand
 level (
 user_id (
 reason (
-nickname (
+nickname (	
 ResponsePetGet‘
 ResponsePetRank,
 page (2.uraus.kku.Common.ResponsePage

+ 8 - 8
protophp/Uraus/Kku/Response/FarmRankItem.php

@@ -42,9 +42,9 @@ class FarmRankItem extends \Google\Protobuf\Internal\Message
     /**
      * 昵称
      *
-     * Generated from protobuf field <code>int64 nickname = 5;</code>
+     * Generated from protobuf field <code>string nickname = 5;</code>
      */
-    protected $nickname = 0;
+    protected $nickname = '';
 
     /**
      * Constructor.
@@ -60,7 +60,7 @@ class FarmRankItem extends \Google\Protobuf\Internal\Message
      *           用户ID
      *     @type int|string $reason
      *           第几届/赛季
-     *     @type int|string $nickname
+     *     @type string $nickname
      *           昵称
      * }
      */
@@ -176,8 +176,8 @@ class FarmRankItem extends \Google\Protobuf\Internal\Message
     /**
      * 昵称
      *
-     * Generated from protobuf field <code>int64 nickname = 5;</code>
-     * @return int|string
+     * Generated from protobuf field <code>string nickname = 5;</code>
+     * @return string
      */
     public function getNickname()
     {
@@ -187,13 +187,13 @@ class FarmRankItem extends \Google\Protobuf\Internal\Message
     /**
      * 昵称
      *
-     * Generated from protobuf field <code>int64 nickname = 5;</code>
-     * @param int|string $var
+     * Generated from protobuf field <code>string nickname = 5;</code>
+     * @param string $var
      * @return $this
      */
     public function setNickname($var)
     {
-        GPBUtil::checkInt64($var);
+        GPBUtil::checkString($var, True);
         $this->nickname = $var;
 
         return $this;