clearUserRelationCache($userId); // 获取用户的直接推荐人 $referral = PromotionUserReferral::where('user_id', $userId)->first(); if (!$referral) { Log::info("用户 {$userId} 没有推荐人,无需生成关系缓存"); return true; } $referrerId = $referral->referrer_id; // 创建直接关系缓存 $directRelation = new PromotionUserRelationCache(); $directRelation->user_id = $userId; $directRelation->related_user_id = $referrerId; $directRelation->level = REFERRAL_LEVEL::DIRECT; $directRelation->path = (string)$referrerId; $directRelation->depth = 1; $directRelation->save(); // 获取推荐人的所有上级 $upperRelations = PromotionUserRelationCache::where('user_id', $referrerId)->get(); // 创建间接关系缓存 foreach ($upperRelations as $upperRelation) { $indirectRelation = new PromotionUserRelationCache(); $indirectRelation->user_id = $userId; $indirectRelation->related_user_id = $upperRelation->related_user_id; $indirectRelation->level = REFERRAL_LEVEL::INDIRECT; $indirectRelation->path = $referrerId . ',' . $upperRelation->path; $indirectRelation->depth = $upperRelation->depth + 1; $indirectRelation->save(); } // 清除Redis缓存 Redis::del("promotion:user:{$userId}:all_referrers"); return true; } catch (\Exception $e) { Log::error("生成用户关系缓存失败: " . $e->getMessage()); return false; } } /** * 清除用户的关系缓存 * * @param int $userId 用户ID * @return bool */ public function clearUserRelationCache(int $userId): bool { try { // 删除数据库中的关系缓存 PromotionUserRelationCache::where('user_id', $userId)->delete(); // 清除Redis缓存 Redis::del("promotion:user:{$userId}:all_referrers"); return true; } catch (\Exception $e) { Log::error("清除用户关系缓存失败: " . $e->getMessage()); return false; } } /** * 重建所有用户的关系缓存 * * @param int $batchSize 批处理大小 * @return array 包含成功和失败的数量 */ public function rebuildAllRelationCache(int $batchSize = 100): array { try { // 清空关系缓存表 PromotionUserRelationCache::truncate(); // 清除所有Redis缓存 $keys = Redis::keys("promotion:user:*:all_referrers"); if (!empty($keys)) { Redis::del($keys); } // 获取所有用户ID $userIds = PromotionUserReferral::pluck('user_id')->toArray(); $successCount = 0; $failCount = 0; // 分批处理 $chunks = array_chunk($userIds, $batchSize); foreach ($chunks as $chunk) { foreach ($chunk as $userId) { if ($this->generateUserRelationCache($userId)) { $successCount++; } else { $failCount++; } } } return [ 'success' => $successCount, 'fail' => $failCount, 'total' => count($userIds) ]; } catch (\Exception $e) { Log::error("重建所有关系缓存失败: " . $e->getMessage()); return [ 'success' => 0, 'fail' => 0, 'total' => 0, 'error' => $e->getMessage() ]; } } /** * 检查关系缓存的完整性 * * @return array 包含检查结果 */ public function checkRelationCacheIntegrity(): array { try { $totalUsers = PromotionUserReferral::count(); $usersWithCache = PromotionUserRelationCache::distinct('user_id')->count('user_id'); $missingUsers = $totalUsers - $usersWithCache; $circularRelations = DB::select(" SELECT r1.user_id, r1.referrer_id FROM promotion_user_referrals r1 JOIN promotion_user_referrals r2 ON r1.referrer_id = r2.user_id WHERE r2.referrer_id = r1.user_id "); $orphanedCaches = DB::select(" SELECT c.user_id FROM promotion_user_relation_cache c LEFT JOIN promotion_user_referrals r ON c.user_id = r.user_id WHERE r.user_id IS NULL "); return [ 'total_users' => $totalUsers, 'users_with_cache' => $usersWithCache, 'missing_users' => $missingUsers, 'circular_relations' => count($circularRelations), 'orphaned_caches' => count($orphanedCaches) ]; } catch (\Exception $e) { Log::error("检查关系缓存完整性失败: " . $e->getMessage()); return [ 'error' => $e->getMessage() ]; } } /** * 修复关系缓存问题 * * @return array 包含修复结果 */ public function fixRelationCacheIssues(): array { try { // 检查完整性 $integrity = $this->checkRelationCacheIntegrity(); $fixed = [ 'missing_users' => 0, 'orphaned_caches' => 0 ]; // 修复缺失的用户缓存 if ($integrity['missing_users'] > 0) { $usersWithCache = PromotionUserRelationCache::distinct('user_id')->pluck('user_id')->toArray(); $allUsers = PromotionUserReferral::pluck('user_id')->toArray(); $missingUsers = array_diff($allUsers, $usersWithCache); foreach ($missingUsers as $userId) { if ($this->generateUserRelationCache($userId)) { $fixed['missing_users']++; } } } // 清理孤立的缓存 if ($integrity['orphaned_caches'] > 0) { $orphanedCaches = DB::select(" SELECT c.user_id FROM promotion_user_relation_cache c LEFT JOIN promotion_user_referrals r ON c.user_id = r.user_id WHERE r.user_id IS NULL "); foreach ($orphanedCaches as $cache) { if ($this->clearUserRelationCache($cache->user_id)) { $fixed['orphaned_caches']++; } } } return [ 'integrity' => $integrity, 'fixed' => $fixed ]; } catch (\Exception $e) { Log::error("修复关系缓存问题失败: " . $e->getMessage()); return [ 'error' => $e->getMessage() ]; } } }