Jelajahi Sumber

Merge remote-tracking branch 'origin/dev' into prod

AI Assistant 6 bulan lalu
induk
melakukan
448e32f7d2

+ 160 - 0
AiWork/202507/022000-新增URS注册农场用户WebHook.md

@@ -0,0 +1,160 @@
+# 新增URS注册农场用户WebHook
+
+**任务时间**: 2025年07月02日 20:00-20:30  
+**任务类型**: 功能开发  
+**模块**: ThirdParty/Urs  
+
+## 任务描述
+
+按照现有WebHook模式,新增一个URS注册农场用户的WebHook处理器,用于处理URS用户注册农场用户的请求。
+
+## 需求分析
+
+- 传入参数:user_id (URS的用户ID), user_key (URS的用户密钥)
+- 处理逻辑:使用 `UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate($userKey, $ursUserId)` 的公共逻辑
+- 返回结果:farm_user_id (农场的用户ID)
+
+## 实现方案
+
+### 1. 创建WebHook处理器
+
+**文件**: `ThirdParty/Urs/Webhook/UrsRegisterFarmUserWebhook.php`
+
+**主要功能**:
+- 继承自 `WebhookReceiver` 基类
+- 验证操作类型为 `register_farm_user`
+- 验证必需参数:`user_id` 和 `user_key`
+- 参数格式验证:用户ID必须为正整数,用户密钥不能为空
+- 调用 `UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate()` 处理用户注册
+- 返回农场用户ID和状态信息
+- 完整的错误处理和日志记录
+
+### 2. 注册WebHook处理器
+
+**文件**: `ThirdParty/Urs/UrsServiceProvider.php`
+
+**修改内容**:
+- 添加 `UrsRegisterFarmUserWebhook` 类的导入
+- 在 `registerWebhookHandlers()` 方法中注册新的处理器
+- 路由映射:`'register_farm_user' => UrsRegisterFarmUserWebhook::class`
+
+## 技术实现要点
+
+### 1. 参数验证
+```php
+protected function validateRegisterRequest(Request $request): void
+{
+    $requiredFields = ['user_id', 'user_key'];
+
+    foreach ($requiredFields as $field) {
+        if (!$request->has($field)) {
+            throw new \Exception("缺少必需字段: {$field}");
+        }
+    }
+
+    // 验证用户ID格式
+    $userId = $request->input('user_id');
+    if (!is_numeric($userId) || $userId <= 0) {
+        throw new \Exception('用户ID格式无效');
+    }
+
+    // 验证用户密钥
+    $userKey = $request->input('user_key');
+    if (empty($userKey)) {
+        throw new \Exception('用户密钥不能为空');
+    }
+}
+```
+
+### 2. 业务逻辑处理
+```php
+protected function processRegisterFarmUser($ursUserId, $userKey): array
+{
+    // 使用UrsUserMappingService的公共逻辑获取或创建农场用户ID
+    $farmUserId = UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate($userKey, $ursUserId);
+
+    if (!$farmUserId) {
+        throw new \Exception("无法获取或创建农场用户ID");
+    }
+
+    // 返回成功响应
+    return [
+        'farm_user_id' => $farmUserId,
+        'status' => 'success'
+    ];
+}
+```
+
+### 3. 日志记录
+- 处理开始时记录请求信息
+- 成功时记录农场用户ID
+- 异常时记录详细错误信息和堆栈跟踪
+
+## 测试验证
+
+### 1. WebHook路由
+- **URL**: `http://kku_laravel.local.gd/thirdParty/webhook/urs/register_farm_user`
+- **方法**: POST
+- **Content-Type**: application/json
+
+### 2. 请求参数
+```json
+{
+  "user_id": 12345,
+  "user_key": "test_user_key_12345"
+}
+```
+
+### 3. 签名验证
+- **Header**: `X-Signature`
+- **算法**: HMAC-SHA256
+- **密钥**: `Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y`
+- **签名字符串**: `user_id=12345&user_key=test_user_key_12345`
+
+### 4. 测试结果
+```json
+{
+  "success": true,
+  "data": {
+    "farm_user_id": 39147,
+    "status": "success"
+  },
+  "request_id": "webhook_dispatch_686524a32e66b8.94052417"
+}
+```
+
+**测试成功**:WebHook正常工作,成功创建了农场用户ID为39147的用户。
+
+## 文件变更
+
+### 新增文件
+1. `ThirdParty/Urs/Webhook/UrsRegisterFarmUserWebhook.php` - WebHook处理器
+2. `ThirdParty/Urs/Webhook/webhook.md` - 需求文档
+
+### 修改文件
+1. `ThirdParty/Urs/UrsServiceProvider.php` - 注册新的WebHook处理器
+
+## 提交信息
+
+```
+新增URS注册农场用户WebHook处理器
+
+- 创建UrsRegisterFarmUserWebhook类,处理URS用户注册农场用户请求
+- 实现参数验证:验证user_id和user_key参数格式
+- 集成UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate逻辑
+- 返回farm_user_id给调用方,包含完整的错误处理和日志记录
+- 在UrsServiceProvider中注册新的WebHook处理器
+- 测试验证功能正常,成功创建农场用户并返回正确响应
+```
+
+## 总结
+
+成功实现了URS注册农场用户的WebHook处理器,完全按照现有WebHook模式开发:
+
+1. **架构一致性**:继承自WebhookReceiver基类,遵循现有的WebHook架构
+2. **参数验证**:完整的参数验证机制,确保数据安全性
+3. **业务逻辑**:复用现有的UrsUserMappingService逻辑,避免重复开发
+4. **错误处理**:完善的异常处理和日志记录机制
+5. **测试验证**:通过实际测试验证功能正确性
+
+该WebHook处理器已成功集成到系统中,可以正常处理URS用户注册农场用户的请求。

