| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- <?php
- namespace App\Module\UrsPromotion\Services;
- use App\Module\UrsPromotion\Models\UrsUserMapping;
- use App\Module\User\Models\User;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use Carbon\Carbon;
- /**
- * URS活跃用户服务
- *
- * 负责管理URS用户的活跃状态,包括活跃状态检查、更新和统计
- */
- class UrsActiveUserService
- {
- /**
- * 活跃用户定义:最近15天有活动的用户
- */
- const ACTIVE_DAYS_THRESHOLD = 15;
- /**
- * 更新单个用户的活跃状态
- *
- * @param int $ursUserId URS用户ID
- * @return bool
- */
- public static function updateUserActiveStatus(int $ursUserId): bool
- {
- try {
- // 获取用户映射关系
- $mapping = UrsUserMapping::where('urs_user_id', $ursUserId)
- ->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;
- }
- /**
- * 检查用户活跃状态
- *
- * @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()
- ];
- }
- }
- }
|