11日1734-完成CollectUserLogsCommand对接Point日志.md 8.7 KB

完成CollectUserLogsCommand对接Point日志

任务概述

为CollectUserLogsCommand命令添加Point模块的日志收集功能,创建PointLogCollector收集器,实现积分日志的自动收集和用户友好消息转换。

执行时间

  • 开始时间:2025年06月11日 17:18
  • 完成时间:2025年06月11日 17:34
  • 总耗时:约16分钟

主要变更

1. 创建PointLogCollector日志收集器

文件位置

  • app/Module/Game/Logics/UserLogCollectors/PointLogCollector.php

核心功能

  • 继承BaseLogCollector:遵循统一的收集器架构
  • 源表配置point_logs表,源类型为point
  • 时间戳支持:支持按时间线收集,使用create_time字段
  • 记录转换:将原始积分日志转换为用户友好的消息

消息生成逻辑

// 根据操作类型生成不同的消息格式
$message = match($record->operate_type) {
    LOG_TYPE::TASK_COMPLETE => "完成任务{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::CHECKIN_REWARD => "签到{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::ACTIVITY_REWARD => "活动奖励{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::ACHIEVEMENT_REWARD => "成就奖励{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::REFERRAL_REWARD => "推荐奖励{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::POINT_CONSUME => "消费{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::POINT_EXCHANGE => "兑换{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::TRANSFER => $this->buildTransferMessage($record, $pointTypeName, $action, $amount),
    LOG_TYPE::CIRCULATION => "积分流转{$action} {$amount} {$pointTypeName}",
    LOG_TYPE::ADMIN_OPERATE => "管理员操作{$action} {$amount} {$pointTypeName}",
    // ... 更多类型
};

过滤逻辑

  • 过滤掉测试操作(LOG_TYPE::TEST
  • 过滤掉金额为0的记录
  • 支持扩展的内部操作过滤

2. 更新UserLogCollectorManager

注册Point收集器

private function registerCollectors(): void
{
    $this->collectors = [
        'fund' => new FundLogCollector(),
        'item' => new ItemLogCollector(),
        'farm' => new FarmLogCollector(),
        'point' => new PointLogCollector(),  // 新增
        // 可以在这里添加更多收集器
    ];
}

添加引用

use App\Module\Game\Logics\UserLogCollectors\PointLogCollector;

3. 更新CollectUserLogsCommand

统计信息支持

// 按类型统计
$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}");  // 新增

表查询支持

// getTableMaxId方法
case 'point_logs':
    return \App\Module\Point\Models\PointLogModel::max('id') ?: 0;

// getTableRecordCount方法
case 'point_logs':
    return \App\Module\Point\Models\PointLogModel::count();

收集器数量更新

private function showStats(UserLogCollectorManager $manager): void
{
    $this->line("");
    $this->line("收集器数量: 4");  // 从3更新为4
    $this->line("- fund: 资金日志收集器");
    $this->line("- item: 物品日志收集器");
    $this->line("- farm: 农场日志收集器");
    $this->line("- point: 积分日志收集器");  // 新增
    $this->line("");
}

4. 修复PointLogModel哈希生成

问题修复

修复了generateHash方法中枚举对象转换为字符串的问题:

$data = [
    $log->user_id,
    $log->point_id->value,  // 修复:添加->value
    $log->amount,
    $log->operate_type->value,
    $log->operate_id,
    $log->before_balance,
    $log->later_balance,
    $log->create_time,
    $log->prev_hash
];

功能特点

1. 智能消息生成

  • 操作类型识别:根据不同的积分操作类型生成相应的消息
  • 正负值处理:正值显示"获得",负值显示"消耗"
  • 积分类型显示:显示具体的积分类型名称(经验积分、成就积分等)
  • 备注信息:包含原始备注信息,提供更多上下文

2. 用户友好的消息格式

生成的消息示例:

  • "完成任务获得 100 经验积分(完成每日任务)"
  • "签到获得 20 签到积分(每日签到奖励)"
  • "消费消耗 30 经验积分(购买道具消耗积分)"
  • "推荐奖励获得 200 推荐积分(推荐新用户奖励)"
  • "成就奖励获得 50 成就积分(完成首次登录成就)"

3. 完整的收集器架构

  • 时间线支持:支持按时间戳进行增量收集
  • 错误处理:完善的异常处理和日志记录
  • 过滤机制:智能过滤不需要的记录
  • 性能优化:批量处理和限制记录数量

4. 统一的管理界面

  • 收集器信息--info参数显示所有收集器信息
  • 统计信息--statistics参数显示详细统计
  • 详细模式--detail参数显示处理过程
  • 进度重置--reset参数重置收集进度

测试验证

1. 收集器注册验证

php artisan game:collect-user-logs --info

输出显示Point收集器已成功注册:

收集器: point
  类名: App\Module\Game\Logics\UserLogCollectors\PointLogCollector
  源表: point_logs
  类型: point

2. 日志收集测试

php artisan game:collect-user-logs --detail

成功处理了10条积分日志记录:

📝 开始处理各收集器...
  fund: 处理了 0 条记录
  item: 处理了 0 条记录
  farm: 处理了 0 条记录
  point: 处理了 10 条记录

3. 统计信息验证

php artisan game:collect-user-logs --statistics

积分日志统计正确显示:

📊 按类型统计:
    💰 资金日志: 4297
    📦 物品日志: 6648
    🌾 农场日志: 673866
    ⭐ 积分日志: 10

4. 消息质量验证

生成的用户日志消息格式正确,内容友好:

  • 用户1: 6条日志(任务完成、成就奖励、积分消费)
  • 用户2: 2条日志(签到奖励)
  • 用户3: 2条日志(推荐奖励)

技术实现

1. 继承架构

BaseLogCollector (基类)
├── FundLogCollector (资金日志)
├── ItemLogCollector (物品日志)
├── FarmLogCollector (农场日志)
└── PointLogCollector (积分日志) ← 新增

2. 数据流程

Point原始日志 → PointLogCollector → 用户友好消息 → UserLog表

3. 消息转换流程

  1. 获取原始记录:从point_logs表获取新记录
  2. 类型识别:识别积分类型和操作类型
  3. 消息生成:根据操作类型生成相应消息
  4. 过滤处理:过滤不需要的记录
  5. 批量保存:保存到user_logs

使用方法

1. 基本收集

# 执行日志收集
php artisan game:collect-user-logs

# 详细模式
php artisan game:collect-user-logs --detail

# 限制处理数量
php artisan game:collect-user-logs --limit=500

2. 信息查看

# 查看收集器信息
php artisan game:collect-user-logs --info

# 查看统计信息
php artisan game:collect-user-logs --statistics

3. 进度管理

# 重置收集进度
php artisan game:collect-user-logs --reset

扩展性

1. 新增操作类型

buildUserFriendlyMessage方法中添加新的match分支:

LOG_TYPE::NEW_OPERATION => "新操作{$action} {$amount} {$pointTypeName}",

2. 自定义过滤规则

shouldLogRecord方法中添加新的过滤条件:

// 过滤特定操作ID
if (str_starts_with($record->operate_id, 'internal_')) {
    return false;
}

3. 消息格式定制

可以根据不同的积分类型或用户群体定制消息格式。

总结

Point模块的日志收集功能已完全集成到CollectUserLogsCommand中,具备以下特点:

  • 完整集成:Point收集器已注册到收集器管理器中
  • 智能转换:原始积分日志转换为用户友好的消息
  • 统一管理:通过统一的命令界面管理所有日志收集
  • 性能优化:支持增量收集和批量处理
  • 错误处理:完善的异常处理和日志记录
  • 扩展性强:易于添加新的操作类型和过滤规则

现在用户可以通过CollectUserLogsCommand命令自动收集积分日志,生成用户友好的日志消息,为用户提供清晰的积分变动记录。