Prechádzať zdrojové kódy

完成URS推广模块与Farm模块集成

- 新增CropHarvestedListener监听Farm收获事件
- 修复UrsProfitLogic中字段结构适配问题
- 更新UrsPromotionServiceProvider注册事件监听器
- 新增TestFarmIntegrationCommand集成测试命令
- 验证种植收益自动分发功能正常工作
- 更新开发文档记录集成完成状态
notfff 7 mesiacov pred
rodič
commit
dc8e9bedc3

+ 232 - 0
app/Module/UrsPromotion/Commands/TestFarmIntegrationCommand.php

@@ -0,0 +1,232 @@
+<?php
+
+namespace App\Module\UrsPromotion\Commands;
+
+use Illuminate\Console\Command;
+use App\Module\Farm\Events\CropHarvestedEvent;
+use App\Module\Farm\Models\FarmLand;
+use App\Module\Farm\Models\FarmCrop;
+use App\Module\Farm\Models\FarmHarvestLog;
+use App\Module\UrsPromotion\Models\UrsUserReferral;
+use App\Module\UrsPromotion\Models\UrsUserTalent;
+use App\Module\UrsPromotion\Models\UrsTalentConfig;
+use App\Module\UrsPromotion\Models\UrsProfit;
+use App\Module\UrsPromotion\Enums\UrsProfitType;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * 测试Farm模块与UrsPromotion模块集成
+ */
+class TestFarmIntegrationCommand extends Command
+{
+    /**
+     * 命令签名
+     *
+     * @var string
+     */
+    protected $signature = 'urs:test-farm-integration {--clean : 清理测试数据}';
+
+    /**
+     * 命令描述
+     *
+     * @var string
+     */
+    protected $description = '测试Farm模块与UrsPromotion模块的事件集成';
+
+    /**
+     * 执行命令
+     */
+    public function handle(): int
+    {
+        if ($this->option('clean')) {
+            $this->cleanTestData();
+            $this->info('测试数据清理完成');
+            return 0;
+        }
+
+        $this->info('开始测试Farm模块与UrsPromotion模块集成...');
+
+        try {
+            // 1. 准备测试数据
+            $this->info('1. 准备测试数据...');
+            $testData = $this->prepareTestData();
+
+            // 2. 模拟Farm收获事件
+            $this->info('2. 模拟Farm收获事件...');
+            $this->simulateHarvestEvent($testData);
+
+            // 3. 验证URS收益分发
+            $this->info('3. 验证URS收益分发...');
+            $this->verifyProfitDistribution($testData);
+
+            $this->info('✅ Farm模块与UrsPromotion模块集成测试通过!');
+            return 0;
+
+        } catch (\Exception $e) {
+            $this->error('❌ 集成测试失败: ' . $e->getMessage());
+            $this->error('错误详情: ' . $e->getTraceAsString());
+            return 1;
+        }
+    }
+
+    /**
+     * 准备测试数据
+     */
+    private function prepareTestData(): array
+    {
+        DB::beginTransaction();
+
+        try {
+            // 创建测试用户推荐关系
+            $userId = 3001; // 收获用户
+            $directReferrerId = 3002; // 直推
+            $indirectReferrerId = 3003; // 间推
+
+            // 清理可能存在的测试数据
+            UrsUserReferral::whereIn('user_id', [$userId, $directReferrerId])->delete();
+            UrsUserTalent::whereIn('user_id', [$userId, $directReferrerId, $indirectReferrerId])->delete();
+            UrsProfit::where('source_type', 'farm_harvest_test')->delete();
+
+            // 创建推荐关系:3003 -> 3002 -> 3001
+            UrsUserReferral::create([
+                'user_id' => $directReferrerId,
+                'referrer_id' => $indirectReferrerId,
+                'referral_code' => 'TEST_' . $indirectReferrerId,
+                'direct_count' => 1,
+                'indirect_count' => 0,
+                'third_count' => 0,
+            ]);
+
+            UrsUserReferral::create([
+                'user_id' => $userId,
+                'referrer_id' => $directReferrerId,
+                'referral_code' => 'TEST_' . $directReferrerId,
+                'direct_count' => 0,
+                'indirect_count' => 0,
+                'third_count' => 0,
+            ]);
+
+            // 创建达人等级
+            UrsUserTalent::create([
+                'user_id' => $directReferrerId,
+                'talent_level' => 1, // 初级达人
+                'direct_count' => 1,
+                'indirect_count' => 0,
+                'third_count' => 0,
+                'total_count' => 1,
+            ]);
+
+            UrsUserTalent::create([
+                'user_id' => $indirectReferrerId,
+                'talent_level' => 2, // 中级达人
+                'direct_count' => 1,
+                'indirect_count' => 1,
+                'third_count' => 0,
+                'total_count' => 2,
+            ]);
+
+            // 创建模拟的Farm数据
+            $mockLand = new FarmLand();
+            $mockLand->id = 9999;
+            $mockLand->user_id = $userId;
+
+            $mockCrop = new FarmCrop();
+            $mockCrop->id = 9999;
+            $mockCrop->user_id = $userId;
+
+            $mockHarvestLog = new FarmHarvestLog();
+            $mockHarvestLog->id = 9999;
+            $mockHarvestLog->user_id = $userId;
+            $mockHarvestLog->crop_id = $mockCrop->id;
+
+            DB::commit();
+
+            $this->info("   - 创建推荐关系: {$indirectReferrerId} -> {$directReferrerId} -> {$userId}");
+            $this->info("   - 设置达人等级: 用户{$directReferrerId}=初级达人, 用户{$indirectReferrerId}=中级达人");
+
+            return [
+                'user_id' => $userId,
+                'direct_referrer_id' => $directReferrerId,
+                'indirect_referrer_id' => $indirectReferrerId,
+                'mock_land' => $mockLand,
+                'mock_crop' => $mockCrop,
+                'mock_harvest_log' => $mockHarvestLog,
+                'output_amount' => 1000,
+            ];
+
+        } catch (\Exception $e) {
+            DB::rollBack();
+            throw $e;
+        }
+    }
+
+    /**
+     * 模拟Farm收获事件
+     */
+    private function simulateHarvestEvent(array $testData): void
+    {
+        $event = new CropHarvestedEvent(
+            $testData['user_id'],
+            $testData['mock_land'],
+            $testData['mock_crop'],
+            $testData['mock_harvest_log'],
+            1001, // 输出物品ID
+            $testData['output_amount']
+        );
+
+        // 触发事件
+        event($event);
+
+        $this->info("   - 触发收获事件: 用户{$testData['user_id']}收获{$testData['output_amount']}个物品");
+    }
+
+    /**
+     * 验证收益分发
+     */
+    private function verifyProfitDistribution(array $testData): void
+    {
+        // 等待事件处理完成
+        sleep(1);
+
+        // 查询生成的收益记录
+        $profits = UrsProfit::where('source_type', 'farm_harvest')
+            ->where('source_id', $testData['mock_harvest_log']->id)
+            ->where('profit_type', UrsProfitType::PLANTING_REWARD->value)
+            ->get();
+
+        $this->info("   - 生成收益记录数量: " . $profits->count());
+
+        if ($profits->isEmpty()) {
+            throw new \Exception('未生成任何收益记录');
+        }
+
+        foreach ($profits as $profit) {
+            $this->info("   - 收益记录: 用户{$profit->user_id}, 层级{$profit->relation_level}, 金额{$profit->profit_amount}, 比例{$profit->profit_rate}");
+        }
+
+        // 验证收益记录的正确性
+        $directProfit = $profits->where('user_id', $testData['direct_referrer_id'])->first();
+        $indirectProfit = $profits->where('user_id', $testData['indirect_referrer_id'])->first();
+
+        if (!$directProfit) {
+            throw new \Exception('直推收益记录不存在');
+        }
+
+        if (!$indirectProfit) {
+            throw new \Exception('间推收益记录不存在');
+        }
+
+        $this->info("   ✅ 直推收益: {$directProfit->profit_amount} (比例: {$directProfit->profit_rate})");
+        $this->info("   ✅ 间推收益: {$indirectProfit->profit_amount} (比例: {$indirectProfit->profit_rate})");
+    }
+
+    /**
+     * 清理测试数据
+     */
+    private function cleanTestData(): void
+    {
+        UrsUserReferral::whereIn('user_id', [3001, 3002])->delete();
+        UrsUserTalent::whereIn('user_id', [3001, 3002, 3003])->delete();
+        UrsProfit::where('source_type', 'farm_harvest')->where('source_id', 9999)->delete();
+    }
+}

