与Farm模块集成.md 19 KB

团队模块与Farm模块集成

1. 概述

团队模块与Farm模块的集成主要围绕收益分成机制展开,当Farm模块中的用户收获作物时,团队模块会根据用户的推荐关系计算并分配收益给其上级。这种集成通过事件驱动的方式实现,保持了模块间的松耦合,同时提供了灵活的收益分成机制。

2. 集成目标

  1. 收益分成:Farm模块中的作物收获收益按比例分成给推荐人
  2. 达人权益:团队达人等级影响Farm模块中的产出加成
  3. 团队任务:支持团队协作完成Farm模块中的特定任务
  4. 数据统计:统计团队在Farm模块中的活跃度和收益情况
  5. 直间推收益:实现直间推播种收获贡献百分比农作物收益的核心机制

3. 事件驱动集成

3.1 Farm模块触发的事件

Farm模块在作物收获时会触发以下事件:

namespace App\Module\Farm\Events;

class CropHarvestedEvent
{
    /**
     * @var int 用户ID
     */
    public $userId;

    /**
     * @var int 作物ID
     */
    public $cropId;

    /**
     * @var int 土地ID
     */
    public $landId;

    /**
     * @var int 种子ID
     */
    public $seedId;

    /**
     * @var int 产出数量
     */
    public $outputAmount;

    /**
     * 构造函数
     */
    public function __construct(int $userId, int $landId, int $cropId, int $seedId, int $outputAmount)
    {
        $this->userId = $userId;
        $this->landId = $landId;
        $this->cropId = $cropId;
        $this->seedId = $seedId;
        $this->outputAmount = $outputAmount;
    }
}

3.2 Promotion模块的事件监听器

Promotion模块监听Farm模块的作物收获事件,计算并分配收益:

namespace App\Module\Promotion\Listeners;

use App\Module\Farm\Events\CropHarvestedEvent;
use App\Module\Promotion\Services\PromotionProfitService;

class CropHarvestedListener
{
    /**
     * @var PromotionProfitService
     */
    protected $promotionProfitService;

    /**
     * 构造函数
     */
    public function __construct(PromotionProfitService $promotionProfitService)
    {
        $this->promotionProfitService = $promotionProfitService;
    }

    /**
     * 处理事件
     */
    public function handle(CropHarvestedEvent $event)
    {
        // 计算团队收益分成
        $this->promotionProfitService->calculatePromotionProfit(
            $event->userId,
            'farm_harvest',
            $event->cropId,
            $event->seedId, // 作为物品ID
            $event->outputAmount
        );
    }
}

3.3 事件注册

在Promotion模块的服务提供者中注册事件监听器:

namespace App\Module\Promotion\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use App\Module\Farm\Events\CropHarvestedEvent;
use App\Module\Promotion\Listeners\CropHarvestedListener;

class PromotionServiceProvider extends ServiceProvider
{
    /**
     * 事件到监听器的映射
     *
     * @var array
     */
    protected $listen = [
        CropHarvestedEvent::class => [
            CropHarvestedListener::class,
        ],
    ];

    /**
     * 注册服务提供者
     */
    public function register()
    {
        parent::register();

        // 注册服务
    }

    /**
     * 启动服务提供者
     */
    public function boot()
    {
        parent::boot();

        // 启动服务
    }
}

4. 收益分成机制

4.1 分成规则配置

Promotion模块为Farm模块的收获收益配置专门的分成规则:

INSERT INTO `promotion_profit_rules` (`source_type`, `direct_profit_rate`, `max_indirect_level`, `status`, `rules`) VALUES
('farm_harvest', 0.0500, 20, 1, '{"min_amount": 10, "max_amount": 1000}');

4.2 分成计算逻辑

当用户收获作物时,Promotion模块按以下逻辑计算分成:

/**
 * 计算团队收益分成
 */
