|
|
@@ -46,9 +46,42 @@ class UrsRelationCacheLogic
|
|
|
$farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
|
|
|
$farmReferrerId = UrsUserMappingService::getFarmUserId($ursReferrerId);
|
|
|
|
|
|
- // 如果农场用户ID为0,跳过缓存生成
|
|
|
- if ($farmUserId <= 0 || $farmReferrerId <= 0) {
|
|
|
- Log::info("URS用户 {$ursUserId} 或推荐人 {$ursReferrerId} 未进入农场,跳过缓存生成");
|
|
|
+ // 如果当前用户未进入农场,无法生成缓存
|
|
|
+ if ($farmUserId <= 0) {
|
|
|
+ Log::info("URS用户 {$ursUserId} 未进入农场,跳过缓存生成");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果推荐人未进入农场,创建占位缓存记录,避免断代问题
|
|
|
+ if ($farmReferrerId <= 0) {
|
|
|
+ Log::info("URS用户 {$ursUserId} 的推荐人 {$ursReferrerId} 未进入农场,创建占位缓存记录");
|
|
|
+
|
|
|
+ // 检查是否已存在该深度的缓存记录,避免重复插入
|
|
|
+ $existingCache = UrsUserRelationCache::where('urs_user_id', $ursUserId)
|
|
|
+ ->where('urs_related_user_id', $ursReferrerId)
|
|
|
+ ->where('depth', 1)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$existingCache) {
|
|
|
+ // 创建占位的直接关系缓存(农场用户ID为0)
|
|
|
+ $directRelation = new UrsUserRelationCache();
|
|
|
+ $directRelation->user_id = $farmUserId;
|
|
|
+ $directRelation->related_user_id = 0; // 推荐人未进入农场,设为0
|
|
|
+ $directRelation->urs_user_id = $ursUserId;
|
|
|
+ $directRelation->urs_related_user_id = $ursReferrerId;
|
|
|
+ $directRelation->level = UrsPromotionRelationLevel::DIRECT;
|
|
|
+ $directRelation->path = '0'; // 占位路径
|
|
|
+ $directRelation->urs_path = (string)$ursReferrerId;
|
|
|
+ $directRelation->depth = 1;
|
|
|
+ $directRelation->save();
|
|
|
+ } else {
|
|
|
+ Log::debug("URS用户 {$ursUserId} 的占位缓存记录已存在,跳过创建");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 尝试获取推荐人的上级关系(基于URS关系)
|
|
|
+ $this->generateIndirectRelationsFromUrsChain($ursUserId, $farmUserId, $ursReferrerId, 1);
|
|
|
+
|
|
|
+ Log::info("URS用户 {$ursUserId} 占位缓存记录创建完成");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -105,6 +138,178 @@ class UrsRelationCacheLogic
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 基于URS关系链生成间接关系缓存
|
|
|
+ *
|
|
|
+ * 当推荐人未进入农场时,通过URS推荐关系链向上查找已进入农场的上级
|
|
|
+ *
|
|
|
+ * @param int $ursUserId 当前用户的URS用户ID
|
|
|
+ * @param int $farmUserId 当前用户的农场用户ID
|
|
|
+ * @param int $currentUrsReferrerId 当前层级的URS推荐人ID
|
|
|
+ * @param int $currentDepth 当前深度
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ private function generateIndirectRelationsFromUrsChain(int $ursUserId, int $farmUserId, int $currentUrsReferrerId, int $currentDepth): void
|
|
|
+ {
|
|
|
+ // 限制最大深度为20代
|
|
|
+ if ($currentDepth >= UrsPromotionRelationLevel::getMaxLevel()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前推荐人的推荐人
|
|
|
+ $upperReferral = UrsUserReferral::where('urs_user_id', $currentUrsReferrerId)
|
|
|
+ ->where('status', UrsUserReferral::STATUS_VALID)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$upperReferral) {
|
|
|
+ // 没有更上级的推荐人,结束递归
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $upperUrsReferrerId = $upperReferral->urs_referrer_id;
|
|
|
+ $upperFarmReferrerId = UrsUserMappingService::getFarmUserId($upperUrsReferrerId);
|
|
|
+ $newDepth = $currentDepth + 1;
|
|
|
+
|
|
|
+ if ($upperFarmReferrerId > 0) {
|
|
|
+ // 检查是否已存在该深度的关系缓存
|
|
|
+ $existingCache = UrsUserRelationCache::where('urs_user_id', $ursUserId)
|
|
|
+ ->where('urs_related_user_id', $upperUrsReferrerId)
|
|
|
+ ->where('depth', $newDepth)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$existingCache) {
|
|
|
+ // 上级推荐人已进入农场,创建有效的关系缓存
|
|
|
+ $indirectRelation = new UrsUserRelationCache();
|
|
|
+ $indirectRelation->user_id = $farmUserId;
|
|
|
+ $indirectRelation->related_user_id = $upperFarmReferrerId;
|
|
|
+ $indirectRelation->urs_user_id = $ursUserId;
|
|
|
+ $indirectRelation->urs_related_user_id = $upperUrsReferrerId;
|
|
|
+ $indirectRelation->level = UrsPromotionRelationLevel::getLevelByDepth($newDepth);
|
|
|
+ $indirectRelation->path = $this->buildFarmUserPath($currentUrsReferrerId, $upperFarmReferrerId);
|
|
|
+ $indirectRelation->urs_path = $this->buildUrsPath($currentUrsReferrerId, $upperUrsReferrerId);
|
|
|
+ $indirectRelation->depth = $newDepth;
|
|
|
+ $indirectRelation->save();
|
|
|
+ }
|
|
|
+
|
|
|
+ Log::debug("为URS用户 {$ursUserId} 创建间接关系缓存", [
|
|
|
+ 'upper_urs_referrer_id' => $upperUrsReferrerId,
|
|
|
+ 'upper_farm_referrer_id' => $upperFarmReferrerId,
|
|
|
+ 'depth' => $newDepth
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 继续向上查找,基于已有的关系缓存
|
|
|
+ $this->generateIndirectRelationsFromExistingCache($ursUserId, $farmUserId, $upperUrsReferrerId, $newDepth);
|
|
|
+ } else {
|
|
|
+ // 检查是否已存在该深度的占位缓存
|
|
|
+ $existingCache = UrsUserRelationCache::where('urs_user_id', $ursUserId)
|
|
|
+ ->where('urs_related_user_id', $upperUrsReferrerId)
|
|
|
+ ->where('depth', $newDepth)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$existingCache) {
|
|
|
+ // 上级推荐人也未进入农场,创建占位缓存并继续向上查找
|
|
|
+ $indirectRelation = new UrsUserRelationCache();
|
|
|
+ $indirectRelation->user_id = $farmUserId;
|
|
|
+ $indirectRelation->related_user_id = 0; // 占位
|
|
|
+ $indirectRelation->urs_user_id = $ursUserId;
|
|
|
+ $indirectRelation->urs_related_user_id = $upperUrsReferrerId;
|
|
|
+ $indirectRelation->level = UrsPromotionRelationLevel::getLevelByDepth($newDepth);
|
|
|
+ $indirectRelation->path = $this->buildFarmUserPath($currentUrsReferrerId, 0);
|
|
|
+ $indirectRelation->urs_path = $this->buildUrsPath($currentUrsReferrerId, $upperUrsReferrerId);
|
|
|
+ $indirectRelation->depth = $newDepth;
|
|
|
+ $indirectRelation->save();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 继续向上递归查找
|
|
|
+ $this->generateIndirectRelationsFromUrsChain($ursUserId, $farmUserId, $upperUrsReferrerId, $newDepth);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 基于已有关系缓存生成间接关系
|
|
|
+ *
|
|
|
+ * @param int $ursUserId 当前用户的URS用户ID
|
|
|
+ * @param int $farmUserId 当前用户的农场用户ID
|
|
|
+ * @param int $baseUrsReferrerId 基准URS推荐人ID
|
|
|
+ * @param int $baseDepth 基准深度
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ private function generateIndirectRelationsFromExistingCache(int $ursUserId, int $farmUserId, int $baseUrsReferrerId, int $baseDepth): void
|
|
|
+ {
|
|
|
+ // 获取基准推荐人的所有上级关系缓存
|
|
|
+ $upperRelations = UrsUserRelationCache::where('urs_user_id', $baseUrsReferrerId)
|
|
|
+ ->where('depth', '<', UrsPromotionRelationLevel::getMaxLevel() - $baseDepth)
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ foreach ($upperRelations as $upperRelation) {
|
|
|
+ $newDepth = $baseDepth + $upperRelation->depth;
|
|
|
+
|
|
|
+ // 限制最大深度为20代
|
|
|
+ if ($newDepth > UrsPromotionRelationLevel::getMaxLevel()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否已存在该深度的关系缓存
|
|
|
+ $existingCache = UrsUserRelationCache::where('urs_user_id', $ursUserId)
|
|
|
+ ->where('urs_related_user_id', $upperRelation->urs_related_user_id)
|
|
|
+ ->where('depth', $newDepth)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$existingCache) {
|
|
|
+ $indirectRelation = new UrsUserRelationCache();
|
|
|
+ $indirectRelation->user_id = $farmUserId;
|
|
|
+ $indirectRelation->related_user_id = $upperRelation->related_user_id;
|
|
|
+ $indirectRelation->urs_user_id = $ursUserId;
|
|
|
+ $indirectRelation->urs_related_user_id = $upperRelation->urs_related_user_id;
|
|
|
+ $indirectRelation->level = UrsPromotionRelationLevel::getLevelByDepth($newDepth);
|
|
|
+ $indirectRelation->path = $this->buildCombinedFarmPath($baseUrsReferrerId, $upperRelation->path);
|
|
|
+ $indirectRelation->urs_path = $this->buildCombinedUrsPath($baseUrsReferrerId, $upperRelation->urs_path);
|
|
|
+ $indirectRelation->depth = $newDepth;
|
|
|
+ $indirectRelation->save();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建农场用户路径
|
|
|
+ */
|
|
|
+ private function buildFarmUserPath(int $currentUrsReferrerId, int $upperFarmReferrerId): string
|
|
|
+ {
|
|
|
+ $currentFarmReferrerId = UrsUserMappingService::getFarmUserId($currentUrsReferrerId);
|
|
|
+ $currentPart = $currentFarmReferrerId > 0 ? (string)$currentFarmReferrerId : '0';
|
|
|
+
|
|
|
+ if ($upperFarmReferrerId > 0) {
|
|
|
+ return $currentPart . ',' . $upperFarmReferrerId;
|
|
|
+ }
|
|
|
+ return $currentPart;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建URS用户路径
|
|
|
+ */
|
|
|
+ private function buildUrsPath(int $currentUrsReferrerId, int $upperUrsReferrerId): string
|
|
|
+ {
|
|
|
+ return $currentUrsReferrerId . ',' . $upperUrsReferrerId;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建组合农场用户路径
|
|
|
+ */
|
|
|
+ private function buildCombinedFarmPath(int $baseUrsReferrerId, string $upperPath): string
|
|
|
+ {
|
|
|
+ $baseFarmReferrerId = UrsUserMappingService::getFarmUserId($baseUrsReferrerId);
|
|
|
+ $basePart = $baseFarmReferrerId > 0 ? (string)$baseFarmReferrerId : '0';
|
|
|
+ return $basePart . ',' . $upperPath;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建组合URS用户路径
|
|
|
+ */
|
|
|
+ private function buildCombinedUrsPath(int $baseUrsReferrerId, string $upperUrsPath): string
|
|
|
+ {
|
|
|
+ return $baseUrsReferrerId . ',' . $upperUrsPath;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 清除用户的关系缓存
|
|
|
*
|
|
|
@@ -318,16 +523,31 @@ class UrsRelationCacheLogic
|
|
|
UrsUserRelationCache::where('urs_user_id', $ursUserId)
|
|
|
->update(['user_id' => $farmUserId]);
|
|
|
|
|
|
- // 更新该用户作为推荐人的缓存记录
|
|
|
- UrsUserRelationCache::where('urs_related_user_id', $ursUserId)
|
|
|
+ // 更新该用户作为推荐人的缓存记录(将占位的0更新为实际农场用户ID)
|
|
|
+ $updatedCount = UrsUserRelationCache::where('urs_related_user_id', $ursUserId)
|
|
|
+ ->where('related_user_id', 0) // 只更新占位记录
|
|
|
->update(['related_user_id' => $farmUserId]);
|
|
|
|
|
|
+ if ($updatedCount > 0) {
|
|
|
+ Log::info("更新了 {$updatedCount} 条占位缓存记录", [
|
|
|
+ 'urs_user_id' => $ursUserId,
|
|
|
+ 'farm_user_id' => $farmUserId
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 更新路径中的占位符
|
|
|
+ $this->updatePlaceholderPaths($ursUserId, $farmUserId);
|
|
|
+ }
|
|
|
+
|
|
|
// 重新生成该用户的关系缓存(确保路径正确)
|
|
|
$this->generateUserRelationCache($ursUserId);
|
|
|
|
|
|
+ // 为该用户的所有下级重新生成缓存(修复断代问题)
|
|
|
+ $this->regenerateDownstreamCaches($ursUserId);
|
|
|
+
|
|
|
Log::info("URS用户关系缓存中的农场用户ID更新成功", [
|
|
|
'urs_user_id' => $ursUserId,
|
|
|
- 'farm_user_id' => $farmUserId
|
|
|
+ 'farm_user_id' => $farmUserId,
|
|
|
+ 'updated_placeholder_count' => $updatedCount
|
|
|
]);
|
|
|
|
|
|
return true;
|
|
|
@@ -340,4 +560,95 @@ class UrsRelationCacheLogic
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新路径中的占位符
|
|
|
+ *
|
|
|
+ * @param int $ursUserId URS用户ID
|
|
|
+ * @param int $farmUserId 农场用户ID
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ private function updatePlaceholderPaths(int $ursUserId, int $farmUserId): void
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 获取所有包含该用户的路径记录
|
|
|
+ $records = UrsUserRelationCache::where('urs_path', 'LIKE', "%{$ursUserId}%")->get();
|
|
|
+
|
|
|
+ foreach ($records as $record) {
|
|
|
+ $pathParts = explode(',', $record->path);
|
|
|
+ $ursPathParts = explode(',', $record->urs_path);
|
|
|
+
|
|
|
+ // 找到URS路径中对应的位置,更新农场用户路径
|
|
|
+ $ursIndex = array_search((string)$ursUserId, $ursPathParts);
|
|
|
+ if ($ursIndex !== false && isset($pathParts[$ursIndex]) && $pathParts[$ursIndex] === '0') {
|
|
|
+ $pathParts[$ursIndex] = (string)$farmUserId;
|
|
|
+ $record->path = implode(',', $pathParts);
|
|
|
+ $record->save();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Log::debug("更新路径占位符完成", [
|
|
|
+ 'urs_user_id' => $ursUserId,
|
|
|
+ 'farm_user_id' => $farmUserId,
|
|
|
+ 'updated_records' => $records->count()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::warning("更新路径占位符失败", [
|
|
|
+ 'urs_user_id' => $ursUserId,
|
|
|
+ 'farm_user_id' => $farmUserId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为用户的所有下级重新生成缓存
|
|
|
+ *
|
|
|
+ * 当用户进入农场后,需要为其所有下级重新生成缓存以修复断代问题
|
|
|
+ *
|
|
|
+ * @param int $ursUserId URS用户ID
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ private function regenerateDownstreamCaches(int $ursUserId): void
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 获取该用户的所有直接下级
|
|
|
+ $directSubordinates = UrsUserReferral::where('urs_referrer_id', $ursUserId)
|
|
|
+ ->where('status', UrsUserReferral::STATUS_VALID)
|
|
|
+ ->pluck('urs_user_id')
|
|
|
+ ->toArray();
|
|
|
+
|
|
|
+ if (empty($directSubordinates)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Log::info("开始为用户的下级重新生成缓存", [
|
|
|
+ 'urs_user_id' => $ursUserId,
|
|
|
+ 'subordinate_count' => count($directSubordinates)
|
|
|
+ ]);
|
|
|
+
|
|
|
+ foreach ($directSubordinates as $subordinateUrsUserId) {
|
|
|
+ // 检查下级是否已进入农场
|
|
|
+ $subordinateFarmUserId = UrsUserMappingService::getFarmUserId($subordinateUrsUserId);
|
|
|
+ if ($subordinateFarmUserId > 0) {
|
|
|
+ // 重新生成下级的关系缓存
|
|
|
+ $this->generateUserRelationCache($subordinateUrsUserId);
|
|
|
+
|
|
|
+ // 递归处理下级的下级
|
|
|
+ $this->regenerateDownstreamCaches($subordinateUrsUserId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Log::info("用户下级缓存重新生成完成", [
|
|
|
+ 'urs_user_id' => $ursUserId
|
|
|
+ ]);
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("重新生成下级缓存失败", [
|
|
|
+ 'urs_user_id' => $ursUserId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|