+ 132 - 0
AiWork/202507/022207-修复房屋排行榜第二页数据问题.md

@@ -0,0 +1,132 @@
+# 修复房屋排行榜第二页数据问题
+
+**时间**: 2025年07月02日 22:07
+**任务**: 修复 House-Rank 排行榜第二页数据显示问题
+
+## 问题描述
+
+用户反馈房屋排行榜第二页数据有问题:
+- 响应中有分页信息(总数15,当前页2,每页10条)
+- 但是列表数据为空,没有显示第二页的数据
+
+```json
+{
+  "runUnid": "6865391969844",
+  "runMs": "21", 
+  "code": "OK",
+  "callpath": "House-Rank",
+  "lastData": {},
+  "houseRank": {
+    "page": {
+      "currentPage": "2",
+      "perPage": "10", 
+      "lastPage": "2",
+      "total": "15"
+    },
+    "userRank": "13",
+    "reason": "1"
+  }
+}
+```
+
+## 问题分析
+
+通过代码分析发现了多个问题:
+
+### 1. 类型错误
+在 `app/Module/Farm/Logics/HouseLogic.php` 的 `getHouseRankListCache` 方法中:
+- 方法声明返回类型为 `array`
+- 但在第329-335行,当请求数据超出前100名时,返回的是 `HouseRankDto` 对象
+- 导致后续 `array_slice` 操作失败
+
+### 2. 设计问题
+- `getHouseRankListCache` 方法不应该处理分页逻辑
+- 分页应该在外部的 `getHouseRankList` 方法中处理
+- 缓存方法应该只负责获取和缓存数据
+
+### 3. 用户排名计算错误
+- 用户排名计算中错误地加上了当前页偏移量
+- 应该是在整个排行榜中的绝对位置
+
+### 4. 总数统计不准确
+- `getTotalHouseRankCount()` 统计的是 `FarmUser::count()`
+- 但实际排行榜查询需要JOIN `user_infos` 表
+- 导致总数与实际数据不匹配
+
+## 修复方案
+
+### 1. 重构缓存方法
+```php
+// 修改前
+protected function getHouseRankListCache(int $userId, int $page = 1, int $pageSize = 20): array
+
+// 修改后  
+protected function getHouseRankListCache(): array
+```
+
+### 2. 移除分页逻辑
+- 将分页检查逻辑移到 `getHouseRankList` 方法中
+- 缓存方法只负责获取完整的排行榜数据
+
+### 3. 修复用户排名计算
+```php
+// 修改前
+$rank = $offset + $index + 1;
+
+// 修改后
+$userRank = $index + 1; // 用户在整个排行榜中的排名
+```
+
+### 4. 使用缓存数据统计总数
+```php
+// 修改前
+'total' => min($maxRankLimit, $this->getTotalHouseRankCount())
+
+// 修改后
+'total' => count($cachedRankList) // 直接使用缓存数据的行数
+```
+
+## 测试验证
+
+创建测试命令验证修复效果:
+
+```bash
+docker exec kku_laravel php artisan test:house-rank
+```
+
+测试结果:
+- **缓存数据总数**: 7条
+- **第一页 (page=1, pageSize=5)**: 显示5条数据,排名1-5
+- **第二页 (page=2, pageSize=5)**: 显示2条数据,排名6-7  
+- **分页信息**: 总数7,每页5条,分页计算正确
+
+## 修改文件
+
+- `app/Module/Farm/Logics/HouseLogic.php`
+  - 重构 `getHouseRankListCache` 方法
+  - 修复 `getHouseRankList` 方法中的分页逻辑
+  - 修复用户排名计算
+  - 删除不再使用的 `getTotalHouseRankCount` 方法
+
+## 提交信息
+
+```
+修复房屋排行榜第二页数据问题
+
+- 修复getHouseRankListCache方法返回类型错误
+- 移除分页参数,缓存方法只负责获取数据  
+- 修复用户排名计算错误
+- 使用缓存数据行数作为总数,确保分页信息准确
+- 删除不再使用的getTotalHouseRankCount方法
+```
+
+## 总结
+
+问题已完全修复:
+1. ✅ 修复了类型错误和设计问题
+2. ✅ 分页逻辑正确,第二页能正常显示数据
+3. ✅ 用户排名计算准确
+4. ✅ 分页信息与实际数据一致
+5. ✅ 代码结构更清晰,职责分离明确
+
+现在房屋排行榜的分页功能完全正常,第二页数据能够正确显示。

