团队系统.md 15 KB

团队系统

1. 概述

团队系统是农场模块的重要组成部分,通过推荐关系建立用户间的团队结构,实现收益分成和团队奖励机制。该系统鼓励用户发展团队,共同参与农场种植活动,形成良性的社交生态。

2. 团队结构

2.1 推荐关系

  • 直推关系:用户A直接推荐用户B注册,则用户A是用户B的直推上级
  • 间推关系:用户A推荐用户B,用户B推荐用户C,则用户A是用户C的间推上级
  • 团队成员:用户的所有直推和间推下级构成该用户的团队

2.2 达人等级

团队系统设有达人等级,根据团队规模和活跃度评定:

达人等级 名称 升级条件 奖励权益
1 初级达人 直推5人且团队总人数≥10 团队收益1%分成
2 中级达人 直推10人且团队总人数≥30 团队收益1.5%分成
3 高级达人 直推20人且团队总人数≥50 团队收益2%分成
4 资深达人 直推30人且团队总人数≥100 团队收益2.5%分成
5 顶级达人 直推50人且团队总人数≥200 团队收益3%分成

3. 数据结构

3.1 用户推荐关系表 (farm_user_referrals)

字段名 类型 说明
id bigint 主键ID
user_id bigint 用户ID
referrer_id bigint 推荐人ID
level tinyint 推荐层级(1=直推,2=间推)
created_at timestamp 创建时间
updated_at timestamp 更新时间
CREATE TABLE `farm_user_referrals` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
  `referrer_id` bigint(20) NOT NULL COMMENT '推荐人ID',
  `level` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '推荐层级:1直推,2间推',
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_user_referrer` (`user_id`,`referrer_id`),
  KEY `idx_referrer_id` (`referrer_id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户推荐关系表';

3.2 达人等级表 (farm_user_talents)

字段名 类型 说明
id bigint 主键ID
user_id bigint 用户ID
talent_level tinyint 达人等级(1-5)
direct_count int 直推人数
team_count int 团队总人数
created_at timestamp 创建时间
updated_at timestamp 更新时间
CREATE TABLE `farm_user_talents` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
  `talent_level` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '达人等级:0无,1初级,2中级,3高级,4资深,5顶级',
  `direct_count` int(11) NOT NULL DEFAULT '0' COMMENT '直推人数',
  `team_count` int(11) NOT NULL DEFAULT '0' COMMENT '团队总人数',
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_user_id` (`user_id`),
  KEY `idx_talent_level` (`talent_level`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='达人等级表';

3.3 团队收益记录表 (farm_team_profits)

字段名 类型 说明
id bigint 主键ID
user_id bigint 获得收益的用户ID
team_member_id bigint 团队成员ID
harvest_id bigint 收获记录ID
profit_amount int 分成收益数量
profit_rate decimal 分成比例
created_at timestamp 创建时间
CREATE TABLE `farm_team_profits` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_id` bigint(20) NOT NULL COMMENT '获得收益的用户ID',
  `team_member_id` bigint(20) NOT NULL COMMENT '团队成员ID',
  `harvest_id` bigint(20) NOT NULL COMMENT '收获记录ID',
  `profit_amount` int(11) NOT NULL COMMENT '分成收益数量',
  `profit_rate` decimal(5,4) NOT NULL COMMENT '分成比例',
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_team_member_id` (`team_member_id`),
  KEY `idx_harvest_id` (`harvest_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='团队收益记录表';

4. 核心功能

4.1 推荐关系建立

当新用户注册时,如果填写了推荐人ID,系统会建立推荐关系:

/**
 * 建立推荐关系
 * 
 * @param int $userId 用户ID
 * @param int $referrerId 推荐人ID
 * @return bool 是否成功
 */
