050425-修复URS用户活跃状态数据不一致问题.md 5.1 KB

修复 URS 用户活跃状态数据不一致问题

任务时间: 2025年07月05日 04:25 任务类型: Bug修复 + 功能增强 模块: UrsPromotion

问题描述

用户反馈项目才上线几天,没到不活跃的限制天数(15天),但是 UrsUserMapping 表中有102个用户的 is_active 字段被标记为0(不活跃),这是不正确的。

问题分析

1. 数据检查结果

  • 总用户数: 3124
  • 活跃用户: 3022 (96.73%)
  • 不活跃用户: 102 (3.27%)
  • 活跃判定标准: 最近15天有活动

2. 深入分析发现的问题

通过手动检查不活跃用户的详细信息,发现:

用户 44578: 最后活动时间 2025-07-04 23:03:23 (距今 -0.22天)
用户 10387: 最后活动时间 2025-07-05 00:18:18 (距今 -0.17天)  
用户 10003: 最后活动时间 2025-07-05 02:45:04 (距今 -0.07天)

关键发现:

  • 这些用户的最后活动时间都是最近的(今天或昨天)
  • 手动调用 UrsActiveUserService::checkUserActivity() 返回 true(活跃)
  • 但数据库中 is_active 字段为 0(不活跃)
  • 数据库状态与实际检查结果不一致

3. 根本原因分析

  1. 定时任务逻辑限制: getUsersNeedActivityCheck() 方法只检查 last_activity_check 超过1天的用户
  2. 初始化数据问题: 可能在数据初始化时某些用户状态设置不正确
  3. 更新时机问题: 定时任务可能在某个时间点执行异常,导致部分用户状态未正确更新

解决方案

1. 立即修复数据

执行强制更新脚本,修复所有状态不一致的用户:

// 获取所有标记为不活跃的用户
$inactiveUsers = UrsUserMapping::where('is_active', 0)
    ->where('status', 1)
    ->with('user.info')
    ->get();

// 检查并更新实际应该活跃的用户
foreach($inactiveUsers as $mapping) {
    if ($mapping->user) {
        $isActive = UrsActiveUserService::checkUserActivity($mapping->user);
        if ($isActive) {
            $mapping->update([
                'is_active' => 1,
                'last_activity_check' => now(),
                'active_days_count' => 1,
            ]);
        }
    }
}

修复结果:

  • 应该活跃的用户: 100个
  • 实际更新的用户: 100个
  • 修复后活跃比例: 99.94% (3122/3124)
  • 剩余不活跃用户: 2个(确实无活动记录)

2. 增强命令功能

为防止类似问题再次发生,增强 urs:update-active-status 命令:

2.1 添加 --force 选项

php artisan urs:update-active-status --force
  • 强制检查所有用户,忽略 last_activity_check 时间限制
  • 适用于数据修复和全量检查场景

2.2 新增 forceUpdateActiveStatus 方法

public static function forceUpdateActiveStatus(int $limit = 1000): array
{
    // 获取所有有效用户映射,忽略last_activity_check限制
    $mappings = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID)
        ->with(['user', 'user.info'])
        ->limit($limit)
        ->get();
    
    // 逐个检查并更新活跃状态
    foreach ($mappings as $mapping) {
        $isActive = self::checkUserActivity($mapping->user);
        $mapping->update([
            'is_active' => $isActive ? 1 : 0,
            'last_activity_check' => now(),
            'active_days_count' => $isActive ? 1 : 0,
        ]);
    }
}

3. 修改的文件

  1. 命令文件: app/Module/UrsPromotion/Commands/UrsUpdateActiveStatusCommand.php

    • 添加 --force 选项
    • 更新帮助信息
    • 增强处理逻辑
  2. 服务文件: app/Module/UrsPromotion/Services/UrsActiveUserService.php

    • 新增 forceUpdateActiveStatus() 方法
    • 支持强制更新所有用户状态

验证结果

1. 数据修复验证

修复前: 活跃用户 3022 (96.73%), 不活跃用户 102
修复后: 活跃用户 3122 (99.94%), 不活跃用户 2

2. 功能测试验证

# 测试强制更新功能
php artisan urs:update-active-status --force --limit=10 --dry-run
# ✅ 命令执行正常,功能可用

3. 剩余不活跃用户验证

剩余的2个不活跃用户确实无活动记录,状态正确:

用户 46260: 无活动记录
用户 46262: 无活动记录

预防措施

1. 监控建议

  • 定期检查活跃状态统计,关注异常波动
  • 监控定时任务执行日志,确保正常运行
  • 设置活跃比例告警,低于预期时及时处理

2. 运维建议

  • 每周执行一次强制更新: php artisan urs:update-active-status --force
  • 在数据迁移或系统升级后执行数据一致性检查
  • 保持定时任务的稳定执行

3. 代码改进建议

  • 考虑在 getUsersNeedActivityCheck 方法中增加数据一致性检查
  • 添加活跃状态变更的详细日志记录
  • 考虑实现活跃状态的实时更新机制

总结

此次问题的核心是数据库状态与实际业务逻辑不一致,通过强制更新修复了100个用户的错误状态,并增强了命令功能以防止类似问题再次发生。现在系统的活跃用户比例达到99.94%,符合项目刚上线几天的预期状态。