+ 31 - 52
AiWork/now.md

@@ -1,67 +1,46 @@
-# 模块梳理和README.md维护任务
+# 新增URS注册农场用户WebHook
 
 ## 任务概述
-以代码为准,梳理模块,维护 app/Module/README.md
+按照现有WebHook模式,新增一个URS注册农场用户的WebHook处理器,用于处理URS用户注册农场用户的请求。
 
-## 发现的问题
-1. **模块数量不匹配**:文档显示35个,实际37个
-2. **新增模块未记录**:
-   - Cleanup - 数据清理模块(75%完成)
-   - Transfer - 新版划转系统(已完成)
-   - UrsPromotion - URS推广模块(开发中)
-3. **废弃模块**:TransferOld(已被Transfer替代)
-4. **模块名称错误**:Promotionurs应为UrsPromotion
+## 任务要求
+- 传入参数:user_id (URS的用户ID), user_key (URS的用户密钥)
+- 处理逻辑:使用 UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate($userKey, $ursUserId) 的公共逻辑
+- 返回结果:farm_user_id (农场的用户ID)
 
 ## 工作计划
-- [x] 分析现有文档和实际模块
-- [x] 收集所有模块详细信息
-- [x] 重新分类模块
-- [x] 更新模块状态
-- [x] 修正依赖关系图
-- [x] 更新统计数据
-- [x] 更新README.md文件
+- [x] 创建URS注册农场用户WebHook处理器
+- [x] 实现参数验证和业务逻辑
+- [x] 集成UrsUserMappingService逻辑
+- [x] 在UrsServiceProvider中注册WebHook
+- [x] 测试WebHook功能
+- [x] 提交代码到git仓库
+- [x] 创建工作记录文档
 
 ## 完成的工作
-1. **模块数量更新**:从35个更新为37个
-2. **新增模块记录**:
-   - Transfer模块(资金划转系统)- 已完成
-   - Cleanup模块(数据清理工具)- 基础功能75%
-   - UrsPromotion模块(URS推广系统)- 开发中
-3. **废弃模块标记**:TransferOld模块标记为已废弃
-4. **模块分类调整**:重新分类为7大类
-5. **依赖关系更新**:修正模块依赖关系图
-6. **统计数据更新**:更新状态分布图表
+1. **创建WebHook处理器**:UrsRegisterFarmUserWebhook.php
+   - 继承WebhookReceiver基类
+   - 实现参数验证:user_id和user_key
+   - 集成UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate逻辑
+   - 完整的错误处理和日志记录
 