public function createReferralRelation(int $userId, int $referrerId): bool
{
    return DB::transaction(function () use ($userId, $referrerId) {
        // 验证用户和推荐人是否存在
        if (!$this->userRepository->exists($userId) || !$this->userRepository->exists($referrerId)) {
            throw new UserNotFoundException("用户或推荐人不存在");
        }
        
        // 验证是否已存在推荐关系
        if ($this->referralRepository->hasReferrer($userId)) {
            throw new ReferralException("用户已有推荐人,不能重复设置");
        }
        
        // 创建直推关系
        $this->referralRepository->create([
            'user_id' => $userId,
            'referrer_id' => $referrerId,
            'level' => 1 // 直推
        ]);
        
        // 更新推荐人的直推人数
        $this->talentRepository->incrementDirectCount($referrerId);
        
        // 获取推荐人的上级
        $upperReferrers = $this->referralRepository->getUpperReferrers($referrerId);
        
        // 创建间推关系
        foreach ($upperReferrers as $upperReferrer) {
            $this->referralRepository->create([
                'user_id' => $userId,
                'referrer_id' => $upperReferrer->referrer_id,
                'level' => 2 // 间推
            ]);
            
            // 更新上级的团队人数
            $this->talentRepository->incrementTeamCount($upperReferrer->referrer_id);
        }
        
        // 更新推荐人的团队人数
        $this->talentRepository->incrementTeamCount($referrerId);
        
        // 检查并更新达人等级
        $this->checkAndUpdateTalentLevel($referrerId);
        foreach ($upperReferrers as $upperReferrer) {
            $this->checkAndUpdateTalentLevel($upperReferrer->referrer_id);
        }
        
        return true;
    });
}

4.2 收获分成计算

当团队成员收获作物时,系统会计算并分配收益给上级:

/**
 * 计算团队收益分成
 * 
 * @param int $userId 收获用户ID
 * @param int $harvestId 收获记录ID
 * @param int $outputAmount 收获产量
 * @return bool 是否成功
 */
public function calculateTeamProfit(int $userId, int $harvestId, int $outputAmount): bool
{
    // 获取用户的所有上级
    $referrers = $this->referralRepository->getUserReferrers($userId);
    
    // 按推荐层级分组
    $directReferrers = [];
    $indirectReferrers = [];
    
    foreach ($referrers as $referrer) {
        if ($referrer->level == 1) {
            $directReferrers[] = $referrer;
        } else {
            $indirectReferrers[] = $referrer;
        }
    }
    
    // 处理直推上级分成
    foreach ($directReferrers as $referrer) {
        // 获取上级的达人等级
        $talentInfo = $this->talentRepository->getByUserId($referrer->referrer_id);
        
        // 计算分成比例和金额
        $profitRate = $this->getDirectProfitRate($talentInfo->talent_level);
        $profitAmount = (int)($outputAmount * $profitRate);
        
        if ($profitAmount > 0) {
            // 记录分成
            $this->teamProfitRepository->create([
                'user_id' => $referrer->referrer_id,
                'team_member_id' => $userId,
                'harvest_id' => $harvestId,
                'profit_amount' => $profitAmount,
                'profit_rate' => $profitRate
            ]);
            
            // 添加收益到上级账户
            $this->itemService->addUserItem(
                $referrer->referrer_id,
                $this->harvestRepository->getOutputItemId($harvestId),
                $profitAmount,
                "团队直推收益"
            );
        }
    }
    
    // 处理间推上级分成
    foreach ($indirectReferrers as $referrer) {
        // 获取上级的达人等级
        $talentInfo = $this->talentRepository->getByUserId($referrer->referrer_id);
        
        // 只有达人才能获得间推收益
        if ($talentInfo->talent_level > 0) {
            // 计算分成比例和金额
            $profitRate = $this->getIndirectProfitRate($talentInfo->talent_level);
            $profitAmount = (int)($outputAmount * $profitRate);
            
            if ($profitAmount > 0) {
                // 记录分成
                $this->teamProfitRepository->create([
                    'user_id' => $referrer->referrer_id,
                    'team_member_id' => $userId,
                    'harvest_id' => $harvestId,
                    'profit_amount' => $profitAmount,
                    'profit_rate' => $profitRate
                ]);
                
                // 添加收益到上级账户
                $this->itemService->addUserItem(
                    $referrer->referrer_id,
                    $this->harvestRepository->getOutputItemId($harvestId),
                    $profitAmount,
                    "团队间推收益"
                );
            }
        }
    }
    
    return true;
}

4.3 达人等级升级

系统会定期检查用户的团队规模,并更新达人等级:

/**
 * 检查并更新达人等级
 * 
 * @param int $userId 用户ID
 * @return bool 是否成功
 */
