|
|
@@ -0,0 +1,293 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Module\UrsPromotion\Logics;
|
|
|
+
|
|
|
+use App\Module\UrsPromotion\Services\UrsReferralService;
|
|
|
+use App\Module\UrsPromotion\Services\UrsTalentService;
|
|
|
+use App\Module\UrsPromotion\Models\UrsTalentConfig;
|
|
|
+use App\Module\Game\Services\RewardService;
|
|
|
+use App\Module\Game\Enums\REWARD_SOURCE_TYPE;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
+
|
|
|
+/**
|
|
|
+ * URS推荐奖励补发逻辑层
|
|
|
+ *
|
|
|
+ * 处理用户首次进入农场时的推荐奖励补发核心逻辑
|
|
|
+ */
|
|
|
+class UrsBackfillRewardLogic
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 为用户补发推荐奖励
|
|
|
+ *
|
|
|
+ * @param int $ursUserId URS用户ID
|
|
|
+ * @param int $farmUserId 农场用户ID
|
|
|
+ * @return array 补发结果
|
|
|
+ */
|
|
|
+ public function backfillPromotionReward(int $ursUserId, int $farmUserId): array
|
|
|
+ {
|
|
|
+ // 1. 检查用户是否需要补发奖励
|
|
|
+ if (!$this->needsBackfillReward($ursUserId)) {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '用户无下级或不需要补发奖励',
|
|
|
+ 'backfilled_count' => 0,
|
|
|
+ 'total_subordinates' => 0,
|
|
|
+ 'talent_level' => 0,
|
|
|
+ 'reward_group_id' => 0
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 获取用户下级统计
|
|
|
+ $subordinateStats = $this->getSubordinateStats($ursUserId);
|
|
|
+ $totalSubordinates = $subordinateStats['total_count'];
|
|
|
+
|
|
|
+ if ($totalSubordinates <= 0) {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '用户无下级,无需补发奖励',
|
|
|
+ 'backfilled_count' => 0,
|
|
|
+ 'total_subordinates' => 0,
|
|
|
+ 'talent_level' => 0,
|
|
|
+ 'reward_group_id' => 0
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 获取用户当前达人等级
|
|
|
+ $talentLevel = $this->getUserTalentLevel($ursUserId);
|
|
|
+
|
|
|
+ // 4. 获取对应等级的推荐奖励组配置
|
|
|
+ $rewardGroups = $this->getPromotionRewardGroups($talentLevel);
|
|
|
+
|
|
|
+ if (empty($rewardGroups)) {
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => "达人等级 {$talentLevel} 无对应的奖励组配置",
|
|
|
+ 'backfilled_count' => 0,
|
|
|
+ 'total_subordinates' => $totalSubordinates,
|
|
|
+ 'talent_level' => $talentLevel,
|
|
|
+ 'reward_details' => []
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 按推荐层级分别发放奖励
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ $rewardDetails = [];
|
|
|
+ $totalBackfilledCount = 0;
|
|
|
+
|
|
|
+ // 直推奖励
|
|
|
+ if ($subordinateStats['direct_count'] > 0 && $rewardGroups['direct'] > 0) {
|
|
|
+ $directResult = RewardService::grantReward(
|
|
|
+ $farmUserId,
|
|
|
+ $rewardGroups['direct'],
|
|
|
+ REWARD_SOURCE_TYPE::URSPROMOTION_BACKFILL,
|
|
|
+ $ursUserId,
|
|
|
+ $subordinateStats['direct_count']
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!$directResult->success) {
|
|
|
+ DB::rollBack();
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => "直推奖励发放失败: {$directResult->errorMessage}",
|
|
|
+ 'backfilled_count' => 0,
|
|
|
+ 'total_subordinates' => $totalSubordinates,
|
|
|
+ 'talent_level' => $talentLevel,
|
|
|
+ 'reward_details' => []
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $rewardDetails['direct'] = [
|
|
|
+ 'type' => '直推奖励',
|
|
|
+ 'count' => $subordinateStats['direct_count'],
|
|
|
+ 'reward_group_id' => $rewardGroups['direct'],
|
|
|
+ 'items_count' => count($directResult->items)
|
|
|
+ ];
|
|
|
+ $totalBackfilledCount += count($directResult->items);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 间推奖励
|
|
|
+ if ($subordinateStats['indirect_count'] > 0 && $rewardGroups['indirect'] > 0) {
|
|
|
+ $indirectResult = RewardService::grantReward(
|
|
|
+ $farmUserId,
|
|
|
+ $rewardGroups['indirect'],
|
|
|
+ REWARD_SOURCE_TYPE::URSPROMOTION_BACKFILL,
|
|
|
+ $ursUserId,
|
|
|
+ $subordinateStats['indirect_count']
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!$indirectResult->success) {
|
|
|
+ DB::rollBack();
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => "间推奖励发放失败: {$indirectResult->errorMessage}",
|
|
|
+ 'backfilled_count' => $totalBackfilledCount,
|
|
|
+ 'total_subordinates' => $totalSubordinates,
|
|
|
+ 'talent_level' => $talentLevel,
|
|
|
+ 'reward_details' => $rewardDetails
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $rewardDetails['indirect'] = [
|
|
|
+ 'type' => '间推奖励',
|
|
|
+ 'count' => $subordinateStats['indirect_count'],
|
|
|
+ 'reward_group_id' => $rewardGroups['indirect'],
|
|
|
+ 'items_count' => count($indirectResult->items)
|
|
|
+ ];
|
|
|
+ $totalBackfilledCount += count($indirectResult->items);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 三推奖励
|
|
|
+ if ($subordinateStats['third_count'] > 0 && $rewardGroups['third'] > 0) {
|
|
|
+ $thirdResult = RewardService::grantReward(
|
|
|
+ $farmUserId,
|
|
|
+ $rewardGroups['third'],
|
|
|
+ REWARD_SOURCE_TYPE::URSPROMOTION_BACKFILL,
|
|
|
+ $ursUserId,
|
|
|
+ $subordinateStats['third_count']
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!$thirdResult->success) {
|
|
|
+ DB::rollBack();
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => "三推奖励发放失败: {$thirdResult->errorMessage}",
|
|
|
+ 'backfilled_count' => $totalBackfilledCount,
|
|
|
+ 'total_subordinates' => $totalSubordinates,
|
|
|
+ 'talent_level' => $talentLevel,
|
|
|
+ 'reward_details' => $rewardDetails
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $rewardDetails['third'] = [
|
|
|
+ 'type' => '三推奖励',
|
|
|
+ 'count' => $subordinateStats['third_count'],
|
|
|
+ 'reward_group_id' => $rewardGroups['third'],
|
|
|
+ 'items_count' => count($thirdResult->items)
|
|
|
+ ];
|
|
|
+ $totalBackfilledCount += count($thirdResult->items);
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+
|
|
|
+ Log::info('URS推荐奖励补发成功', [
|
|
|
+ 'urs_user_id' => $ursUserId,
|
|
|
+ 'farm_user_id' => $farmUserId,
|
|
|
+ 'talent_level' => $talentLevel,
|
|
|
+ 'subordinate_stats' => $subordinateStats,
|
|
|
+ 'reward_details' => $rewardDetails,
|
|
|
+ 'total_backfilled_count' => $totalBackfilledCount
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => '推荐奖励补发成功',
|
|
|
+ 'backfilled_count' => $totalBackfilledCount,
|
|
|
+ 'total_subordinates' => $totalSubordinates,
|
|
|
+ 'talent_level' => $talentLevel,
|
|
|
+ 'reward_details' => $rewardDetails
|
|
|
+ ];
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户是否需要补发推荐奖励
|
|
|
+ *
|
|
|
+ * @param int $ursUserId URS用户ID
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function needsBackfillReward(int $ursUserId): bool
|
|
|
+ {
|
|
|
+ // 检查用户是否有下级
|
|
|
+ $subordinateStats = $this->getSubordinateStats($ursUserId);
|
|
|
+ return $subordinateStats['total_count'] > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户的下级统计信息
|
|
|
+ *
|
|
|
+ * @param int $ursUserId URS用户ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function getSubordinateStats(int $ursUserId): array
|
|
|
+ {
|
|
|
+ // 获取直推下级
|
|
|
+ $directReferrals = UrsReferralService::getDirectReferrals($ursUserId);
|
|
|
+ $directCount = count($directReferrals);
|
|
|
+
|
|
|
+ // 获取间推下级(直推的直推)
|
|
|
+ $indirectCount = 0;
|
|
|
+ $indirectReferrals = [];
|
|
|
+ foreach ($directReferrals as $directUserId) {
|
|
|
+ $secondLevelReferrals = UrsReferralService::getDirectReferrals($directUserId);
|
|
|
+ $indirectReferrals = array_merge($indirectReferrals, $secondLevelReferrals);
|
|
|
+ $indirectCount += count($secondLevelReferrals);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取三推下级(间推的直推)
|
|
|
+ $thirdCount = 0;
|
|
|
+ foreach ($indirectReferrals as $indirectUserId) {
|
|
|
+ $thirdLevelReferrals = UrsReferralService::getDirectReferrals($indirectUserId);
|
|
|
+ $thirdCount += count($thirdLevelReferrals);
|
|
|
+ }
|
|
|
+
|
|
|
+ $totalCount = $directCount + $indirectCount + $thirdCount;
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'direct_count' => $directCount,
|
|
|
+ 'indirect_count' => $indirectCount,
|
|
|
+ 'third_count' => $thirdCount,
|
|
|
+ 'total_count' => $totalCount
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户当前达人等级
|
|
|
+ *
|
|
|
+ * @param int $ursUserId URS用户ID
|
|
|
+ * @return int 达人等级,最低为0(青铜级)
|
|
|
+ */
|
|
|
+ private function getUserTalentLevel(int $ursUserId): int
|
|
|
+ {
|
|
|
+ $talentDto = UrsTalentService::getTalentInfo($ursUserId);
|
|
|
+
|
|
|
+ // 如果用户没有达人等级记录,返回最低级(青铜级)
|
|
|
+ if (!$talentDto) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $talentDto->talentLevel;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定达人等级的推荐奖励组配置
|
|
|
+ *
|
|
|
+ * @param int $talentLevel 达人等级
|
|
|
+ * @return array 奖励组配置数组,包含direct、indirect、third三个层级的奖励组ID
|
|
|
+ */
|
|
|
+ private function getPromotionRewardGroups(int $talentLevel): array
|
|
|
+ {
|
|
|
+ $config = UrsTalentConfig::where('level', $talentLevel)
|
|
|
+ ->where('status', UrsTalentConfig::STATUS_ENABLED)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$config) {
|
|
|
+ Log::warning('达人等级配置不存在', [
|
|
|
+ 'talent_level' => $talentLevel
|
|
|
+ ]);
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'direct' => $config->promotion_direct_group ?? 0,
|
|
|
+ 'indirect' => $config->promotion_indirect_group ?? 0,
|
|
|
+ 'third' => $config->promotion_third_group ?? 0,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+}
|