public function calculatePromotionProfit(int $userId, string $sourceType, int $sourceId, int $itemId, int $amount): bool
{
    // 获取分成规则
    $rule = $this->profitRuleRepository->getBySourceType($sourceType);
    if (!$rule || $rule->status != 1) {
        return false;
    }

    // 验证收益数量
    $rules = json_decode($rule->rules, true);
    if (isset($rules['min_amount']) && $amount < $rules['min_amount']) {
        return false;
    }
    if (isset($rules['max_amount']) && $amount > $rules['max_amount']) {
        return false;
    }

    // 获取用户的所有上级
    $referrers = $this->referralRepository->getUserReferrers($userId);

    // 按推荐层级分组
    $directReferrers = [];
    $indirectReferrers = [];

    foreach ($referrers as $referrer) {
        if ($referrer->level == 1) {
            $directReferrers[] = $referrer;
        } else {
            $indirectReferrers[] = $referrer;
        }
    }

    // 处理直推上级分成
    foreach ($directReferrers as $referrer) {
        // 计算分成比例和金额
        $profitRate = $rule->direct_profit_rate;
        $profitAmount = (int)($amount * $profitRate);

        if ($profitAmount > 0) {
            // 记录分成
            $this->promotionProfitRepository->create([
                'user_id' => $referrer->referrer_id,
                'promotion_member_id' => $userId,
                'source_id' => $sourceId,
                'source_type' => $sourceType,
                'item_id' => $itemId,
                'profit_amount' => $profitAmount,
                'profit_rate' => $profitRate
            ]);

            // 添加收益到上级账户
            $this->itemService->addUserItem(
                $referrer->referrer_id,
                $itemId,
                $profitAmount,
                "团队直推收益"
            );
        }
    }

    // 处理间推上级分成
    foreach ($indirectReferrers as $referrer) {
        // 获取上级的达人等级
        $talentInfo = $this->talentRepository->getByUserId($referrer->referrer_id);

        // 只有达人才能获得间推收益
        if ($talentInfo && $talentInfo->talent_level > 0) {
            // 计算分成比例和金额
            $profitRate = $this->talentService->getTalentProfitRate($talentInfo->talent_level);
            $profitAmount = (int)($amount * $profitRate);

            if ($profitAmount > 0) {
                // 记录分成
                $this->promotionProfitRepository->create([
                    'user_id' => $referrer->referrer_id,
                    'promotion_member_id' => $userId,
                    'source_id' => $sourceId,
                    'source_type' => $sourceType,
                    'item_id' => $itemId,
                    'profit_amount' => $profitAmount,
                    'profit_rate' => $profitRate
                ]);

                // 添加收益到上级账户
                $this->itemService->addUserItem(
                    $referrer->referrer_id,
                    $itemId,
                    $profitAmount,
                    "团队间推收益"
                );
            }
        }
    }

    return true;
}

4.3 分成比例

Farm模块的收获收益分成比例如下:

关系 达人等级 分成比例
直推 任意 5%
间推 非达人 0%
间推 初级达人 1%
间推 中级达人 1.5%
间推 高级达人 2%
间推 资深达人 2.5%
间推 顶级达人 3%

5. 达人权益在Farm模块中的应用

5.1 产出加成

达人等级可以为Farm模块中的作物产量提供加成:

/**
 * 计算达人产出加成
 */
public function calculateTalentOutputBonus(int $userId): float
{
    // 获取用户达人信息
    $talentInfo = $this->talentRepository->getByUserId($userId);
    if (!$talentInfo || $talentInfo->talent_level == 0) {
        return 0.0;
    }

    // 获取达人等级配置
    $talentConfig = $this->talentConfigRepository->getByLevel($talentInfo->talent_level);
    if (!$talentConfig) {
        return 0.0;
    }

    // 获取产出加成
    $benefits = json_decode($talentConfig->benefits, true);
    return $benefits['farm_output_bonus'] ?? 0.0;
}

Farm模块在计算作物产量时,调用Promotion模块的接口获取达人加成:

/**
 * 计算作物的最终产量
 */
public function calculateOutput(FarmCrop $crop, FarmLand $land, int $houseLevel): int
{
    // 获取种子配置
    $seedConfig = $this->seedRepository->find($crop->seed_id);

    // 随机生成基础产量
    $baseOutput = rand($seedConfig->min_output, $seedConfig->max_output);

    // 计算土地加成
    $landBonus = $this->landLogic->calculateOutputBonus($land);

    // 计算房屋加成
    $houseBonus = $this->houseLogic->calculateOutputBonus($houseLevel);

    // 计算灾害减产
    $disasterImpact = $this->disasterLogic->calculateDisasterImpact($crop->disasters);

    // 计算达人加成
    $talentBonus = $this->promotionService->calculateTalentOutputBonus($crop->user_id);

    // 计算最终产量
    $finalOutput = $baseOutput * (1 + $landBonus) * (1 + $houseBonus) * (1 - $disasterImpact) * (1 + $talentBonus);

    // 应用产量限制
    $finalOutput = max(1000, min($finalOutput, 3000));

    return (int)$finalOutput;
}

5.2 达人每日礼包

达人可以在Farm模块中领取每日礼包:

/**
 * 领取达人每日礼包
 */