public function checkAndUpdateTalentLevel(int $userId): bool
{
    // 获取用户当前达人信息
    $talentInfo = $this->talentRepository->getByUserId($userId);
    if (!$talentInfo) {
        // 创建初始达人记录
        $talentInfo = $this->talentRepository->create([
            'user_id' => $userId,
            'talent_level' => 0,
            'direct_count' => 0,
            'team_count' => 0
        ]);
    }
    
    // 获取用户的直推人数和团队总人数
    $directCount = $this->referralRepository->countDirectReferrals($userId);
    $teamCount = $this->referralRepository->countTeamMembers($userId);
    
    // 更新计数
    $this->talentRepository->update($talentInfo->id, [
        'direct_count' => $directCount,
        'team_count' => $teamCount
    ]);
    
    // 计算新的达人等级
    $newLevel = $this->calculateTalentLevel($directCount, $teamCount);
    
    // 如果等级有变化,更新等级
    if ($newLevel != $talentInfo->talent_level) {
        $this->talentRepository->update($talentInfo->id, [
            'talent_level' => $newLevel
        ]);
        
        // 如果是升级,触发达人升级事件
        if ($newLevel > $talentInfo->talent_level) {
            event(new TalentLevelUpEvent($userId, $talentInfo->talent_level, $newLevel));
        }
    }
    
    return true;
}

5. 分成比例设置

5.1 直推分成比例

直推上级可获得团队成员收获产量的固定比例分成:

关系 分成比例
直推 5%

5.2 间推分成比例

间推上级的分成比例取决于达人等级:

达人等级 名称 间推分成比例
0 非达人 0%
1 初级达人 1%
2 中级达人 1.5%
3 高级达人 2%
4 资深达人 2.5%
5 顶级达人 3%

5.3 分成范围限制

  • 直推分成:对所有直推下级的收获都有效
  • 间推分成:仅对20代以内的团队成员有效

6. 业务逻辑实现

6.1 收获事件监听

系统监听作物收获事件,触发团队分成计算:

namespace App\Module\Farm\Listeners;

use App\Module\Farm\Events\CropHarvestedEvent;
use App\Module\Farm\Services\TeamService;

class CropHarvestedListener
{
    /**
     * @var TeamService
     */
    protected $teamService;
    
    /**
     * 构造函数
     */
    public function __construct(TeamService $teamService)
    {
        $this->teamService = $teamService;
    }
    
    /**
     * 处理事件
     */
    public function handle(CropHarvestedEvent $event)
    {
        // 计算团队收益分成
        $this->teamService->calculateTeamProfit(
            $event->userId,
            $event->cropId,
            $event->outputAmount
        );
    }
}

6.2 达人升级事件

当用户达人等级提升时,系统会触发达人升级事件:

namespace App\Module\Farm\Events;

class TalentLevelUpEvent
{
    /**
     * @var int 用户ID
     */
    public $userId;
    
    /**
     * @var int 旧等级
     */
    public $oldLevel;
    
    /**
     * @var int 新等级
     */
    public $newLevel;
    
    /**
     * 构造函数
     */
    public function __construct(int $userId, int $oldLevel, int $newLevel)
    {
        $this->userId = $userId;
        $this->oldLevel = $oldLevel;
        $this->newLevel = $newLevel;
    }
}

7. 前端交互

7.1 团队信息展示

前端应展示用户的团队信息,包括:

  • 达人等级和称号
  • 直推人数和团队总人数
  • 距离下一级达人的差距
  • 团队收益统计

7.2 团队成员管理

前端应提供团队成员管理功能,包括:

  • 查看直推成员列表
  • 查看团队成员列表
  • 查看成员贡献收益

7.3 推荐码生成

前端应提供推荐码生成功能,方便用户分享和邀请新成员:

  • 生成带有用户ID的推荐链接
  • 生成推荐二维码
  • 分享到社交媒体

8. 与其他模块的交互

8.1 与User模块的交互

  • 用户注册时接收推荐人ID
  • 验证推荐人ID的有效性
  • 建立推荐关系

8.2 与GameItems模块的交互

  • 将团队分成收益添加到用户物品库
  • 记录收益来源和分成比例

8.3 与Task模块的交互

  • 达人升级可触发任务完成
  • 发展团队成员可完成特定任务

9. 扩展性考虑

9.1 多级分成

系统设计支持未来扩展为多级分成机制,可根据业务需求调整分成层级和比例。

9.2 团队活跃度

可引入团队活跃度概念,根据团队成员的活跃程度提供额外奖励。

9.3 团队排行榜

可实现团队排行榜功能,展示团队规模、收益等排名,增加竞争性。

10. 总结

团队系统通过推荐关系和收益分成机制,鼓励用户发展团队,形成良性的社交生态。系统设计灵活,支持多级分成和达人等级,可根据业务需求进行扩展和调整。通过与其他模块的紧密集成,团队系统成为农场模块的重要组成部分,为用户提供更丰富的游戏体验。