where('status', UrsUserMapping::STATUS_VALID) ->with('user') ->first(); if (!$mapping || !$mapping->user) { Log::warning('URS用户映射关系不存在或农场用户不存在', [ 'urs_user_id' => $ursUserId ]); return false; } // 检查用户活跃状态 $isActive = self::checkUserActivity($mapping->user); $activeDaysCount = self::calculateActiveDaysCount($mapping->user); // 更新活跃状态 $mapping->update([ 'is_active' => $isActive ? UrsUserMapping::ACTIVE_YES : UrsUserMapping::ACTIVE_NO, 'last_activity_check' => now(), 'active_days_count' => $activeDaysCount, ]); Log::info('URS用户活跃状态更新成功', [ 'urs_user_id' => $ursUserId, 'farm_user_id' => $mapping->user_id, 'is_active' => $isActive, 'active_days_count' => $activeDaysCount ]); return true; } catch (\Exception $e) { Log::error('URS用户活跃状态更新失败', [ 'urs_user_id' => $ursUserId, 'error' => $e->getMessage() ]); return false; } } /** * 批量更新用户活跃状态 * * @param int $limit 每次处理的用户数量限制 * @return array 更新结果统计 */ public static function batchUpdateActiveStatus(int $limit = 1000): array { $stats = [ 'total_processed' => 0, 'successful_updates' => 0, 'failed_updates' => 0, 'active_users' => 0, 'inactive_users' => 0, ]; try { // 获取需要检查的用户(预加载用户和用户信息关联) $mappings = UrsUserMapping::getUsersNeedActivityCheck($limit); $stats['total_processed'] = $mappings->count(); Log::info('开始批量更新URS用户活跃状态', [ 'total_users' => $stats['total_processed'], 'limit' => $limit ]); foreach ($mappings as $mapping) { try { if (!$mapping->user) { $stats['failed_updates']++; continue; } // 检查用户活跃状态 $isActive = self::checkUserActivity($mapping->user); $activeDaysCount = self::calculateActiveDaysCount($mapping->user); // 更新活跃状态 $mapping->update([ 'is_active' => $isActive ? UrsUserMapping::ACTIVE_YES : UrsUserMapping::ACTIVE_NO, 'last_activity_check' => now(), 'active_days_count' => $activeDaysCount, ]); $stats['successful_updates']++; if ($isActive) { $stats['active_users']++; } else { $stats['inactive_users']++; } } catch (\Exception $e) { $stats['failed_updates']++; Log::error('单个用户活跃状态更新失败', [ 'urs_user_id' => $mapping->urs_user_id, 'error' => $e->getMessage() ]); } } Log::info('批量更新URS用户活跃状态完成', $stats); } catch (\Exception $e) { Log::error('批量更新URS用户活跃状态失败', [ 'error' => $e->getMessage(), 'stats' => $stats ]); } return $stats; } /** * 强制更新用户活跃状态(忽略last_activity_check时间限制) * * @param int $limit 每次处理的用户数量限制 * @return array 更新结果统计 */ public static function forceUpdateActiveStatus(int $limit = 1000): array { $stats = [ 'total_processed' => 0, 'successful_updates' => 0, 'failed_updates' => 0, 'active_users' => 0, 'inactive_users' => 0, ]; try { // 获取所有有效的用户映射(忽略last_activity_check限制) $mappings = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID) ->with(['user', 'user.info']) ->limit($limit) ->get(); $stats['total_processed'] = $mappings->count(); Log::info('开始强制更新URS用户活跃状态', [ 'total_users' => $stats['total_processed'], 'limit' => $limit ]); foreach ($mappings as $mapping) { try { if (!$mapping->user) { $stats['failed_updates']++; continue; } // 检查用户活跃状态 $isActive = self::checkUserActivity($mapping->user); $activeDaysCount = self::calculateActiveDaysCount($mapping->user); // 更新活跃状态 $mapping->update([ 'is_active' => $isActive ? UrsUserMapping::ACTIVE_YES : UrsUserMapping::ACTIVE_NO, 'last_activity_check' => now(), 'active_days_count' => $activeDaysCount, ]); $stats['successful_updates']++; if ($isActive) { $stats['active_users']++; } else { $stats['inactive_users']++; } } catch (\Exception $e) { $stats['failed_updates']++; Log::error('单个用户活跃状态强制更新失败', [ 'urs_user_id' => $mapping->urs_user_id, 'error' => $e->getMessage() ]); } } Log::info('强制更新URS用户活跃状态完成', $stats); } catch (\Exception $e) { Log::error('强制更新URS用户活跃状态失败', [ 'error' => $e->getMessage(), 'stats' => $stats ]); } return $stats; } /** * 检查用户活跃状态 * * @param User $user 农场用户对象 * @return bool */ public static function checkUserActivity(User $user): bool { // 获取用户信息中的活动时间 $userInfo = $user->info; if (!$userInfo || !$userInfo->last_activity_time) { return false; } $threshold = Carbon::now()->subDays(self::ACTIVE_DAYS_THRESHOLD); return $userInfo->last_activity_time >= $threshold; } /** * 计算用户活跃天数 * * @param User $user 农场用户对象 * @return int */ public static function calculateActiveDaysCount(User $user): int { // 获取用户信息中的活动时间 $userInfo = $user->info; if (!$userInfo || !$userInfo->last_activity_time) { return 0; } $daysSinceLastActivity = Carbon::now()->diffInDays($userInfo->last_activity_time); // 如果在活跃期内,返回1,否则返回0 return $daysSinceLastActivity <= self::ACTIVE_DAYS_THRESHOLD ? 1 : 0; } /** * 获取活跃用户统计信息 * * @return array */ public static function getActiveUserStats(): array { return UrsUserMapping::getActiveUserStats(); } /** * 获取指定URS用户的活跃团队成员 * * @param int $ursUserId URS用户ID * @return array */ public static function getActiveTeamMembers(int $ursUserId): array { // 获取用户的推荐关系(使用配置的团队统计深度,支持达人等级统计) $teamMembers = UrsReferralService::getTeamMembers($ursUserId); if (empty($teamMembers)) { return [ 'active_direct_count' => 0, 'active_total_count' => 0, 'active_members' => [] ]; } // 提取所有团队成员的URS用户ID $allMemberIds = []; foreach ($teamMembers as $level => $members) { // $members 是一个简单的用户ID数组,不是对象数组 $allMemberIds = array_merge($allMemberIds, $members); } // 获取活跃的团队成员 $activeMemberIds = UrsUserMapping::getActiveUrsUserIds($allMemberIds); // 统计各层级的活跃人数 $activeDirectCount = 0; $activeTotalCount = count($activeMemberIds); $activeMembers = []; foreach ($teamMembers as $level => $members) { foreach ($members as $memberId) { if (in_array($memberId, $activeMemberIds)) { $activeMembers[] = [ 'urs_user_id' => $memberId, 'level' => $level ]; if ($level === 1) { // 直推 $activeDirectCount++; } } } } return [ 'active_direct_count' => $activeDirectCount, 'active_total_count' => $activeTotalCount, 'active_members' => $activeMembers ]; } /** * 获取指定URS用户的活跃直推成员(仅直推层级) * * 针对达人等级升级条件优化,只统计直推活跃用户 * 相比getActiveTeamMembers方法,此方法只关注直推层级,性能更优 * * @param int $ursUserId URS用户ID * @return array 返回活跃直推统计信息 */ public static function getActiveDirectMembers(int $ursUserId): array { // 只获取直推成员(第1层级) $directMembers = UrsReferralService::getDirectReferrals($ursUserId); if (empty($directMembers)) { return [ 'active_direct_count' => 0, 'active_direct_members' => [] ]; } // 获取活跃的直推成员 $activeDirectIds = UrsUserMapping::getActiveUrsUserIds($directMembers); // 构建活跃直推成员详情 $activeDirectMembers = []; foreach ($activeDirectIds as $memberId) { $activeDirectMembers[] = [ 'urs_user_id' => $memberId, 'level' => 1 // 直推层级 ]; } return [ 'active_direct_count' => count($activeDirectIds), 'active_direct_members' => $activeDirectMembers ]; } /** * 获取活跃用户详细统计 * * @return array */ public static function getDetailedActiveStats(): array { $baseStats = self::getActiveUserStats(); // 获取最近更新统计 $recentUpdates = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID) ->where('last_activity_check', '>=', now()->subDay()) ->count(); // 获取需要检查的用户数量 $needCheckCount = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID) ->where(function($query) { $query->whereNull('last_activity_check') ->orWhere('last_activity_check', '<', now()->subDay()); }) ->count(); return array_merge($baseStats, [ 'recent_updates' => $recentUpdates, 'need_check_count' => $needCheckCount, 'last_update_time' => UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID) ->whereNotNull('last_activity_check') ->max('last_activity_check'), ]); } /** * 重置所有用户的活跃状态(用于测试或重新初始化) * * @return array */ public static function resetAllActiveStatus(): array { try { DB::beginTransaction(); // 重置所有用户的活跃状态 $updated = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID) ->update([ 'is_active' => UrsUserMapping::ACTIVE_NO, 'last_activity_check' => null, 'active_days_count' => 0, ]); DB::commit(); Log::info('重置所有URS用户活跃状态完成', [ 'updated_count' => $updated ]); return [ 'success' => true, 'updated_count' => $updated, 'message' => '重置完成' ]; } catch (\Exception $e) { DB::rollBack(); Log::error('重置URS用户活跃状态失败', [ 'error' => $e->getMessage() ]); return [ 'success' => false, 'updated_count' => 0, 'message' => '重置失败:' . $e->getMessage() ]; } } }