-## 当前进度
-✅ 模块梳理任务已完成
-🚧 SocialFarm模块创建中
+2. **注册WebHook**:在UrsServiceProvider中注册
+   - 路由映射:register_farm_user => UrsRegisterFarmUserWebhook::class
+   - 添加必要的导入声明
 
-## 新任务:SocialFarm模块创建
-### 已完成工作
-- [x] 创建完整的模块目录结构
-- [x] 编写详细的README.md文档
-- [x] 设计数据库表结构和SQL文件
-- [x] 创建核心枚举类(STEAL_STATUS, SOCIAL_ACTION, VISIT_TYPE, HELP_TYPE)
-- [x] 实现主要服务类(SocialFarmService)
-- [x] 创建基础模型类(SocialFarmStealLog, SocialFarmSetting)
-- [x] 编写API接口文档
-- [x] 配置服务提供者和配置文件
+3. **测试验证**:
+   - 测试URL:/thirdParty/webhook/urs/register_farm_user
+   - 测试参数:{"user_id": 12345, "user_key": "test_user_key_12345"}
+   - 测试结果:成功创建农场用户ID 39147
 
-### 待完成工作
-- [ ] 创建逻辑层类(StealLogic, VisitLogic, HelpLogic, PermissionLogic)
-- [ ] 实现事件和监听器
-- [ ] 创建验证类和DTO类
-- [ ] 实现Handler层(AppGame模块集成)
-- [ ] 创建后台管理界面
-- [ ] 编写测试用例
+## 当前进度
+✅ **WebHook开发任务已完成**
 
 ## Git提交记录
-- 模块梳理提交:✅ 成功 (commit: 95aea691)
-- SocialFarm模块:准备提交
+- WebHook实现提交:✅ 成功 (commit: 2c3f4c9e)
 
 ## 时间记录
-- 模块梳理开始:2025年07月02日 13:23:44 CST
-- 模块梳理完成:2025年07月02日 13:50:00 CST
-- SocialFarm开始:2025年07月02日 14:00:00 CST
-- 当前时间:2025年07月02日 14:30:00 CST
+- 任务开始:2025年07月02日 20:00:00 CST
+- 任务完成:2025年07月02日 20:30:00 CST
+- 总耗时:30分钟
 

+ 6 - 4
ThirdParty/Urs/UrsServiceProvider.php

@@ -8,6 +8,7 @@ use ThirdParty\Urs\Services\UrsService;
 use ThirdParty\Urs\Webhook\UrsCheckWebhook;
 use ThirdParty\Urs\Webhook\UrsDepositWebhook;
 use ThirdParty\Urs\Webhook\UrsRegisterWebhook;
