| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- <?php
- namespace App\Module\UrsPromotion\Logics;
- use App\Module\UrsPromotion\Models\UrsUserReferral;
- use App\Module\UrsPromotion\Models\UrsUserTalent;
- use App\Module\UrsPromotion\Models\UrsUserMapping;
- use App\Module\UrsPromotion\Services\UrsUserMappingService;
- use App\Module\UrsPromotion\Services\UrsReferralService;
- use App\Module\UrsPromotion\Logics\UrsRelationCacheLogic;
- use Illuminate\Support\Facades\Log;
- use ThirdParty\Urs\Services\UrsService;
- /**
- * URS推荐关系同步逻辑类
- *
- * 按照文档《URS推荐关系同步机制.md》实现,将同步流程拆分为独立的节点方法,
- * 每个节点功能单一,职责清晰,按顺序调用。
- */
- class UrsReferralSyncLogic
- {
- /**
- * 执行完整的URS推荐关系同步流程
- *
- * @param int $ursUserId URS用户ID
- * @param int $farmUserId 农场用户ID
- * @return bool 是否为首次进入农场(新创建了推荐关系)
- */
- public function syncReferralRelations(int $ursUserId, int $farmUserId): bool
- {
- try {
- Log::info('开始URS推荐关系同步流程', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId
- ]);
- // 1. 创建用户映射
- $this->createUserMapping($ursUserId, $farmUserId);
- // 2. 请求URS获取上级关系
- $teamData = $this->requestUrsTeamRelations($ursUserId);
- if (!$teamData) {
- Log::info('URS用户无上级关系,同步结束', ['urs_user_id' => $ursUserId]);
- return false;
- }
- // 3. 验证和创建推荐关系
- $isFirstEntry = $this->validateAndCreateReferrals($ursUserId, $teamData);
- if (!$isFirstEntry) {
- Log::info('URS用户推荐关系已存在,同步结束', ['urs_user_id' => $ursUserId]);
- return false;
- }
- // 4. 生成关系缓存
- $this->generateRelationCache($ursUserId);
- // 5. 更新团队统计
- $this->updateTeamStatistics($ursUserId, $teamData);
- // 6. 触发事件
- $this->triggerEvents($ursUserId, $farmUserId, $teamData);
- Log::info('URS推荐关系同步流程完成', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId,
- 'is_first_entry' => $isFirstEntry
- ]);
- return $isFirstEntry;
- } catch (\Exception $e) {
- Log::error('URS推荐关系同步流程失败', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return false;
- }
- }
- /**
- * 节点1:创建用户映射
- * 建立URS用户ID与农场用户ID的映射关系
- *
- * @param int $ursUserId URS用户ID
- * @param int $farmUserId 农场用户ID
- * @return void
- */
- private function createUserMapping(int $ursUserId, int $farmUserId): void
- {
- Log::info('节点1:创建用户映射', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId
- ]);
- // 检查映射是否已存在
- $existingMapping = UrsUserMappingService::getFarmUserId($ursUserId);
- if ($existingMapping) {
- Log::info('用户映射已存在', [
- 'urs_user_id' => $ursUserId,
- 'existing_farm_user_id' => $existingMapping,
- 'current_farm_user_id' => $farmUserId
- ]);
- return;
- }
- // 创建新的映射关系
- try {
- UrsUserMappingService::createMapping($ursUserId, $farmUserId);
- Log::info('用户映射创建成功', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId
- ]);
- } catch (\Exception $e) {
- Log::warning('用户映射创建失败', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId,
- 'error' => $e->getMessage()
- ]);
- // 映射创建失败不影响后续流程
- }
- }
- /**
- * 节点2:请求URS获取上级关系
- * 调用URS接口获取20级上级关系数据
- *
- * @param int $ursUserId URS用户ID
- * @return array|null 团队关系数据,失败返回null
- */
- private function requestUrsTeamRelations(int $ursUserId): ?array
- {
- Log::info('节点2:请求URS获取上级关系', ['urs_user_id' => $ursUserId]);
- try {
- $teamResult = UrsService::getUserTeam($ursUserId);
- Log::info('URS团队关系获取结果', [
- 'urs_user_id' => $ursUserId,
- 'success' => $teamResult['success'] ?? false,
- 'has_data' => !empty($teamResult['data']),
- 'team_data' => $teamResult['data'] ?? null
- ]);
- if (!$teamResult['success'] || empty($teamResult['data'])) {
- Log::info('URS用户无上级关系', ['urs_user_id' => $ursUserId]);
- return null;
- }
- return $teamResult['data'];
- } catch (\Exception $e) {
- Log::error('URS团队关系获取失败', [
- 'urs_user_id' => $ursUserId,
- 'error' => $e->getMessage()
- ]);
- return null;
- }
- }
- /**
- * 节点3:验证和创建推荐关系
- * 补充缺失的推荐关系记录(20代关系)
- *
- * @param int $ursUserId URS用户ID
- * @param array $teamData 团队关系数据,格式:['team' => ['1' => 10001, '2' => 10002, ...]]
- * @return bool 是否为首次创建推荐关系
- */
- private function validateAndCreateReferrals(int $ursUserId, array $teamData): bool
- {
- Log::info('节点3:验证和创建推荐关系', [
- 'urs_user_id' => $ursUserId,
- 'team_data_structure' => array_keys($teamData)
- ]);
- // 检查是否已存在推荐关系
- $existingReferral = UrsUserReferral::where('urs_user_id', $ursUserId)->first();
- if ($existingReferral) {
- Log::info('URS用户推荐关系已存在', [
- 'urs_user_id' => $ursUserId,
- 'urs_referrer_id' => $existingReferral->urs_referrer_id
- ]);
- return false;
- }
- // 获取团队关系数据
- $teamRelations = $teamData['team'] ?? [];
- if (empty($teamRelations)) {
- Log::info('URS用户无团队关系数据', [
- 'urs_user_id' => $ursUserId,
- 'team_data' => $teamData
- ]);
- return false;
- }
- Log::info('解析团队关系数据', [
- 'urs_user_id' => $ursUserId,
- 'team_levels' => array_keys($teamRelations),
- 'team_relations_count' => count($teamRelations)
- ]);
- // 获取直接推荐人(一级上级)
- $directReferrerId = $teamRelations['1'] ?? null;
- if (!$directReferrerId) {
- Log::info('URS用户无直接推荐人', [
- 'urs_user_id' => $ursUserId,
- 'team_relations' => $teamRelations
- ]);
- return false;
- }
- try {
- Log::info('开始创建20代推荐关系', [
- 'urs_user_id' => $ursUserId,
- 'direct_referrer_id' => $directReferrerId,
- 'available_levels' => array_keys($teamRelations)
- ]);
- // 检查是否会形成循环推荐(只检查直接推荐人)
- if ($this->wouldCreateCircularReferral($ursUserId, $directReferrerId)) {
- throw new \Exception("不能形成循环推荐关系");
- }
- // 获取农场用户ID(如果已进入农场)
- $farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
- $referrerFarmUserId = UrsUserMappingService::getFarmUserId($directReferrerId);
- // 1. 创建当前用户的直接推荐关系记录
- $referral = UrsUserReferral::create([
- 'urs_user_id' => $ursUserId,
- 'urs_referrer_id' => $directReferrerId,
- 'user_id' => $farmUserId ?: 0,
- 'referrer_id' => $referrerFarmUserId ?: 0,
- 'referral_time' => now(),
- 'status' => UrsUserReferral::STATUS_VALID,
- ]);
- Log::info('直接推荐关系创建成功', [
- 'urs_user_id' => $ursUserId,
- 'urs_referrer_id' => $directReferrerId,
- 'referral_id' => $referral->id
- ]);
- // 2. 为所有20代上级补全下级关系记录
- $createdCount = 1; // 已创建直接关系
- $maxLevel = min(count($teamRelations), 20); // 最多20代
- for ($level = 1; $level <= $maxLevel; $level++) {
- $referrerId = $teamRelations[(string)$level] ?? null;
- if (!$referrerId) {
- continue;
- }
- // 检查该推荐人是否已存在推荐关系记录
- $existingReferrerRecord = UrsUserReferral::where('urs_user_id', $referrerId)->first();
- if ($existingReferrerRecord) {
- Log::debug('第' . $level . '级推荐人已有推荐关系,跳过', [
- 'urs_referrer_id' => $referrerId,
- 'level' => $level
- ]);
- continue;
- }
- // 获取该推荐人的上级(如果存在)
- $upperReferrerId = null;
- if ($level < $maxLevel) {
- $upperReferrerId = $teamRelations[(string)($level + 1)] ?? null;
- }
- if ($upperReferrerId) {
- // 获取推荐人的农场用户ID
- $referrerFarmId = UrsUserMappingService::getFarmUserId($referrerId);
- $upperReferrerFarmId = UrsUserMappingService::getFarmUserId($upperReferrerId);
- // 为该推荐人创建推荐关系记录
- try {
- $upperReferral = UrsUserReferral::create([
- 'urs_user_id' => $referrerId,
- 'urs_referrer_id' => $upperReferrerId,
- 'user_id' => $referrerFarmId ?: 0,
- 'referrer_id' => $upperReferrerFarmId ?: 0,
- 'referral_time' => now(),
- 'status' => UrsUserReferral::STATUS_VALID,
- ]);
- $createdCount++;
- Log::debug('第' . $level . '级推荐人的推荐关系创建成功', [
- 'urs_user_id' => $referrerId,
- 'urs_referrer_id' => $upperReferrerId,
- 'level' => $level,
- 'referral_id' => $upperReferral->id
- ]);
- } catch (\Exception $e) {
- // 如果创建失败(可能是重复),记录日志但不中断流程
- Log::warning('第' . $level . '级推荐人的推荐关系创建失败', [
- 'urs_user_id' => $referrerId,
- 'urs_referrer_id' => $upperReferrerId,
- 'error' => $e->getMessage()
- ]);
- }
- }
- }
- Log::info('20代推荐关系补全完成', [
- 'urs_user_id' => $ursUserId,
- 'created_count' => $createdCount,
- 'max_level' => $maxLevel
- ]);
- return true;
- } catch (\Exception $e) {
- Log::error('推荐关系创建失败', [
- 'urs_user_id' => $ursUserId,
- 'direct_referrer_id' => $directReferrerId,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 节点4:生成关系缓存
- * 创建20级关系缓存
- *
- * @param int $ursUserId URS用户ID
- * @return void
- */
- private function generateRelationCache(int $ursUserId): void
- {
- Log::info('节点4:生成关系缓存', ['urs_user_id' => $ursUserId]);
- try {
- $relationCacheLogic = new UrsRelationCacheLogic();
- $result = $relationCacheLogic->generateUserRelationCache($ursUserId);
- Log::info('关系缓存生成结果', [
- 'urs_user_id' => $ursUserId,
- 'success' => $result
- ]);
- } catch (\Exception $e) {
- Log::error('关系缓存生成失败', [
- 'urs_user_id' => $ursUserId,
- 'error' => $e->getMessage()
- ]);
- // 缓存生成失败不影响主流程
- }
- }
- /**
- * 节点5:更新团队统计
- * 更新推荐人的团队统计数据
- *
- * @param int $ursUserId URS用户ID
- * @param array $teamData 团队关系数据
- * @return void
- */
- private function updateTeamStatistics(int $ursUserId, array $teamData): void
- {
- Log::info('节点5:更新团队统计', ['urs_user_id' => $ursUserId]);
- try {
- // 获取直接推荐人
- $directReferrerId = $teamData['team']['1'] ?? null;
- if (!$directReferrerId) {
- Log::info('无直接推荐人,跳过团队统计更新', ['urs_user_id' => $ursUserId]);
- return;
- }
- // 更新推荐人的团队统计
- $this->updateReferrerTeamStats($directReferrerId);
- Log::info('团队统计更新成功', [
- 'urs_user_id' => $ursUserId,
- 'urs_referrer_id' => $directReferrerId
- ]);
- } catch (\Exception $e) {
- Log::error('团队统计更新失败', [
- 'urs_user_id' => $ursUserId,
- 'error' => $e->getMessage()
- ]);
- // 统计更新失败不影响主流程
- }
- }
- /**
- * 节点6:触发事件
- * 条件触发UrsReferralCreatedEvent事件(双方都进入农场时)
- *
- * @param int $ursUserId URS用户ID
- * @param int $farmUserId 农场用户ID
- * @param array $teamData 团队关系数据
- * @return void
- */
- private function triggerEvents(int $ursUserId, int $farmUserId, array $teamData): void
- {
- Log::info('节点6:触发事件', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId
- ]);
- try {
- // 获取直接推荐人
- $directReferrerId = $teamData['team']['1'] ?? null;
- if (!$directReferrerId) {
- Log::info('无直接推荐人,跳过事件触发', ['urs_user_id' => $ursUserId]);
- return;
- }
- // 获取推荐人的农场用户ID
- $referrerFarmUserId = UrsUserMappingService::getFarmUserId($directReferrerId);
- // 只有双方都进入农场时才触发事件
- if ($farmUserId && $referrerFarmUserId) {
- event(new \App\Module\UrsPromotion\Events\UrsReferralCreatedEvent(
- $farmUserId,
- $referrerFarmUserId,
- null
- ));
- Log::info('URS推荐关系创建事件已触发', [
- 'user_id' => $farmUserId,
- 'referrer_id' => $referrerFarmUserId,
- 'urs_user_id' => $ursUserId,
- 'urs_referrer_id' => $directReferrerId
- ]);
- } else {
- Log::info('URS推荐关系创建但未触发事件(用户未进入农场)', [
- 'urs_user_id' => $ursUserId,
- 'urs_referrer_id' => $directReferrerId,
- 'farm_user_id' => $farmUserId,
- 'referrer_farm_user_id' => $referrerFarmUserId
- ]);
- }
- } catch (\Exception $e) {
- Log::error('事件触发失败', [
- 'urs_user_id' => $ursUserId,
- 'farm_user_id' => $farmUserId,
- 'error' => $e->getMessage()
- ]);
- // 事件触发失败不影响主流程
- }
- }
- /**
- * 检查是否会形成循环推荐
- *
- * @param int $ursUserId URS用户ID
- * @param int $ursReferrerId URS推荐人ID
- * @return bool
- */
- private function wouldCreateCircularReferral(int $ursUserId, int $ursReferrerId): bool
- {
- // 检查推荐人的上级链中是否包含当前用户
- $referrerChain = UrsReferralService::getReferralChain($ursReferrerId);
- return in_array($ursUserId, $referrerChain);
- }
- /**
- * 更新推荐人的团队统计
- *
- * @param int $ursReferrerId URS推荐人ID
- * @return void
- */
- private function updateReferrerTeamStats(int $ursReferrerId): void
- {
- try {
- $farmUserId = UrsUserMapping::getFarmUserIdByUrsUserId($ursReferrerId);
- if (!$farmUserId) {
- Log::info('推荐人未进入农场,跳过团队统计更新', [
- 'urs_referrer_id' => $ursReferrerId
- ]);
- return;
- }
- // 获取团队成员统计(使用配置的团队统计深度)
- $teamMembers = UrsReferralService::getTeamMembers($ursReferrerId);
- $directCount = count($teamMembers[1] ?? []);
- $indirectCount = count($teamMembers[2] ?? []);
- $thirdCount = count($teamMembers[3] ?? []);
- // 计算20代总人数
- $totalCount = 0;
- foreach ($teamMembers as $members) {
- $totalCount += count($members);
- }
- UrsUserTalent::updateOrCreate(
- ['user_id' => $farmUserId],
- [
- 'direct_count' => $directCount,
- 'indirect_count' => $indirectCount,
- 'third_count' => $thirdCount,
- 'promotion_count' => $totalCount, // 现在包含20代总人数
- ]
- );
- Log::info('推荐人团队统计更新成功', [
- 'urs_referrer_id' => $ursReferrerId,
- 'farm_user_id' => $farmUserId,
- 'direct_count' => $directCount,
- 'total_count' => $totalCount
- ]);
- } catch (\Exception $e) {
- Log::error('推荐人团队统计更新失败', [
- 'urs_referrer_id' => $ursReferrerId,
- 'error' => $e->getMessage()
- ]);
- }
- }
- }
|