+ 62 - 0
app/Module/UrsPromotion/Listeners/CropHarvestedListener.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Module\UrsPromotion\Listeners;
+
+use App\Module\Farm\Events\CropHarvestedEvent;
+use App\Module\UrsPromotion\Services\UrsProfitService;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * Farm收获事件监听器
+ * 
+ * 监听Farm模块的作物收获事件,自动分发URS种植收益
+ */
+class CropHarvestedListener
+{
+    /**
+     * 处理作物收获事件
+     *
+     * @param CropHarvestedEvent $event
+     * @return void
+     */
+    public function handle(CropHarvestedEvent $event): void
+    {
+        try {
+            Log::info('收到Farm收获事件,开始处理URS种植收益分发', [
+                'user_id' => $event->userId,
+                'land_id' => $event->land->id,
+                'crop_id' => $event->crop->id,
+                'output_item_id' => $event->outputItemId,
+                'output_amount' => $event->outputAmount,
+                'harvest_log_id' => $event->harvestLog->id,
+            ]);
+
+            // 调用URS收益分发服务
+            // 使用收获记录ID作为source_id,便于追溯
+            $profits = UrsProfitService::distributePlantingReward(
+                $event->userId,
+                'farm_harvest',
+                $event->harvestLog->id,
+                (string)$event->outputAmount
+            );
+
+            Log::info('URS种植收益分发完成', [
+                'user_id' => $event->userId,
+                'harvest_log_id' => $event->harvestLog->id,
+                'profit_count' => count($profits),
+                'total_distributed' => array_sum(array_column($profits, 'profit_amount')),
+            ]);
+
+        } catch (\Exception $e) {
+            Log::error('处理Farm收获事件失败', [
+                'user_id' => $event->userId,
+                'harvest_log_id' => $event->harvestLog->id ?? null,
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString(),
+            ]);
+            
+            // 不抛出异常,避免影响Farm模块的正常流程
+            // 收益分发失败不应该影响用户的收获操作
+        }
+    }
+}