public function claimTalentDailyGift(int $userId): array
{
    // 获取用户达人信息
    $talentInfo = $this->talentRepository->getByUserId($userId);
    if (!$talentInfo || $talentInfo->talent_level == 0) {
        throw new TalentException("用户不是达人,无法领取礼包");
    }

    // 检查今日是否已领取
    if ($this->hasClaimed($userId)) {
        throw new TalentException("今日已领取礼包");
    }

    // 获取达人等级配置
    $talentConfig = $this->talentConfigRepository->getByLevel($talentInfo->talent_level);
    if (!$talentConfig) {
        throw new TalentException("达人等级配置不存在");
    }

    // 获取礼包内容
    $benefits = json_decode($talentConfig->benefits, true);
    $gift = $benefits['daily_gift'] ?? null;

    if (!$gift) {
        throw new TalentException("该等级达人没有每日礼包");
    }

    // 添加礼包物品到用户背包
    $this->itemService->addUserItem(
        $userId,
        $gift['item_id'],
        $gift['amount'],
        "达人每日礼包"
    );

    // 记录领取记录
    $this->talentGiftRepository->create([
        'user_id' => $userId,
        'talent_level' => $talentInfo->talent_level,
        'item_id' => $gift['item_id'],
        'amount' => $gift['amount'],
        'claim_date' => date('Y-m-d')
    ]);

    return [
        'item_id' => $gift['item_id'],
        'amount' => $gift['amount']
    ];
}

6. 团队任务系统

6.1 团队种植任务

Promotion模块可以创建团队种植任务,鼓励团队成员在Farm模块中种植特定作物:

/**
 * 创建团队种植任务
 */
public function createPromotionPlantingTask(int $userId, int $seedId, int $targetCount, int $rewardItemId, int $rewardAmount): array
{
    // 验证用户是否是达人
    $talentInfo = $this->talentRepository->getByUserId($userId);
    if (!$talentInfo || $talentInfo->talent_level < 3) {
        throw new TalentException("只有高级及以上达人才能创建团队任务");
    }

    // 创建团队任务
    $task = $this->promotionTaskRepository->create([
        'creator_id' => $userId,
        'task_type' => 'planting',
        'seed_id' => $seedId,
        'target_count' => $targetCount,
        'current_count' => 0,
        'reward_item_id' => $rewardItemId,
        'reward_amount' => $rewardAmount,
        'status' => 1,
        'expire_time' => now()->addDays(7)
    ]);

    // 返回任务信息
    return [
        'task_id' => $task->id,
        'seed_id' => $seedId,
        'target_count' => $targetCount,
        'reward_item_id' => $rewardItemId,
        'reward_amount' => $rewardAmount,
        'expire_time' => $task->expire_time
    ];
}

6.2 监听种植事件

Promotion模块监听Farm模块的种植事件,更新团队任务进度:

namespace App\Module\Promotion\Listeners;

use App\Module\Farm\Events\CropPlantedEvent;
use App\Module\Promotion\Services\PromotionTaskService;

class CropPlantedListener
{
    /**
     * @var PromotionTaskService
     */
    protected $promotionTaskService;

    /**
     * 构造函数
     */
    public function __construct(PromotionTaskService $promotionTaskService)
    {
        $this->promotionTaskService = $promotionTaskService;
    }

    /**
     * 处理事件
     */
    public function handle(CropPlantedEvent $event)
    {
        // 更新团队种植任务进度
        $this->promotionTaskService->updatePlantingTaskProgress(
            $event->userId,
            $event->seedId
        );
    }
}

7. 数据统计与分析

7.1 团队农场活跃度

Promotion模块统计团队在Farm模块中的活跃度:

/**
 * 统计团队农场活跃度
 */
public function calculatePromotionFarmActivity(int $userId, int $days = 7): array
{
    // 获取团队成员ID列表
    $memberIds = $this->referralRepository->getPromotionMemberIds($userId);

    // 统计种植次数
    $plantCount = $this->farmActivityRepository->countPlantings($memberIds, $days);

    // 统计收获次数
    $harvestCount = $this->farmActivityRepository->countHarvests($memberIds, $days);

    // 统计活跃成员数
    $activeMembers = $this->farmActivityRepository->countActiveMembers($memberIds, $days);

    // 计算人均种植和收获
    $totalMembers = count($memberIds);
    $avgPlant = $totalMembers > 0 ? $plantCount / $totalMembers : 0;
    $avgHarvest = $totalMembers > 0 ? $harvestCount / $totalMembers : 0;

    return [
        'total_members' => $totalMembers,
        'active_members' => $activeMembers,
        'active_rate' => $totalMembers > 0 ? $activeMembers / $totalMembers : 0,
        'plant_count' => $plantCount,
        'harvest_count' => $harvestCount,
        'avg_plant' => $avgPlant,
        'avg_harvest' => $avgHarvest,
        'days' => $days
    ];
}

7.2 团队收益分析

Promotion模块分析团队在Farm模块中的收益情况:

/**
 * 分析团队农场收益
 */