+use ThirdParty\Urs\Webhook\UrsRegisterFarmUserWebhook;
 use ThirdParty\Urs\Webhook\UrsWithdrawWebhook;
 
 /**
@@ -51,10 +52,11 @@ class UrsServiceProvider extends ServiceProvider
         // 一对一映射:每个路由对应一个专门的处理器
         // 每个处理器只处理一种特定的Webhook请求
         WebhookDispatchService::registerPackageHandlers('urs', [
-            'register' => UrsRegisterWebhook::class,    // 注册通知 - 专门处理用户注册
-            'deposit' => UrsDepositWebhook::class,      // 充值通知 - 专门处理充值操作
-            'withdraw' => UrsWithdrawWebhook::class,    // 提取通知 - 专门处理提取操作
-            'check' => UrsCheckWebhook::class,          // 余额检查 - 专门处理余额检查
+            'register' => UrsRegisterWebhook::class,                // 注册通知 - 专门处理用户注册
+            'register_farm_user' => UrsRegisterFarmUserWebhook::class, // 注册农场用户 - 专门处理URS用户注册农场用户
+            'deposit' => UrsDepositWebhook::class,                  // 充值通知 - 专门处理充值操作
+            'withdraw' => UrsWithdrawWebhook::class,                // 提取通知 - 专门处理提取操作
+            'check' => UrsCheckWebhook::class,                      // 余额检查 - 专门处理余额检查
         ]);
     }
 

+ 137 - 0
ThirdParty/Urs/Webhook/UrsRegisterFarmUserWebhook.php

@@ -0,0 +1,137 @@
+<?php
+
+namespace ThirdParty\Urs\Webhook;
+
+use App\Module\ThirdParty\Models\ThirdPartyService as ServiceModel;
+use App\Module\UrsPromotion\Services\UrsUserMappingService;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * URS注册农场用户Webhook处理器
+ *
+ * 专门处理URS用户注册农场用户的Webhook通知
+ */
+class UrsRegisterFarmUserWebhook extends WebhookReceiver
+{
+    /**
+     * 构造函数
+     *
+     * @param string $serviceCode 服务代码
+     * @param Request $request 请求对象
+     * @param ServiceModel $service 服务配置对象
+     */
+    public function __construct(string $serviceCode, Request $request, ServiceModel $service)
+    {
+        parent::__construct($serviceCode, $request, $service);
+    }
+
+    /**
+     * 处理注册农场用户通知
+     *
+     * @param string $action 操作类型(固定为register_farm_user)
+     * @param Request $request 请求对象
+     * @return array
+     * @throws \Exception
+     */
+    protected function handler(string $action, Request $request): array
+    {
+        // 验证操作类型
+        if ($action !== 'register_farm_user') {
+            throw new \Exception("此处理器只能处理register_farm_user操作,当前操作: {$action}");
+        }
+
+        // 验证必需字段
+        $this->validateRegisterRequest($request);
+
+        // 处理注册农场用户通知
+        return $this->processRegisterFarmUser(
+            $request->get('user_id'), 
+            $request->get('user_key')
+        );
+    }
+
+    /**
+     * 验证注册请求
+     *
+     * @param Request $request 请求对象
+     * @throws \Exception
+     */
+    protected function validateRegisterRequest(Request $request): void
+    {
+        $requiredFields = ['user_id', 'user_key'];
+
+        foreach ($requiredFields as $field) {
+            if (!$request->has($field)) {
+                throw new \Exception("缺少必需字段: {$field}");
+            }
+        }
+
+        // 验证用户ID
+        $userId = $request->input('user_id');
+        if (!is_numeric($userId) || $userId <= 0) {
+            throw new \Exception('用户ID格式无效');
+        }
+
+        // 验证用户密钥
+        $userKey = $request->input('user_key');
+        if (empty($userKey)) {
+            throw new \Exception('用户密钥不能为空');
+        }
+    }
+
+    /**
+     * 处理注册农场用户
+     *
+     * @param int $ursUserId URS用户ID
+     * @param string $userKey 用户密钥
+     * @return array
+     */
+    protected function processRegisterFarmUser($ursUserId, $userKey): array
+    {
+        // 记录处理日志
+        Log::info("URS注册农场用户处理开始", [
+            'urs_user_id' => $ursUserId,
+            'user_key_length' => strlen($userKey),
+            'request_id' => $this->getRequestId(),
+        ]);
+
+        try {
+            // 使用UrsUserMappingService的公共逻辑获取或创建农场用户ID
+            $farmUserId = UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate($userKey, $ursUserId);
+
+            if (!$farmUserId) {
+                Log::error("URS注册农场用户失败:无法获取或创建农场用户ID", [
+                    'urs_user_id' => $ursUserId,
+                    'user_key_length' => strlen($userKey),
+                ]);
+                throw new \Exception("无法获取或创建农场用户ID");
+            }
+
+            // 记录成功日志
+            Log::info("URS注册农场用户成功", [
+                'urs_user_id' => $ursUserId,
+                'farm_user_id' => $farmUserId,
+                'user_key_length' => strlen($userKey),
+            ]);
+
+            // 返回成功响应
+            return [
+                'farm_user_id' => $farmUserId,
+                'status' => 'success'
+            ];
+
+        } catch (\Exception $e) {
+            // 记录异常日志
+            Log::error("URS注册农场用户处理异常", [
+                'urs_user_id' => $ursUserId,
+                'user_key_length' => strlen($userKey),
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString(),
+            ]);
+
+            // 重新抛出异常,让上层处理
+            throw $e;
+        }
+    }
+}