+ 20 - 10
app/Module/UrsPromotion/Logics/UrsProfitLogic.php

@@ -343,12 +343,17 @@ class UrsProfitLogic
      */
     private function getPromotionRewardGroupId(array $config, int $relationLevel): ?int
     {
-        $groups = $config['promotion_reward_groups'] ?? [];
-        if (is_string($groups)) {
-            $groups = json_decode($groups, true) ?? [];
+        // 使用新的独立字段结构
+        switch ($relationLevel) {
+            case 1: // 直推
+                return $config['promotion_direct_group'] ?? null;
+            case 2: // 间推
+                return $config['promotion_indirect_group'] ?? null;
+            case 3: // 三推
+                return $config['promotion_third_group'] ?? null;
+            default:
+                return null;
         }
-
-        return $groups[$relationLevel] ?? null;
     }
 
     /**
@@ -360,12 +365,17 @@ class UrsProfitLogic
      */
     private function getPlantingRewardRate(array $config, int $relationLevel): float
     {
-        $rates = $config['planting_reward_rates'] ?? [];
-        if (is_string($rates)) {
-            $rates = json_decode($rates, true) ?? [];
+        // 使用新的独立字段结构
+        switch ($relationLevel) {
+            case 1: // 直推
+                return (float)($config['planting_direct_rate'] ?? 0);
+            case 2: // 间推
+                return (float)($config['planting_indirect_rate'] ?? 0);
+            case 3: // 三推
+                return (float)($config['planting_third_rate'] ?? 0);
+            default:
+                return 0;
         }
-
-        return (float)($rates[$relationLevel] ?? 0);
     }
 
     /**

+ 21 - 0
app/Module/UrsPromotion/Providers/UrsPromotionServiceProvider.php

@@ -4,12 +4,24 @@ namespace App\Module\UrsPromotion\Providers;
 
 use Illuminate\Support\ServiceProvider;
 use Illuminate\Console\Scheduling\Schedule;
+use App\Module\Farm\Events\CropHarvestedEvent;
+use App\Module\UrsPromotion\Listeners\CropHarvestedListener;
 
 /**
  * URS推广模块服务提供者
  */
 class UrsPromotionServiceProvider extends ServiceProvider
 {
+    /**
+     * 事件与监听器映射
+     *
+     * @var array
+     */
+    protected $listen = [
+        CropHarvestedEvent::class => [
+            CropHarvestedListener::class,
+        ],
+    ];
     /**
      * 注册服务
      */
@@ -22,6 +34,7 @@ class UrsPromotionServiceProvider extends ServiceProvider
                 \App\Module\UrsPromotion\Commands\TestUrsTalentCommand::class,
                 \App\Module\UrsPromotion\Commands\InsertUrsPromotionAdminMenuCommand::class,
                 \App\Module\UrsPromotion\Commands\UrsPromotionIntegrationTestCommand::class,
+                \App\Module\UrsPromotion\Commands\TestFarmIntegrationCommand::class,
             ]);
         }
     }
@@ -31,6 +44,14 @@ class UrsPromotionServiceProvider extends ServiceProvider
      */
     public function boot(): void
     {
+        // 注册事件监听器
+        $events = $this->app['events'];
+        foreach ($this->listen as $event => $listeners) {
+            foreach ($listeners as $listener) {
+                $events->listen($event, $listener);
+            }
+        }
+
         // 加载API路由
         if (file_exists(__DIR__ . '/../Routes/api.php')) {
             require __DIR__ . '/../Routes/api.php';