public function analyzePromotionFarmProfit(int $userId, string $timeRange = 'month'): array
{
    // 确定时间范围
    $startTime = $this->getTimeRangeStart($timeRange);

    // 获取团队成员ID列表
    $memberIds = $this->referralRepository->getPromotionMemberIds($userId);

    // 统计总收益
    $totalProfit = $this->farmProfitRepository->sumProfit($memberIds, $startTime);

    // 统计直推收益
    $directProfit = $this->promotionProfitRepository->sumProfit(
        $userId,
        'farm_harvest',
        $startTime,
        1
    );

    // 统计间推收益
    $indirectProfit = $this->promotionProfitRepository->sumProfit(
        $userId,
        'farm_harvest',
        $startTime,
        2
    );

    // 计算收益比例
    $profitRate = $totalProfit > 0 ? ($directProfit + $indirectProfit) / $totalProfit : 0;

    return [
        'total_profit' => $totalProfit,
        'direct_profit' => $directProfit,
        'indirect_profit' => $indirectProfit,
        'profit_rate' => $profitRate,
        'time_range' => $timeRange
    ];
}

8. 集成实现步骤

8.1 前置条件

  1. Farm模块已实现作物收获事件
  2. Promotion模块已实现推荐关系和达人等级系统
  3. 两个模块都已注册到应用中

8.2 实现步骤

  1. 配置事件监听:在Promotion模块中注册监听Farm模块的事件
  2. 实现收益分成:在Promotion模块中实现Farm收益的分成逻辑
  3. 添加达人权益:在Farm模块中调用Promotion模块接口获取达人加成
  4. 实现团队任务:创建和管理与Farm相关的团队任务
  5. 数据统计分析:实现团队在Farm模块中的活跃度和收益分析

8.3 配置示例

config/app.php中注册两个模块的服务提供者:

'providers' => [
    // ...
    App\Module\Farm\Providers\FarmServiceProvider::class,
    App\Module\Promotion\Providers\PromotionServiceProvider::class,
],

9. 测试与验证

9.1 单元测试

为Promotion模块与Farm模块的集成编写单元测试:

/**
 * 测试作物收获事件触发收益分成
 */
public function testCropHarvestedEventTriggersProfitSharing()
{
    // 创建测试用户
    $user1 = factory(User::class)->create();
    $user2 = factory(User::class)->create();

    // 建立推荐关系
    $this->referralService->createReferralRelation($user2->id, $user1->id);

    // 模拟作物收获
    event(new CropHarvestedEvent($user2->id, 1, 1, 1, 100));

    // 验证收益分成
    $profit = $this->promotionProfitRepository->findByConditions([
        'user_id' => $user1->id,
        'promotion_member_id' => $user2->id,
        'source_type' => 'farm_harvest'
    ])->first();

    $this->assertNotNull($profit);
    $this->assertEquals(5, $profit->profit_amount); // 5% of 100
}

9.2 集成测试

测试完整的集成流程:

/**
 * 测试完整的Farm-Promotion集成流程
 */
public function testFarmPromotionIntegrationFlow()
{
    // 创建测试用户
    $user1 = factory(User::class)->create();
    $user2 = factory(User::class)->create();

    // 建立推荐关系
    $this->referralService->createReferralRelation($user2->id, $user1->id);

    // 设置用户1为达人
    $this->talentRepository->create([
        'user_id' => $user1->id,
        'talent_level' => 3,
        'direct_count' => 5,
        'promotion_count' => 10
    ]);

    // 用户2种植作物
    $landId = $this->farmService->createLand($user2->id, 1);
    $seedId = 1;
    $cropId = $this->farmService->plantCrop($user2->id, $landId, $seedId);

    // 模拟作物成熟
    $this->farmService->updateCropToMature($cropId);

    // 用户2收获作物
    $harvestResult = $this->farmService->harvestCrop($user2->id, $cropId);

    // 验证用户1获得分成
    $profit = $this->promotionProfitRepository->findByConditions([
        'user_id' => $user1->id,
        'promotion_member_id' => $user2->id,
        'source_type' => 'farm_harvest'
    ])->first();

    $this->assertNotNull($profit);
    $this->assertEquals(0.05 * $harvestResult['amount'], $profit->profit_amount);

    // 验证用户1物品增加
    $userItem = $this->itemRepository->getUserItem($user1->id, $harvestResult['item_id']);
    $this->assertEquals($profit->profit_amount, $userItem->amount);
}

10. 总结

Promotion模块与Farm模块的集成主要通过事件驱动机制实现,核心功能是收益分成和达人权益。当Farm模块中的用户收获作物时,Promotion模块会根据用户的推荐关系计算并分配收益给其上级。同时,Promotion模块的达人等级系统也为Farm模块提供产出加成,提高达人用户的游戏体验。

这种集成方式保持了模块间的松耦合,同时提供了灵活的收益分成机制,鼓励用户发展团队,形成良性的社交生态。通过团队任务和数据统计分析,进一步增强了两个模块的协同效应,提升了游戏的社交性和粘性。