Explorar o código

refactor(game): 优化用户日志收集命令及统计功能

- 移除了重置进度功能,简化了命令选项
- 重构了统计信息显示逻辑,支持动态显示所有收集器信息
- 添加了收集器图标和描述,提高了信息的可读性
-优化了按类型统计的逻辑,支持动态获取所有收集器类型- 删除了未使用的 SQL 升级脚本
- 更新了相关文档,移除了重置进度相关的说明
notfff hai 7 meses
pai
achega
92da473f16

+ 68 - 49
app/Module/Game/Commands/CollectUserLogsCommand.php

@@ -17,7 +17,7 @@ class CollectUserLogsCommand extends Command
      *
      * @var string
      */
-    protected $signature = 'game:collect-user-logs {--reset : 重置处理进度,从头开始收集} {--info : 显示收集器信息} {--statistics : 显示收集统计信息} {--detail : 显示详细的处理过程} {--limit=1000 : 单次处理最大记录数}';
+    protected $signature = 'game:collect-user-logs {--info : 显示收集器信息} {--statistics : 显示收集统计信息} {--detail : 显示详细的处理过程} {--limit=1000 : 单次处理最大记录数}';
 
     /**
      * 命令描述
@@ -27,11 +27,12 @@ class CollectUserLogsCommand extends Command
     protected $description = '收集用户日志,将各模块的原始日志转换为用户友好的日志消息
 
 选项说明:
-  --reset       重置处理进度,从头开始收集
   --info        显示收集器信息
   --statistics  显示收集统计信息
   --detail      显示详细的处理过程
-  --limit       单次处理最大记录数(默认1000)';
+  --limit       单次处理最大记录数(默认1000)
+
+注意:进度追踪基于user_logs表中的已处理记录,系统会自动从上次处理位置继续收集';
 
     /**
      * 执行命令
@@ -41,12 +42,18 @@ class CollectUserLogsCommand extends Command
 
         // 显示统计信息
         if ($this->option('statistics')) {
+            $manager = new UserLogCollectorManager();
+            $collectorsInfo = $manager->getCollectorsInfo();
+
             $this->info("📊 收集器统计信息:");
             $this->line("");
-            $this->line("收集器数量: 3");
-            $this->line("- fund: 资金日志收集器");
-            $this->line("- item: 物品日志收集器");
-            $this->line("- farm: 农场日志收集器");
+            $this->line("收集器数量: " . count($collectorsInfo));
+
+            // 动态显示所有收集器
+            foreach ($collectorsInfo as $name => $info) {
+                $icon = $this->getCollectorIcon($info['source_type']);
+                $this->line("- {$name}: {$icon} {$this->getCollectorDescription($info['source_type'])}");
+            }
             $this->line("");
 
             // 显示用户日志表统计
@@ -62,17 +69,15 @@ class CollectUserLogsCommand extends Command
                     $this->line("  🕐 最新日志时间: " . $latestLog->created_at);
                     $this->line("  🕐 最旧日志时间: " . $oldestLog->created_at);
 
-                    // 按类型统计
-                    $fundCount = \App\Module\Game\Models\UserLog::where('source_type', 'fund')->count();
-                    $itemCount = \App\Module\Game\Models\UserLog::where('source_type', 'item')->count();
-                    $farmCount = \App\Module\Game\Models\UserLog::where('source_type', 'farm')->count();
-                    $pointCount = \App\Module\Game\Models\UserLog::where('source_type', 'point')->count();
-
+                    // 按类型统计 - 动态获取所有收集器类型
                     $this->line("  📊 按类型统计:");
-                    $this->line("    💰 资金日志: {$fundCount}");
-                    $this->line("    📦 物品日志: {$itemCount}");
-                    $this->line("    🌾 农场日志: {$farmCount}");
-                    $this->line("    ⭐ 积分日志: {$pointCount}");
+                    foreach ($collectorsInfo as $name => $info) {
+                        $sourceType = $info['source_type'];
+                        $count = \App\Module\Game\Models\UserLog::where('source_type', $sourceType)->count();
+                        $icon = $this->getCollectorIcon($sourceType);
+                        $description = $this->getCollectorDescription($sourceType);
+                        $this->line("    {$icon} {$description}: {$count}");
+                    }
                 }
             } catch (\Exception $e) {
                 $this->line("  ⚠️  无法获取用户日志统计: " . $e->getMessage());
@@ -90,12 +95,6 @@ class CollectUserLogsCommand extends Command
             return 0;
         }
 
-        // 重置收集器进度
-        if ($this->option('reset')) {
-            $this->resetCollectors($manager);
-            return 0;
-        }
-
         // 执行日志收集
         return $this->executeCollection($manager);
     }
@@ -342,47 +341,67 @@ class CollectUserLogsCommand extends Command
         }
     }
 
+
+
     /**
-     * 重置收集器进度
+     * 显示统计信息
      *
      * @param UserLogCollectorManager $manager
      * @return void
      */