+ 7 - 0
ThirdParty/Urs/Webhook/webhook.md

@@ -0,0 +1,7 @@
+# webhook
+
+## 注册农场用户
+增加一个新的 WebHook ,模式不变,按照其他wenhook的模式再开发一个
+传入参数 user_id (Urs的用户ID), user_key (Urs的用户密钥)
+给这个用户注册农场用户,逻辑使用  UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate($userKey, $ursUserId) 的公共逻辑,不要重写
+返回 farm_user_id (农场的用户ID)

+ 73 - 0
app/Console/Commands/TestWealthRank.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Module\Farm\Services\HouseService;
+use Illuminate\Console\Command;
+
+class TestWealthRank extends Command
+{
+    protected $signature = 'test:wealth-rank {userId=10001}';
+    protected $description = '测试财富排行榜功能';
+
+    public function handle()
+    {
+        $userId = (int) $this->argument('userId');
+        
+        $this->info("测试财富排行榜功能");
+        $this->info("==================");
+        $this->newLine();
+
+        try {
+            // 先检查缓存数据
+            $this->info("检查缓存数据:");
+            $houseLogic = new \App\Module\Farm\Logics\HouseLogic();
+            $reflection = new \ReflectionClass($houseLogic);
+            $method = $reflection->getMethod('getWealthRankListCache');
+            $method->setAccessible(true);
+            $cachedData = $method->invoke($houseLogic);
+            $this->info("- 缓存数据总数: " . count($cachedData));
+            $this->newLine();
+
+            // 测试第一页
+            $this->info("测试第一页 (page=1, pageSize=5):");
+            $page1Data = HouseService::getWealthRankList($userId, 1, 5);
+            $this->info("第一页数据:");
+            $this->info("- 列表数量: " . count($page1Data->list));
+            $this->info("- 用户排名: " . $page1Data->userRank);
+            $this->info("- 分页信息: " . json_encode($page1Data->page, JSON_UNESCAPED_UNICODE));
+            
+            // 显示第一页的前3条数据
+            if (!empty($page1Data->list)) {
+                $this->info("第一页前3条数据:");
+                foreach (array_slice($page1Data->list, 0, 3) as $index => $item) {
+                    $this->info("  " . ($index + 1) . ". 排名: {$item->rank}, 用户ID: {$item->userId}, 昵称: {$item->nickname}, 财富: {$item->wealth}");
+                }
+            }
+            $this->newLine();
+
+            // 测试第二页
+            $this->info("测试第二页 (page=2, pageSize=5):");
+            $page2Data = HouseService::getWealthRankList($userId, 2, 5);
+            $this->info("第二页数据:");
+            $this->info("- 列表数量: " . count($page2Data->list));
+            $this->info("- 用户排名: " . $page2Data->userRank);
+            $this->info("- 分页信息: " . json_encode($page2Data->page, JSON_UNESCAPED_UNICODE));
+            $this->newLine();
+
+            // 如果第二页有数据,显示前几条
+            if (!empty($page2Data->list)) {
+                $this->info("第二页前3条数据:");
+                foreach (array_slice($page2Data->list, 0, 3) as $index => $item) {
+                    $this->info("  " . ($index + 1) . ". 排名: {$item->rank}, 用户ID: {$item->userId}, 昵称: {$item->nickname}, 财富: {$item->wealth}");
+                }
+            } else {
+                $this->warn("第二页没有数据");
+            }
+
+        } catch (\Exception $e) {
+            $this->error("错误: " . $e->getMessage());
+            $this->error("堆栈: " . $e->getTraceAsString());
+        }
+    }
+}

+ 2 - 2
app/Module/Farm/AdminControllers/Metrics/FarmHouseRanking.php

