$userId], [ 'talent_level' => 0, 'direct_count' => 0, 'indirect_count' => 0, 'third_count' => 0, 'promotion_count' => 0, ] ); $oldLevel = $talent->talent_level; // 更新团队统计数据(使用模型方法确保逻辑一致性) $talent->updateTeamStats( $stats[1], $stats[2], $stats[3], $stats['total'] // 20代总人数 ); // 更新达人等级 if ($newLevel > $oldLevel) { $talent->upgradeTalentLevel($newLevel); } $talent->save(); DB::commit(); if ($oldLevel !== $newLevel) { Log::info('URS达人等级更新', [ 'user_id' => $ursUserId, 'old_level' => $oldLevel, 'new_level' => $newLevel, 'direct_count' => $stats[1], 'total_team_count' => $stats['total'], ]); } // 获取配置信息用于创建DTO $config = UrsTalentConfig::where('level', $talent->talent_level)->first(); $nextConfig = UrsTalentConfig::where('level', $talent->talent_level + 1)->first(); $currentConfig = $config ? [ 'name' => $config->name, 'description' => $config->description, 'icon' => $config->icon, ] : null; $nextConfigArray = $nextConfig ? [ 'level' => $nextConfig->level, 'name' => $nextConfig->name, 'direct_count_required' => $nextConfig->direct_count_required, 'promotion_count_required' => $nextConfig->promotion_count_required, 'active_direct_required' => $nextConfig->active_direct_required, 'active_count_required' => $nextConfig->active_count_required, ] : null; return UrsUserTalentDto::fromModel( $talent, $currentConfig, $nextConfigArray, $activeDirectStats['active_direct_count'], $activeTeamStats['active_total_count'] ); } catch (\Exception $e) { DB::rollBack(); Log::error('URS达人等级更新失败', [ 'user_id' => $ursUserId, 'error' => $e->getMessage() ]); throw $e; } } /** * 根据团队数据计算达人等级 * * @param int $directCount 直推人数 * @param int $totalCount 团队总人数 * @param int $activeDirectCount 活跃直推人数 * @param int $activeTotalCount 活跃团队总人数 * @return int 达人等级 */ private static function calculateTalentLevel(int $directCount, int $totalCount, int $activeDirectCount = 0, int $activeTotalCount = 0): int { // 获取等级配置(按等级倒序排列) $configs = UrsTalentConfig::where('status', 1) ->orderBy('level', 'desc') ->get(); foreach ($configs as $config) { // 检查基础条件 $directCountMet = $directCount >= $config->direct_count_required; $totalCountMet = $totalCount >= $config->promotion_count_required; // 检查活跃用户条件 $activeDirectMet = $activeDirectCount >= $config->active_direct_required; $activeTotalMet = $activeTotalCount >= $config->active_count_required; if ($directCountMet && $totalCountMet && $activeDirectMet && $activeTotalMet) { return $config->level; } } return 0; // 默认等级 } /** * 获取用户的达人信息 * * @param int $userId 用户ID * @return UrsUserTalentDto|null */ public static function getTalentInfo(int $userId): ?UrsUserTalentDto { $talent = UrsUserTalent::where('user_id', $userId)->first(); if (!$talent) { return null; } $config = UrsTalentConfig::where('level', $talent->talent_level)->first(); $nextConfig = UrsTalentConfig::where('level', $talent->talent_level + 1)->first(); $currentConfig = $config ? [ 'name' => $config->name, 'description' => $config->description, 'icon' => $config->icon, ] : null; $nextConfigArray = $nextConfig ? [ 'level' => $nextConfig->level, 'name' => $nextConfig->name, 'direct_count_required' => $nextConfig->direct_count_required, 'promotion_count_required' => $nextConfig->promotion_count_required, ] : null; return UrsUserTalentDto::fromModel($talent, $currentConfig, $nextConfigArray); } /** * 批量更新达人等级 * * @param array $ursUserIds URS用户ID数组 * @return array 更新结果 */ public static function batchUpdateTalentLevels(array $userIds): array { $results = []; foreach ($userIds as $userId) { try { $talent = self::updateTalentLevel($userId); $results[$userId] = [ 'success' => true, 'talent_level' => $talent->talentLevel, 'direct_count' => $talent->directCount, 'promotion_count' => $talent->promotionCount, ]; } catch (\Exception $e) { $results[$userId] = [ 'success' => false, 'error' => $e->getMessage(), ]; } } return $results; } /** * 获取所有达人等级配置 * * @return array */ public static function getAllTalentConfigs(): array { return UrsTalentConfig::where('status', 1) ->orderBy('level') ->get() ->map(function ($config) { return [ 'level' => $config->level, 'name' => $config->name, 'description' => $config->description, 'icon' => $config->icon, 'direct_count_required' => $config->direct_count_required, 'promotion_count_required' => $config->promotion_count_required, 'promotion_reward_rates' => $config->promotion_reward_rates, 'planting_reward_rates' => $config->planting_reward_rates, ]; }) ->toArray(); } /** * 检查用户是否满足升级条件 * * @param int $ursUserId URS用户ID * @return array */ public static function checkUpgradeEligibility(int $userId): array { $talent = UrsUserTalent::where('user_id', $userId)->first(); if (!$talent) { return ['eligible' => false, 'reason' => '用户达人信息不存在']; } $nextLevel = $talent->talent_level + 1; $nextConfig = UrsTalentConfig::where('level', $nextLevel)->first(); if (!$nextConfig) { return ['eligible' => false, 'reason' => '已达到最高等级']; } $ursUserId = UrsUserMappingService::getUrsUserId($userId); // 获取活跃团队成员统计 $activeStats = UrsActiveUserService::getActiveTeamMembers($ursUserId); // 检查各项条件 $directCountMet = $talent->direct_count >= $nextConfig->direct_count_required; $promotionCountMet = $talent->promotion_count >= $nextConfig->promotion_count_required; $activeDirectMet = $activeStats['active_direct_count'] >= $nextConfig->active_direct_required; $activeTotalMet = $activeStats['active_total_count'] >= $nextConfig->active_count_required; return [ 'eligible' => $directCountMet && $promotionCountMet && $activeDirectMet && $activeTotalMet, 'next_level' => $nextLevel, 'next_level_name' => $nextConfig->name, 'requirements' => [ 'direct_count' => [ 'required' => $nextConfig->direct_count_required, 'current' => $talent->direct_count, 'met' => $directCountMet, 'gap' => max(0, $nextConfig->direct_count_required - $talent->direct_count), ], 'promotion_count' => [ 'required' => $nextConfig->promotion_count_required, 'current' => $talent->promotion_count, 'met' => $promotionCountMet, 'gap' => max(0, $nextConfig->promotion_count_required - $talent->promotion_count), ], 'active_direct_count' => [ 'required' => $nextConfig->active_direct_required, 'current' => $activeStats['active_direct_count'], 'met' => $activeDirectMet, 'gap' => max(0, $nextConfig->active_direct_required - $activeStats['active_direct_count']), ], 'active_total_count' => [ 'required' => $nextConfig->active_count_required, 'current' => $activeStats['active_total_count'], 'met' => $activeTotalMet, 'gap' => max(0, $nextConfig->active_count_required - $activeStats['active_total_count']), ], ], ]; } }