-    private function resetCollectors(UserLogCollectorManager $manager): void
+    private function showStats(UserLogCollectorManager $manager): void
     {
-        if ($this->confirm('确定要重置处理进度吗?这将清空所有用户日志并从头开始收集。')) {
-            try {
-                // 清空用户日志表
-                \App\Module\Game\Models\UserLog::truncate();
-
-                // 重置全局时间戳(兼容性)
-                \Illuminate\Support\Facades\Cache::forget('user_log_collector:global_last_timestamp');
+        $collectorsInfo = $manager->getCollectorsInfo();
 
-                // 重置各收集器的进度(兼容性)
-                $manager->resetAllCollectors();
+        $this->line("");
+        $this->line("收集器数量: " . count($collectorsInfo));
 
-                $this->info("✅ 已重置处理进度,清空了所有用户日志");
-            } catch (\Exception $e) {
-                $this->error("❌ 重置失败: {$e->getMessage()}");
-            }
+        // 动态显示所有收集器
+        foreach ($collectorsInfo as $name => $info) {
+            $icon = $this->getCollectorIcon($info['source_type']);
+            $this->line("- {$name}: {$icon} {$this->getCollectorDescription($info['source_type'])}");
         }
+        $this->line("");
     }
 
     /**
-     * 显示统计信息
+     * 获取收集器图标
      *
-     * @param UserLogCollectorManager $manager
-     * @return void
+     * @param string $sourceType
+     * @return string
      */
-    private function showStats(UserLogCollectorManager $manager): void
+    private function getCollectorIcon(string $sourceType): string
     {
-        $this->line("");
-        $this->line("收集器数量: 4");
-        $this->line("- fund: 资金日志收集器");
-        $this->line("- item: 物品日志收集器");
-        $this->line("- farm: 农场日志收集器");
-        $this->line("- point: 积分日志收集器");
-        $this->line("");
+        $icons = [
+            'fund' => '💰',
+            'item' => '📦',
+            'farm' => '🌾',
+            'point' => '⭐',
+            'pet' => '🐾',
+            'system' => '⚙️',
+        ];
+
+        return $icons[$sourceType] ?? '📄';
+    }
+
+    /**
+     * 获取收集器描述
+     *
+     * @param string $sourceType
+     * @return string
+     */
+    private function getCollectorDescription(string $sourceType): string
+    {
+        $descriptions = [
+            'fund' => '资金日志收集器',
+            'item' => '物品日志收集器',
+            'farm' => '农场日志收集器',
+            'point' => '积分日志收集器',
+            'pet' => '宠物日志收集器',
+            'system' => '系统日志收集器',
+        ];
+
+        return $descriptions[$sourceType] ?? '未知类型收集器';
     }
 
     /**

+ 0 - 27
app/Module/Game/Databases/GenerateSql/user_logs_upgrade.sql

@@ -1,27 +0,0 @@
--- ******************************************************************
--- 用户日志表升级SQL - 添加原始时间和收集时间字段
--- 对应的Model: App\Module\Game\Models\UserLog
--- 升级说明: 添加original_time和collected_at字段,支持原始时间排序
--- ******************************************************************
-
--- 1. 添加新字段
-ALTER TABLE `kku_user_logs` 
-ADD COLUMN `original_time` timestamp NULL DEFAULT NULL COMMENT '原始日志时间(业务发生时间)' AFTER `source_table`,
-ADD COLUMN `collected_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收集时间(日志收集时间)' AFTER `original_time`;
-
--- 2. 数据迁移:将现有的created_at复制到original_time和collected_at
-UPDATE `kku_user_logs` SET 
-    `original_time` = `created_at`,
-    `collected_at` = `created_at`
-WHERE `original_time` IS NULL;
-
--- 3. 添加新索引
-ALTER TABLE `kku_user_logs` 
-ADD KEY `idx_original_time` (`original_time`),
-ADD KEY `idx_collected_at` (`collected_at`),
-ADD KEY `idx_user_original_time` (`user_id`, `original_time`),
-ADD KEY `idx_user_collected_at` (`user_id`, `collected_at`);
-
--- 4. 修改字段注释,明确用途
-ALTER TABLE `kku_user_logs` 
-MODIFY COLUMN `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(兼容字段,等同于collected_at)';

+ 6 - 9
app/Module/Game/Docs/UserLog.md

@@ -311,9 +311,6 @@ php artisan game:collect-user-logs --info
 
 # 显示统计信息
 php artisan game:collect-user-logs --statistics
-
-# 重置收集进度(危险操作)
-php artisan game:collect-user-logs --reset
 ```
 
 ### 命令选项详解
@@ -352,12 +349,12 @@ php artisan game:collect-user-logs --reset
     ⭐ 积分日志: 866
 ```
 
-#### --reset 重置模式
-重置所有收集进度,清空用户日志表
-```bash
-php artisan game:collect-user-logs --reset
-# 会提示确认:确定要重置处理进度吗?这将清空所有用户日志并从头开始收集。
-```
+#### 进度管理
+系统采用基于已处理记录的进度追踪机制
+- 进度通过`user_logs`表中的记录自动追踪
+- 每个收集器会查找最后处理的记录,从该位置继续收集
+- 无需手动重置,系统会自动从上次中断的位置继续
+- 如需重新收集,可直接删除`user_logs`表中对应的记录
 
 ## 计划任务配置
 

+ 0 - 165
app/Module/Game/Docs/UserLogProgressTracking.md

@@ -1,165 +0,0 @@
-# 用户日志系统进度追踪机制优化
-
-## 概述
-
-根据用户要求,用户日志系统的进度追踪机制已从使用缓存存储改为通过读取 `user_logs` 表的数据来确定处理进度。这种方式更加可靠和准确。
-
-## 修改内容
-
-### 1. 进度追踪方式变更
-
-**原来的方式(使用缓存):**
-```php
-// 从缓存获取进度
-$lastProcessedId = Cache::get("user_log_collector:last_processed_id:{$sourceTable}", 0);
-$lastProcessedTimestamp = Cache::get("user_log_collector:last_processed_timestamp:{$sourceTable}", 0);
-
-// 更新进度到缓存
-Cache::put("user_log_collector:last_processed_id:{$sourceTable}", $id, 86400);
-Cache::put("user_log_collector:last_processed_timestamp:{$sourceTable}", $timestamp, 86400);
-```
-
-**现在的方式(读取user_logs表):**
-```php
-// 从user_logs表获取最后处理的记录
-$lastLog = UserLog::where('source_table', $sourceTable)
-    ->where('source_type', $sourceType)
-    ->orderBy('source_id', 'desc')
-    ->first();
-
-$lastProcessedId = $lastLog ? $lastLog->source_id : 0;
-```
-
-### 2. 核心修改文件
-
-#### BaseLogCollector.php
-- `getLastProcessedId()`: 改为从user_logs表查询最后处理的source_id
-- `getLastProcessedTimestamp()`: 改为从user_logs表查询最后处理的时间戳
-- `updateLastProcessedId()`: 不再需要手动更新,进度自动追踪
-- `updateLastProcessedTimestamp()`: 不再需要手动更新,进度自动追踪
-- 添加 `getOriginalRecordTimestamp()` 抽象方法
-
-#### 各收集器实现
-- **FundLogCollector**: 添加 `getOriginalRecordTimestamp()` 方法
-- **ItemLogCollector**: 添加 `getOriginalRecordTimestamp()` 方法  
-- **FarmLogCollector**: 添加 `getOriginalRecordTimestamp()` 方法,处理多表情况
-
-#### CollectUserLogsCommand.php
-- 修改统计功能,从user_logs表读取进度信息
-- 修改重置功能,清空user_logs表而不是清除缓存
-- 优化错误处理和异常捕获
-
-### 3. 优势
-
-#### 3.1 数据一致性
-- 进度信息直接来源于实际处理结果
-- 避免缓存与实际数据不一致的问题
-- 重启服务后进度不会丢失
-
-#### 3.2 可靠性
-- 不依赖缓存系统的稳定性
-- 数据持久化存储,不会因为缓存清理而丢失
-- 可以通过数据库查询验证处理进度
-
-#### 3.3 可追溯性
-- 可以查看具体的处理历史
-- 便于问题排查和数据审计
-- 支持按时间范围查询处理记录
-
-### 4. 实现细节
-
-#### 4.1 进度查询逻辑
-```php
-protected function getLastProcessedId(): int
-{
-    try {
-        $lastLog = \App\Module\Game\Models\UserLog::where('source_table', $this->sourceTable)
-            ->where('source_type', $this->sourceType)
-            ->orderBy('source_id', 'desc')
-            ->first();
-
-        return $lastLog ? $lastLog->source_id : 0;
-    } catch (\Exception $e) {
-        Log::error("获取最后处理ID失败", [
-            'collector' => $this->collectorName,
-            'source_table' => $this->sourceTable,
-            'error' => $e->getMessage()
-        ]);
-        return 0;
-    }
-}
-```
-
-#### 4.2 农场收集器特殊处理
-由于农场收集器需要处理多个表(farm_harvest_logs 和 farm_upgrade_logs),进度查询逻辑特殊处理:
-
-```php
-protected function getLastProcessedId(): int
-{
-    try {
-        // 查询农场相关的最后处理记录
-        $lastLog = \App\Module\Game\Models\UserLog::where('source_type', $this->sourceType)
-            ->whereIn('source_table', ['farm_harvest_logs', 'farm_upgrade_logs'])
-            ->orderBy('source_id', 'desc')
-            ->first();
-
-        return $lastLog ? $lastLog->source_id : 0;
-    } catch (\Exception $e) {
-        return 0;
-    }
-}
-```
-
-#### 4.3 时间戳获取
-```php
-protected function getOriginalRecordTimestamp(int $recordId): int
-{
-    try {
-        $record = FundLogModel::find($recordId);
-        return $record ? $record->create_time : 0;
-    } catch (\Exception $e) {
-        return 0;
-    }
-}
-```
-
-### 5. 计划任务配置
-
-在 `routes/console.php` 中添加了用户日志收集的计划任务:
-
-```php
-// 每分钟收集用户日志(实现高频收集)
-\Illuminate\Support\Facades\Schedule::command('game:collect-user-logs --limit=100')->everyMinute();
-```
-
-虽然无法实现严格的"每2秒"执行,但每分钟执行可以保证较高的实时性。
-
-### 6. 命令使用
-
-```bash
-# 显示收集器信息
-php artisan game:collect-user-logs --info
-
-# 显示统计信息
-php artisan game:collect-user-logs --stats
-
-# 执行收集(限制处理记录数)
-php artisan game:collect-user-logs --limit=100
-
-# 显示详细处理过程
-php artisan game:collect-user-logs --detail
-
-# 重置进度(清空user_logs表)
-php artisan game:collect-user-logs --reset
-```
-
-### 7. 注意事项
-
-1. **重置功能**: `--reset` 选项会清空整个user_logs表,请谨慎使用
-2. **性能考虑**: 每次查询user_logs表获取进度,在高频执行时需要注意数据库性能
-3. **兼容性**: 保留了原有的缓存相关方法,确保向后兼容
-4. **错误处理**: 增强了异常处理,避免单个收集器失败影响整体流程
-
-## 总结
-
-通过这次优化,用户日志系统的进度追踪更加可靠和准确。系统不再依赖缓存存储进度信息,而是直接从实际的处理结果(user_logs表)中获取进度,确保了数据的一致性和可靠性。

+ 0 - 12
app/Module/Game/Logics/UserLogCollectorManager.php

@@ -194,19 +194,7 @@ class UserLogCollectorManager
         ]);
     }
 
-    /**
-     * 重置所有收集器的处理进度
-     *
-     * @return void
-     */
-    public function resetAllCollectors(): void
-    {
-        foreach ($this->collectors as $name => $collector) {
-            $collector->resetAllProgress();
-        }
 
-        Log::info("重置所有收集器进度");
-    }
 
     /**
      * 添加自定义收集器

+ 1 - 31
app/Module/Game/Logics/UserLogCollectors/BaseLogCollector.php

@@ -3,7 +3,6 @@
 namespace App\Module\Game\Logics\UserLogCollectors;
 
 use App\Module\Game\Services\UserLogService;
-use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Log;
 
 /**
@@ -425,27 +424,7 @@ abstract class BaseLogCollector
         return $this->sourceType;
     }
 
-    /**
-     * 重置最后处理的ID(用于重新处理)
-     *
-     * @return void
-     */
-    public function resetLastProcessedId(): void
-    {
-        $cacheKey = $this->getLastProcessedIdCacheKey();
-        Cache::forget($cacheKey);
-    }
 
-    /**
-     * 重置最后处理的时间戳(用于重新处理)
-     *
-     * @return void
-     */
-    public function resetLastProcessedTimestamp(): void
-    {
-        $cacheKey = $this->getLastProcessedTimestampCacheKey();
-        Cache::forget($cacheKey);
-    }
 
     /**
      * 检查是否为重复记录
@@ -474,14 +453,5 @@ abstract class BaseLogCollector
         }
     }
 
-    /**
-     * 重置所有处理进度
-     *
-     * @return void
-     */
-    public function resetAllProgress(): void
-    {
-        $this->resetLastProcessedId();
-        $this->resetLastProcessedTimestamp();
-    }
+
 }