|
|
@@ -446,31 +446,31 @@ class HouseLogic
|
|
|
public function getWealthRankList(int $userId, int $page = 1, int $pageSize = 20): WealthRankDto
|
|
|
{
|
|
|
try {
|
|
|
- // 计算偏移量
|
|
|
+ // 限制只显示前100名
|
|
|
+ $maxRankLimit = 100;
|
|
|
$offset = ($page - 1) * $pageSize;
|
|
|
|
|
|
- // 查询财富排行榜数据,按钻石余额降序排列,同余额按房屋等级降序排列
|
|
|
- $rankList = DB::table('fund as f')
|
|
|
- ->join('users as u', 'f.user_id', '=', 'u.id')
|
|
|
- ->leftJoin('farm_users as fu', 'f.user_id', '=', 'fu.user_id')
|
|
|
- ->select([
|
|
|
- 'f.user_id',
|
|
|
- 'f.balance',
|
|
|
- 'u.username',
|
|
|
- 'fu.house_level'
|
|
|
- ])
|
|
|
- ->where('f.fund_id', 2) // 钻石资金类型
|
|
|
- ->orderBy('f.balance', 'desc')
|
|
|
- ->orderBy('fu.house_level', 'desc') // 同钻石余额按房屋等级排序
|
|
|
- ->offset($offset)
|
|
|
- ->limit($pageSize)
|
|
|
- ->get()
|
|
|
- ->toArray();
|
|
|
+ // 如果请求的数据超出前100名,返回空结果
|
|
|
+ if ($offset >= $maxRankLimit) {
|
|
|
+ return new WealthRankDto([], 0, 1, [
|
|
|
+ 'page' => $page,
|
|
|
+ 'per_page' => $pageSize,
|
|
|
+ 'total' => min($maxRankLimit, $this->getTotalWealthRankCount())
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从缓存获取前100名数据
|
|
|
+ $cachedRankList = $this->getWealthRankListCache();
|
|
|
+
|
|
|
+ // 调整查询限制,确保不超过前100名
|
|
|
+ $actualLimit = min($pageSize, $maxRankLimit - $offset);
|
|
|
+ // 从缓存数据中获取当前页的数据
|
|
|
+ $rankList = array_slice($cachedRankList, $offset, $actualLimit);
|
|
|
|
|
|
// 转换为DTO对象
|
|
|
$rankItems = [];
|
|
|
foreach ($rankList as $index => $item) {
|
|
|
- $rank = $offset + $index + 1;
|
|
|
+ $rank = $offset + $index + 1;
|
|
|
$rankItems[] = WealthRankItemDto::fromArray((array)$item, $rank);
|
|
|
}
|
|
|
|
|
|
@@ -479,48 +479,96 @@ class HouseLogic
|
|
|
|
|
|
// 构建分页信息
|
|
|
$pageInfo = [
|
|
|
- 'page' => $page,
|
|
|
+ 'page' => $page,
|
|
|
'per_page' => $pageSize,
|
|
|
- 'total' => $this->getTotalWealthRankCount()
|
|
|
+ 'total' => min($maxRankLimit, $this->getTotalWealthRankCount())
|
|
|
];
|
|
|
|
|
|
return new WealthRankDto($rankItems, $userRank, 1, $pageInfo);
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('获取财富排行榜失败', [
|
|
|
- 'user_id' => $userId,
|
|
|
- 'page' => $page,
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'page' => $page,
|
|
|
'page_size' => $pageSize,
|
|
|
- 'error' => $e->getMessage(),
|
|
|
- 'trace' => $e->getTraceAsString()
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ 'trace' => $e->getTraceAsString()
|
|
|
]);
|
|
|
|
|
|
return new WealthRankDto();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取财富排行榜缓存数据
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getWealthRankListCache(): array
|
|
|
+ {
|
|
|
+ // 限制只显示前100名
|
|
|
+ $maxRankLimit = 100;
|
|
|
+
|
|
|
+ // 尝试从缓存获取排行榜数据
|
|
|
+ $cacheKey = $this->cachePrefix . 'wealth_rank:top100';
|
|
|
+ $cachedRankList = Cache::get($cacheKey);
|
|
|
+
|
|
|
+ if (!$cachedRankList) {
|
|
|
+ // 查询前100名财富排行榜数据,按钻石余额降序排列,同余额按房屋等级降序排列
|
|
|
+ $cachedRankList = DB::table('fund as f')
|
|
|
+ ->join('users as u', 'f.user_id', '=', 'u.id')
|
|
|
+ ->leftJoin('farm_users as fu', 'f.user_id', '=', 'fu.user_id')
|
|
|
+ ->select([
|
|
|
+ 'f.user_id',
|
|
|
+ 'f.balance',
|
|
|
+ 'u.username',
|
|
|
+ 'fu.house_level'
|
|
|
+ ])
|
|
|
+ ->where('f.fund_id', 2) // 钻石资金类型
|
|
|
+ ->orderBy('f.balance', 'desc')
|
|
|
+ ->orderBy('fu.house_level', 'desc') // 同钻石余额按房屋等级排序
|
|
|
+ ->limit($maxRankLimit)
|
|
|
+ ->get()
|
|
|
+ ->toArray();
|
|
|
+
|
|
|
+ // 缓存10分钟
|
|
|
+ Cache::put($cacheKey, $cachedRankList, 600);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $cachedRankList;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 获取用户的财富排名
|
|
|
*
|
|
|
* @param int $userId 用户ID
|
|
|
- * @return int 排名,0表示未上榜
|
|
|
+ * @return int 排名,0表示未上榜或超出前100名
|
|
|
*/
|
|
|
private function getUserWealthRank(int $userId): int
|
|
|
{
|
|
|
try {
|
|
|
+ // 尝试从缓存获取用户排名
|
|
|
+ $cacheKey = $this->cachePrefix . 'user_wealth_rank:' . $userId;
|
|
|
+ $cachedRank = Cache::get($cacheKey);
|
|
|
+
|
|
|
+ if ($cachedRank !== null) {
|
|
|
+ return $cachedRank;
|
|
|
+ }
|
|
|
+
|
|
|
// 获取用户的钻石余额和房屋等级
|
|
|
$userFund = DB::table('fund as f')
|
|
|
->leftJoin('farm_users as fu', 'f.user_id', '=', 'fu.user_id')
|
|
|
- ->select([ 'f.balance', 'fu.house_level' ])
|
|
|
+ ->select(['f.balance', 'fu.house_level'])
|
|
|
->where('f.user_id', $userId)
|
|
|
->where('f.fund_id', 2) // 钻石资金类型
|
|
|
->first();
|
|
|
|
|
|
if (!$userFund) {
|
|
|
+ Cache::put($cacheKey, 0, 600); // 缓存10分钟
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- $userBalance = $userFund->balance ?? 0;
|
|
|
+ $userBalance = $userFund->balance ?? 0;
|
|
|
$userHouseLevel = $userFund->house_level ?? 0;
|
|
|
|
|
|
// 计算排名:比用户余额高的用户数量 + 同余额但房屋等级更高的用户数量 + 1
|
|
|
@@ -536,12 +584,22 @@ 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('获取用户财富排名失败', [
|
|
|
'user_id' => $userId,
|
|
|
- 'error' => $e->getMessage()
|
|
|
+ 'error' => $e->getMessage()
|
|
|
]);
|
|
|
|
|
|
return 0;
|
|
|
@@ -549,16 +607,19 @@ class HouseLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取财富排行榜总数
|
|
|
+ * 获取财富排行榜总数(限制前100名)
|
|
|
*
|
|
|
* @return int
|
|
|
*/
|
|
|
private function getTotalWealthRankCount(): int
|
|
|
{
|
|
|
try {
|
|
|
- return DB::table('fund')
|
|
|
+ // 获取实际用户总数,但最多返回100
|
|
|
+ $actualCount = DB::table('fund')
|
|
|
->where('fund_id', 2) // 钻石资金类型
|
|
|
->count();
|
|
|
+
|
|
|
+ return min($actualCount, 100);
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('获取财富排行榜总数失败', [
|
|
|
'error' => $e->getMessage()
|