@@ -8,7 +8,7 @@ use App\Module\Farm\Models\FarmDailyStats;
 
 /**
  * 农场房屋等级排名卡片
- * 
+ *
  * 参考UCore\DcatAdmin\Metrics\Examples\Ranking实现
  * 显示房屋等级的排名统计
  */
@@ -23,7 +23,7 @@ class FarmHouseRanking extends Ranking
     {
         parent::init();
 
-        $this->title('房屋等级排名');
+        $this->title('房屋等级排名(昨天)');
         $this->dropdown([
             'count' => '按数量排序',
             'level' => '按等级排序',

+ 10 - 10
app/Module/Farm/AdminControllers/Metrics/FarmLandLevelStatsCard.php

@@ -15,7 +15,7 @@ class FarmLandLevelStatsCard extends NumberS
     /**
      * 卡片标题
      */
-    protected $title = '土地等级数量统计';
+    protected $title = '土地等级数量统计(昨天)';
 
     /**
      * 初始化卡片内容
@@ -23,7 +23,7 @@ class FarmLandLevelStatsCard extends NumberS
     protected function init()
     {
         parent::init();
-        
+
         // 土地统计不需要时间范围选择,移除下拉选项
         $this->dropdown([]);
     }
@@ -37,13 +37,13 @@ class FarmLandLevelStatsCard extends NumberS
     public function handle(Request $request)
     {
         $stats = $this->getLandLevelStats();
-        
+
         // 转换为NumberS需要的数据格式(键值对数组)
         $dataList = [];
         foreach ($stats as $stat) {
             $dataList[$stat['name']] = $stat['count'];
         }
-        
+
         $this->withContent($dataList);
     }
 
@@ -55,14 +55,14 @@ class FarmLandLevelStatsCard extends NumberS
     private function getLandLevelStats(): array
     {
         $latestStats = FarmDailyStats::orderBy('stats_date', 'desc')->first();
-        
+
         if (!$latestStats) {
             return [];
         }
 
         $landTypeNames = [
             1 => '普通土地',
-            2 => '红土地', 
+            2 => '红土地',
             3 => '黑土地',
             4 => '金色特殊土地',
             5 => '蓝色特殊土地',
@@ -71,13 +71,13 @@ class FarmLandLevelStatsCard extends NumberS
 
         $stats = [];
         $totalLands = 0;
-        
+
         // 获取各个土地类型的数量
         for ($type = 1; $type <= 6; $type++) {
             $field = "land_type_{$type}";
             $count = $latestStats->$field ?? 0;
             $totalLands += $count;
-            
+
             // 只显示有数量的土地类型
             if ($count > 0) {
                 $stats[] = [
@@ -86,7 +86,7 @@ class FarmLandLevelStatsCard extends NumberS
                 ];
             }
         }
-        
+
         // 添加总计
         if ($totalLands > 0) {
             $stats[] = [
@@ -94,7 +94,7 @@ class FarmLandLevelStatsCard extends NumberS
                 'count' => $totalLands
             ];
         }
-        
+
         return $stats;
     }
 }

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

@@ -275,7 +275,18 @@ class HouseLogic
         // 限制只显示前100名
         $maxRankLimit   = 100;
         $offset         = ($page - 1) * $pageSize;
-        $cachedRankList = $this->getHouseRankListCache($userId, $page, $pageSize);
+        // 如果请求的数据超出前100名,返回空结果
+        if ($offset >= $maxRankLimit) {
+            // 先获取缓存数据来计算实际总数
+            $cachedRankList = $this->getHouseRankListCache();
+            return new HouseRankDto([], 0, 1, [
+                'page'     => $page,
+                'per_page' => $pageSize,
+                'total'    => count($cachedRankList)
+            ]);
+        }
+
+        $cachedRankList = $this->getHouseRankListCache();
         // 调整查询限制,确保不超过前100名
         $actualLimit = min($pageSize, $maxRankLimit - $offset);
         // 从缓存数据中获取当前页的数据
@@ -289,12 +300,11 @@ class HouseLogic
         }
 
         // 查询用户自己的排名
-
         $userRank = 0;
         foreach ($cachedRankList as $index => $item) {
             if ($item->user_id == $userId) {
-                $rank     = $offset + $index + 1;
-                $userRank = $rank;
+                $userRank = $index + 1; // 用户在整个排行榜中的排名
+                break; // 找到后立即退出循环
             }
         }
 
@@ -302,7 +312,7 @@ class HouseLogic
         $pageInfo = [
             'page'     => $page,
             'per_page' => $pageSize,
-            'total'    => min($maxRankLimit, $this->getTotalHouseRankCount())
+            'total'    => count($cachedRankList) // 直接使用缓存数据的行数
         ];
 
         return new HouseRankDto($rankItems, $userRank, 1, $pageInfo);
@@ -311,28 +321,14 @@ class HouseLogic
     }
 
     /**
-     * 排行榜缓存
+     * 获取房屋排行榜缓存数据
      *
-     * @param int $userId
-     * @param int $page
-     * @param int $pageSize
-     * @return HouseRankDto
+     * @return array
      */
-    protected function getHouseRankListCache(int $userId, int $page = 1, int $pageSize = 20): array
+    protected function getHouseRankListCache(): array
     {
-
         // 限制只显示前100名
         $maxRankLimit = 100;
-        $offset       = ($page - 1) * $pageSize;
-
-        // 如果请求的数据超出前100名,返回空结果
-        if ($offset >= $maxRankLimit) {
-            return new HouseRankDto([], 0, 1, [
-                'page'     => $page,
-                'per_page' => $pageSize,
-                'total'    => min($maxRankLimit, $this->getTotalHouseRankCount())
-            ]);
-        }
 
 
         // 尝试从缓存获取排行榜数据
@@ -368,26 +364,7 @@ class HouseLogic
     }
 
 
-    /**
-     * 获取房屋排行榜总数(限制前100名)
-     *
-     * @return int
-     */
-    private function getTotalHouseRankCount(): int
-    {
-        try {
-            // 获取实际用户总数,但最多返回100
-            $actualCount = FarmUser::count();
-
-            return min($actualCount, 100);
-        } catch (\Exception $e) {
-            Log::error('获取房屋排行榜总数失败', [
-                'error' => $e->getMessage()
-            ]);
 
-            return 0;
-        }
-    }
 
     /**
      * 获取财富排行榜数据
@@ -406,10 +383,12 @@ class HouseLogic
 
             // 如果请求的数据超出前100名,返回空结果
             if ($offset >= $maxRankLimit) {
+                // 先获取缓存数据来计算实际总数
+                $cachedRankList = $this->getWealthRankListCache();
                 return new WealthRankDto([], 0, 1, [
                     'page'     => $page,
                     'per_page' => $pageSize,
-                    'total'    => min($maxRankLimit, $this->getTotalWealthRankCount())
+                    'total'    => count($cachedRankList)
                 ]);
             }
             // 从缓存获取前100名数据
@@ -432,15 +411,15 @@ class HouseLogic
             $userRank = 0;
             foreach ($cachedRankList as $index => $item) {
                 if ($item->user_id == $userId) {
-                    $rank     = $offset + $index + 1;
-                    $userRank = $rank;
+                    $userRank = $index + 1; // 用户在整个排行榜中的排名
+                    break; // 找到后立即退出循环
                 }
             }
             // 构建分页信息
             $pageInfo = [
                 'page'     => $page,
                 'per_page' => $pageSize,
-                'total'    => min($maxRankLimit, $this->getTotalWealthRankCount())
+                'total'    => count($cachedRankList) // 直接使用缓存数据的行数
             ];
 //            dd($rankItems);
 
@@ -500,28 +479,7 @@ class HouseLogic
     }
 
 
-    /**
-     * 获取财富排行榜总数(限制前100名)
-     *
-     * @return int
-     */
-    private function getTotalWealthRankCount(): int
-    {
-        try {
-            // 获取实际用户总数,但最多返回100
-            $actualCount = DB::table('fund')
-                ->where('fund_id', 2) // 钻石资金类型
-                ->count();
-
-            return min($actualCount, 100);
-        } catch (\Exception $e) {
-            Log::error('获取财富排行榜总数失败', [
-                'error' => $e->getMessage()
-            ]);
 
-            return 0;
-        }
-    }
 
     /**
      * 清除房屋配置缓存