Your Name 5 сар өмнө
parent
commit
d101fc3397
87 өөрчлөгдсөн 0 нэмэгдсэн , 11422 устгасан
  1. 0 15
      app/Module/Promotion/AdminControllers/Helper/FilterHelper.php
  2. 0 64
      app/Module/Promotion/AdminControllers/Helper/FilterHelperTrait.php
  3. 0 15
      app/Module/Promotion/AdminControllers/Helper/FormHelper.php
  4. 0 76
      app/Module/Promotion/AdminControllers/Helper/FormHelperTrait.php
  5. 0 15
      app/Module/Promotion/AdminControllers/Helper/GridHelper.php
  6. 0 64
      app/Module/Promotion/AdminControllers/Helper/GridHelperTrait.php
  7. 0 15
      app/Module/Promotion/AdminControllers/Helper/ShowHelper.php
  8. 0 64
      app/Module/Promotion/AdminControllers/Helper/ShowHelperTrait.php
  9. 0 133
      app/Module/Promotion/AdminControllers/PromotionInviteRewardController.php
  10. 0 139
      app/Module/Promotion/AdminControllers/PromotionProfitController.php
  11. 0 113
      app/Module/Promotion/AdminControllers/PromotionProfitRuleController.php
  12. 0 127
      app/Module/Promotion/AdminControllers/PromotionReferralChangeController.php
  13. 0 114
      app/Module/Promotion/AdminControllers/PromotionReferralCodeController.php
  14. 0 129
      app/Module/Promotion/AdminControllers/PromotionReferralCodeUsageController.php
  15. 0 127
      app/Module/Promotion/AdminControllers/PromotionTalentConfigController.php
  16. 0 107
      app/Module/Promotion/AdminControllers/PromotionUserReferralController.php
  17. 0 111
      app/Module/Promotion/AdminControllers/PromotionUserRelationCacheController.php
  18. 0 110
      app/Module/Promotion/AdminControllers/PromotionUserTalentController.php
  19. 0 60
      app/Module/Promotion/Commands/CleanExpiredReferralCodesCommand.php
  20. 0 114
      app/Module/Promotion/Commands/RebuildRelationCacheCommand.php
  21. 0 120
      app/Module/Promotion/Commands/UpdateTalentLevelsCommand.php
  22. 0 6
      app/Module/Promotion/Databases/GenerateSql/README.md
  23. 0 26
      app/Module/Promotion/Databases/GenerateSql/team_invite_rewards.sql
  24. 0 19
      app/Module/Promotion/Databases/GenerateSql/team_profit_rules.sql
  25. 0 24
      app/Module/Promotion/Databases/GenerateSql/team_profits.sql
  26. 0 19
      app/Module/Promotion/Databases/GenerateSql/team_referral_changes.sql
  27. 0 25
      app/Module/Promotion/Databases/GenerateSql/team_referral_code_usages.sql
  28. 0 20
      app/Module/Promotion/Databases/GenerateSql/team_referral_codes.sql
  29. 0 20
      app/Module/Promotion/Databases/GenerateSql/team_talent_configs.sql
  30. 0 16
      app/Module/Promotion/Databases/GenerateSql/team_user_referrals.sql
  31. 0 22
      app/Module/Promotion/Databases/GenerateSql/team_user_relation_cache.sql
  32. 0 18
      app/Module/Promotion/Databases/GenerateSql/team_user_talents.sql
  33. 0 61
      app/Module/Promotion/Docs/README.md
  34. 0 197
      app/Module/Promotion/Docs/create.sql
  35. 0 1424
      app/Module/Promotion/Docs/推荐关系系统.md
  36. 0 548
      app/Module/Promotion/Docs/数据库设计.md
  37. 0 342
      app/Module/Promotion/Docs/枚举定义.md
  38. 0 828
      app/Module/Promotion/Docs/模块接口.md
  39. 0 129
      app/Module/Promotion/Docs/直间推收益机制.md
  40. 0 793
      app/Module/Promotion/Docs/缓存策略.md
  41. 0 348
      app/Module/Promotion/Docs/设计概述.md
  42. 0 27
      app/Module/Promotion/Enums/PROFIT_RECORD_STATUS.php
  43. 0 27
      app/Module/Promotion/Enums/PROFIT_SOURCE_TYPE.php
  44. 0 27
      app/Module/Promotion/Enums/REFERRAL_CODE_STATUS.php
  45. 0 21
      app/Module/Promotion/Enums/REFERRAL_LEVEL.php
  46. 0 45
      app/Module/Promotion/Enums/TALENT_LEVEL.php
  47. 0 33
      app/Module/Promotion/Enums/TEAM_TASK_STATUS.php
  48. 0 33
      app/Module/Promotion/Enums/TEAM_TASK_TYPE.php
  49. 0 40
      app/Module/Promotion/Events/PromotionProfitCreatedEvent.php
  50. 0 40
      app/Module/Promotion/Events/ReferralCreatedEvent.php
  51. 0 50
      app/Module/Promotion/Events/ReferralUpdatedEvent.php
  52. 0 58
      app/Module/Promotion/Events/TalentLevelChangedEvent.php
  53. 0 101
      app/Module/Promotion/Listeners/DistributePromotionProfitListener.php
  54. 0 155
      app/Module/Promotion/Listeners/UpdatePromotionCountsListener.php
  55. 0 131
      app/Module/Promotion/Listeners/UpdateTalentLevelListener.php
  56. 0 256
      app/Module/Promotion/Logics/PromotionProfitLogic.php
  57. 0 309
      app/Module/Promotion/Logics/ReferralCodeLogic.php
  58. 0 397
      app/Module/Promotion/Logics/ReferralLogic.php
  59. 0 247
      app/Module/Promotion/Logics/RelationCacheLogic.php
  60. 0 326
      app/Module/Promotion/Logics/TalentLogic.php
  61. 0 104
      app/Module/Promotion/Models/PromotionInviteReward.php
  62. 0 79
      app/Module/Promotion/Models/PromotionProfit.php
  63. 0 69
      app/Module/Promotion/Models/PromotionProfitRule.php
  64. 0 86
      app/Module/Promotion/Models/PromotionReferralChange.php
  65. 0 89
      app/Module/Promotion/Models/PromotionReferralCode.php
  66. 0 86
      app/Module/Promotion/Models/PromotionReferralCodeUsage.php
  67. 0 65
      app/Module/Promotion/Models/PromotionTalentConfig.php
  68. 0 49
      app/Module/Promotion/Models/PromotionUserReferral.php
  69. 0 84
      app/Module/Promotion/Models/PromotionUserRelationCache.php
  70. 0 58
      app/Module/Promotion/Models/PromotionUserTalent.php
  71. 0 84
      app/Module/Promotion/Providers/PromotionServiceProvider.php
  72. 0 156
      app/Module/Promotion/README.md
  73. 0 189
      app/Module/Promotion/Repositorys/BaseRepository.php
  74. 0 18
      app/Module/Promotion/Repositorys/PromotionInviteRewardRepository.php
  75. 0 18
      app/Module/Promotion/Repositorys/PromotionProfitRepository.php
  76. 0 18
      app/Module/Promotion/Repositorys/PromotionProfitRuleRepository.php
  77. 0 18
      app/Module/Promotion/Repositorys/PromotionReferralChangeRepository.php
  78. 0 18
      app/Module/Promotion/Repositorys/PromotionReferralCodeRepository.php
  79. 0 18
      app/Module/Promotion/Repositorys/PromotionReferralCodeUsageRepository.php
  80. 0 18
      app/Module/Promotion/Repositorys/PromotionTalentConfigRepository.php
  81. 0 18
      app/Module/Promotion/Repositorys/PromotionUserReferralRepository.php
  82. 0 18
      app/Module/Promotion/Repositorys/PromotionUserRelationCacheRepository.php
  83. 0 18
      app/Module/Promotion/Repositorys/PromotionUserTalentRepository.php
  84. 0 219
      app/Module/Promotion/Services/PromotionProfitService.php
  85. 0 258
      app/Module/Promotion/Services/ReferralCodeService.php
  86. 0 263
      app/Module/Promotion/Services/ReferralService.php
  87. 0 264
      app/Module/Promotion/Services/TalentService.php

+ 0 - 15
app/Module/Promotion/AdminControllers/Helper/FilterHelper.php

@@ -1,15 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use UCore\DcatAdmin\FilterHelper as BaseFilterHelper;
-
-/**
- * 筛选器辅助类
- *
- * 提供筛选器的辅助方法,如筛选条件的显示、格式化等。
- */
-class FilterHelper extends BaseFilterHelper
-{
-    use FilterHelperTrait;
-}

+ 0 - 64
app/Module/Promotion/AdminControllers/Helper/FilterHelperTrait.php

@@ -1,64 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use App\Module\Promotion\Enums\REFERRAL_CHANGE_REASON;
-use App\Module\Promotion\Enums\REFERRAL_CODE_STATUS;
-use App\Module\Promotion\Enums\REFERRAL_CODE_USAGE_STATUS;
-
-/**
- * 筛选器辅助特性
- *
- * 提供筛选器的辅助方法,如筛选条件的显示、格式化等。
- */
-trait FilterHelperTrait
-{
-    /**
-     * 推荐码状态筛选
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Filter\AbstractFilter
-     */
-    public function equalReferralCodeStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->filter->equal($field, $label)->select(REFERRAL_CODE_STATUS::getOptions());
-    }
-
-    /**
-     * 推荐码使用状态筛选
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Filter\AbstractFilter
-     */
-    public function equalReferralCodeUsageStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->filter->equal($field, $label)->select(REFERRAL_CODE_USAGE_STATUS::getOptions());
-    }
-
-    /**
-     * 推荐关系修改原因筛选
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Filter\AbstractFilter
-     */
-    public function equalReferralChangeReason(string $field = 'reason', string $label = '修改原因')
-    {
-        return $this->filter->equal($field, $label)->select(REFERRAL_CHANGE_REASON::getOptions());
-    }
-
-    /**
-     * 收益来源类型筛选
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Filter\AbstractFilter
-     */
-    public function equalProfitSourceType(string $field = 'source_type', string $label = '来源类型')
-    {
-        return $this->filter->equal($field, $label)->select(PROFIT_SOURCE_TYPE::getOptions());
-    }
-}

+ 0 - 15
app/Module/Promotion/AdminControllers/Helper/FormHelper.php

@@ -1,15 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use UCore\DcatAdmin\FormHelper as BaseFormHelper;
-
-/**
- * 表单页辅助类
- *
- * 提供表单页的辅助方法,如表单项的显示、格式化等。
- */
-class FormHelper extends BaseFormHelper
-{
-    use FormHelperTrait;
-}

+ 0 - 76
app/Module/Promotion/AdminControllers/Helper/FormHelperTrait.php

@@ -1,76 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use App\Module\Promotion\Enums\REFERRAL_CHANGE_REASON;
-use App\Module\Promotion\Enums\REFERRAL_CODE_STATUS;
-use App\Module\Promotion\Enums\REFERRAL_CODE_USAGE_STATUS;
-
-/**
- * 表单页辅助特性
- *
- * 提供表单页的辅助方法,如表单项的显示、格式化等。
- */
-trait FormHelperTrait
-{
-    /**
-     * 推荐码状态选择
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Form\Field\Select
-     */
-    public function selectReferralCodeStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->form->select($field, $label)->options(REFERRAL_CODE_STATUS::getOptions());
-    }
-
-    /**
-     * 推荐码使用状态选择
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Form\Field\Select
-     */
-    public function selectReferralCodeUsageStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->form->select($field, $label)->options(REFERRAL_CODE_USAGE_STATUS::getOptions());
-    }
-
-    /**
-     * 推荐关系修改原因选择
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Form\Field\Select
-     */
-    public function selectReferralChangeReason(string $field = 'reason', string $label = '修改原因')
-    {
-        return $this->form->select($field, $label)->options(REFERRAL_CHANGE_REASON::getOptions());
-    }
-
-    /**
-     * 收益来源类型选择
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Form\Field\Select
-     */
-    public function selectProfitSourceType(string $field = 'source_type', string $label = '来源类型')
-    {
-        return $this->form->select($field, $label)->options(PROFIT_SOURCE_TYPE::getOptions());
-    }
-
-    /**
-     * JSON编辑器
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Form\Field\Editor
-     */
-    public function jsonEditor(string $field, string $label)
-    {
-        return $this->form->editor($field, $label)->language('json');
-    }
-}

+ 0 - 15
app/Module/Promotion/AdminControllers/Helper/GridHelper.php

@@ -1,15 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use UCore\DcatAdmin\GridHelper as BaseGridHelper;
-
-/**
- * 列表页辅助类
- *
- * 提供列表页的辅助方法,如列的显示、格式化等。
- */
-class GridHelper extends BaseGridHelper
-{
-    use GridHelperTrait;
-}

+ 0 - 64
app/Module/Promotion/AdminControllers/Helper/GridHelperTrait.php

@@ -1,64 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use App\Module\Promotion\Enums\REFERRAL_CHANGE_REASON;
-use App\Module\Promotion\Enums\REFERRAL_CODE_STATUS;
-use App\Module\Promotion\Enums\REFERRAL_CODE_USAGE_STATUS;
-
-/**
- * 列表页辅助特性
- *
- * 提供列表页的辅助方法,如列的显示、格式化等。
- */
-trait GridHelperTrait
-{
-    /**
-     * 显示推荐码状态
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Column
-     */
-    public function columnReferralCodeStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->grid->column($field, $label)->using(REFERRAL_CODE_STATUS::getOptions());
-    }
-
-    /**
-     * 显示推荐码使用状态
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Column
-     */
-    public function columnReferralCodeUsageStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->grid->column($field, $label)->using(REFERRAL_CODE_USAGE_STATUS::getOptions());
-    }
-
-    /**
-     * 显示推荐关系修改原因
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Column
-     */
-    public function columnReferralChangeReason(string $field = 'reason', string $label = '修改原因')
-    {
-        return $this->grid->column($field, $label)->using(REFERRAL_CHANGE_REASON::getOptions());
-    }
-
-    /**
-     * 显示收益来源类型
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Grid\Column
-     */
-    public function columnProfitSourceType(string $field = 'source_type', string $label = '来源类型')
-    {
-        return $this->grid->column($field, $label)->using(PROFIT_SOURCE_TYPE::getOptions());
-    }
-}

+ 0 - 15
app/Module/Promotion/AdminControllers/Helper/ShowHelper.php

@@ -1,15 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use UCore\DcatAdmin\ShowHelper as BaseShowHelper;
-
-/**
- * 详情页辅助类
- *
- * 提供详情页的辅助方法,如字段的显示、格式化等。
- */
-class ShowHelper extends BaseShowHelper
-{
-    use ShowHelperTrait;
-}

+ 0 - 64
app/Module/Promotion/AdminControllers/Helper/ShowHelperTrait.php

@@ -1,64 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers\Helper;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use App\Module\Promotion\Enums\REFERRAL_CHANGE_REASON;
-use App\Module\Promotion\Enums\REFERRAL_CODE_STATUS;
-use App\Module\Promotion\Enums\REFERRAL_CODE_USAGE_STATUS;
-
-/**
- * 详情页辅助特性
- *
- * 提供详情页的辅助方法,如字段的显示、格式化等。
- */
-trait ShowHelperTrait
-{
-    /**
-     * 显示推荐码状态
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Show\Field
-     */
-    public function fieldReferralCodeStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->show->field($field, $label)->using(REFERRAL_CODE_STATUS::getOptions());
-    }
-
-    /**
-     * 显示推荐码使用状态
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Show\Field
-     */
-    public function fieldReferralCodeUsageStatus(string $field = 'status', string $label = '状态')
-    {
-        return $this->show->field($field, $label)->using(REFERRAL_CODE_USAGE_STATUS::getOptions());
-    }
-
-    /**
-     * 显示推荐关系修改原因
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Show\Field
-     */
-    public function fieldReferralChangeReason(string $field = 'reason', string $label = '修改原因')
-    {
-        return $this->show->field($field, $label)->using(REFERRAL_CHANGE_REASON::getOptions());
-    }
-
-    /**
-     * 显示收益来源类型
-     *
-     * @param string $field 字段名
-     * @param string $label 标签
-     * @return \Dcat\Admin\Show\Field
-     */
-    public function fieldProfitSourceType(string $field = 'source_type', string $label = '来源类型')
-    {
-        return $this->show->field($field, $label)->using(PROFIT_SOURCE_TYPE::getOptions());
-    }
-}

+ 0 - 133
app/Module/Promotion/AdminControllers/PromotionInviteRewardController.php

@@ -1,133 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionInviteRewardRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 邀请奖励记录管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-invite-rewards', names: 'dcat.admin.promotion-invite-rewards')]
-class PromotionInviteRewardController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '邀请奖励记录管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionInviteRewardRepository(['user', 'invitee']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('user.username', '用户名');
-            $grid->column('user.nickname', '用户昵称');
-            $grid->column('invitee.username', '被邀请人用户名');
-            $grid->column('invitee.nickname', '被邀请人昵称');
-            $grid->column('reward_type', '奖励类型');
-            $grid->column('reward_id', '奖励ID');
-            $grid->column('reward_amount', '奖励数量')->sortable();
-            $grid->column('status', '状态')->switch();
-            $grid->column('remark', '备注');
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->equal('user_id', '用户ID');
-                $filter->whereLike('user.username', '用户名');
-                $filter->whereLike('user.nickname', '用户昵称');
-                $filter->equal('invitee_id', '被邀请人ID');
-                $filter->whereLike('invitee.username', '被邀请人用户名');
-                $filter->whereLike('invitee.nickname', '被邀请人昵称');
-                $filter->equal('reward_type', '奖励类型');
-                $filter->equal('reward_id', '奖励ID');
-                $filter->between('reward_amount', '奖励数量');
-                $filter->equal('status', '状态')->radio([
-                    1 => '已发放',
-                    0 => '未发放',
-                ]);
-                $filter->like('remark', '备注');
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionInviteRewardRepository(['user', 'invitee']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('user_id', '用户ID');
-            $show->field('user.username', '用户名');
-            $show->field('user.nickname', '用户昵称');
-            $show->field('invitee_id', '被邀请人ID');
-            $show->field('invitee.username', '被邀请人用户名');
-            $show->field('invitee.nickname', '被邀请人昵称');
-            $show->field('reward_type', '奖励类型');
-            $show->field('reward_id', '奖励ID');
-            $show->field('reward_amount', '奖励数量');
-            $show->field('status', '状态')->using([
-                1 => '已发放',
-                0 => '未发放',
-            ]);
-            $show->field('remark', '备注');
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionInviteRewardRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('user_id', '用户ID')->required();
-            $form->text('invitee_id', '被邀请人ID')->required();
-            $form->text('reward_type', '奖励类型')->required();
-            $form->text('reward_id', '奖励ID')->required();
-            $form->number('reward_amount', '奖励数量')->min(0)->default(0)->required();
-            $form->switch('status', '状态')->default(0);
-            $form->textarea('remark', '备注');
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 139
app/Module/Promotion/AdminControllers/PromotionProfitController.php

@@ -1,139 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionProfitRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 团队收益记录管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-profits', names: 'dcat.admin.promotion-profits')]
-class PromotionProfitController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '团队收益记录管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionProfitRepository(['user', 'fromUser']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('user.username', '用户名');
-            $grid->column('user.nickname', '用户昵称');
-            $grid->column('from_user_id', '来源用户ID');
-            $grid->column('fromUser.username', '来源用户名');
-            $helper->columnProfitSourceType();
-            $grid->column('source_id', '来源ID');
-            $grid->column('item_id', '物品ID');
-            $grid->column('amount', '数量');
-            $grid->column('profit_rate', '分成比例');
-            $grid->column('level', '层级');
-            $grid->column('is_direct', '是否直推')->bool();
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->equal('user_id', '用户ID');
-                $filter->whereLike('user.username', '用户名');
-                $filter->whereLike('user.nickname', '用户昵称');
-                $filter->equal('from_user_id', '来源用户ID');
-                $filter->whereLike('fromUser.username', '来源用户名');
-                $helper->equalProfitSourceType();
-                $filter->equal('source_id', '来源ID');
-                $filter->equal('item_id', '物品ID');
-                $filter->between('amount', '数量');
-                $filter->between('profit_rate', '分成比例');
-                $filter->equal('level', '层级');
-                $filter->equal('is_direct', '是否直推')->radio([
-                    1 => '是',
-                    0 => '否',
-                ]);
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionProfitRepository(['user', 'fromUser']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('user_id', '用户ID');
-            $show->field('user.username', '用户名');
-            $show->field('user.nickname', '用户昵称');
-            $show->field('from_user_id', '来源用户ID');
-            $show->field('fromUser.username', '来源用户名');
-            $helper->fieldProfitSourceType();
-            $show->field('source_id', '来源ID');
-            $show->field('item_id', '物品ID');
-            $show->field('amount', '数量');
-            $show->field('profit_rate', '分成比例');
-            $show->field('level', '层级');
-            $show->field('is_direct', '是否直推')->using([
-                1 => '是',
-                0 => '否',
-            ]);
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionProfitRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('user_id', '用户ID')->required();
-            $form->text('from_user_id', '来源用户ID')->required();
-            $helper->selectProfitSourceType()->required();
-            $form->text('source_id', '来源ID')->required();
-            $form->text('item_id', '物品ID')->required();
-            $form->number('amount', '数量')->min(0)->default(0)->required();
-            $form->rate('profit_rate', '分成比例')->min(0)->max(1)->default(0)->required();
-            $form->number('level', '层级')->min(1)->default(1)->required();
-            $form->switch('is_direct', '是否直推')->default(0);
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 113
app/Module/Promotion/AdminControllers/PromotionProfitRuleController.php

@@ -1,113 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionProfitRuleRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 收益分成规则管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-profit-rules', names: 'dcat.admin.promotion-profit-rules')]
-class PromotionProfitRuleController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '收益分成规则管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionProfitRuleRepository(), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $helper->columnProfitSourceType();
-            $grid->column('direct_profit_rate', '直推分成比例')->sortable();
-            $grid->column('max_indirect_level', '最大间接层级')->sortable();
-            $grid->column('status', '状态')->switch();
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $helper->equalProfitSourceType();
-                $filter->between('direct_profit_rate', '直推分成比例');
-                $filter->equal('max_indirect_level', '最大间接层级');
-                $filter->equal('status', '状态')->radio([
-                    1 => '启用',
-                    0 => '禁用',
-                ]);
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionProfitRuleRepository(), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $helper->fieldProfitSourceType();
-            $show->field('direct_profit_rate', '直推分成比例');
-            $show->field('max_indirect_level', '最大间接层级');
-            $show->field('rules', '规则配置')->json();
-            $show->field('status', '状态')->using([
-                1 => '启用',
-                0 => '禁用',
-            ]);
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionProfitRuleRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $helper->selectProfitSourceType()->required();
-            $form->rate('direct_profit_rate', '直推分成比例')->min(0)->max(1)->default(0)->required();
-            $form->number('max_indirect_level', '最大间接层级')->min(0)->default(0)->required();
-            $helper->jsonEditor('rules', '规则配置')->help('规则配置,JSON格式');
-            $form->switch('status', '状态')->default(1);
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 127
app/Module/Promotion/AdminControllers/PromotionReferralChangeController.php

@@ -1,127 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionReferralChangeRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 推荐关系修改记录管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-referral-changes', names: 'dcat.admin.promotion-referral-changes')]
-class PromotionReferralChangeController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '推荐关系修改记录管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionReferralChangeRepository(['user', 'oldReferrer', 'newReferrer', 'operator']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('user.username', '用户名');
-            $grid->column('user.nickname', '用户昵称');
-            $grid->column('oldReferrer.username', '旧推荐人用户名');
-            $grid->column('newReferrer.username', '新推荐人用户名');
-            $helper->columnReferralChangeReason();
-            $grid->column('operator.username', '操作人');
-            $grid->column('remark', '备注');
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->equal('user_id', '用户ID');
-                $filter->whereLike('user.username', '用户名');
-                $filter->whereLike('user.nickname', '用户昵称');
-                $filter->equal('old_referrer_id', '旧推荐人ID');
-                $filter->whereLike('oldReferrer.username', '旧推荐人用户名');
-                $filter->equal('new_referrer_id', '新推荐人ID');
-                $filter->whereLike('newReferrer.username', '新推荐人用户名');
-                $helper->equalReferralChangeReason();
-                $filter->equal('operator_id', '操作人ID');
-                $filter->whereLike('operator.username', '操作人用户名');
-                $filter->like('remark', '备注');
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionReferralChangeRepository(['user', 'oldReferrer', 'newReferrer', 'operator']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('user_id', '用户ID');
-            $show->field('user.username', '用户名');
-            $show->field('user.nickname', '用户昵称');
-            $show->field('old_referrer_id', '旧推荐人ID');
-            $show->field('oldReferrer.username', '旧推荐人用户名');
-            $show->field('oldReferrer.nickname', '旧推荐人昵称');
-            $show->field('new_referrer_id', '新推荐人ID');
-            $show->field('newReferrer.username', '新推荐人用户名');
-            $show->field('newReferrer.nickname', '新推荐人昵称');
-            $helper->fieldReferralChangeReason();
-            $show->field('operator_id', '操作人ID');
-            $show->field('operator.username', '操作人用户名');
-            $show->field('operator.nickname', '操作人昵称');
-            $show->field('remark', '备注');
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionReferralChangeRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('user_id', '用户ID')->required();
-            $form->text('old_referrer_id', '旧推荐人ID')->required();
-            $form->text('new_referrer_id', '新推荐人ID')->required();
-            $helper->selectReferralChangeReason()->required();
-            $form->text('operator_id', '操作人ID')->required();
-            $form->textarea('remark', '备注');
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 114
app/Module/Promotion/AdminControllers/PromotionReferralCodeController.php

@@ -1,114 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionReferralCodeRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 推荐码管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-referral-codes', names: 'dcat.admin.promotion-referral-codes')]
-class PromotionReferralCodeController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '推荐码管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionReferralCodeRepository(['user']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('code', '推荐码');
-            $grid->column('user.username', '用户名');
-            $grid->column('user.nickname', '用户昵称');
-            $grid->column('usage_count', '使用次数')->sortable();
-            $helper->columnReferralCodeStatus();
-            $grid->column('expire_time', '过期时间');
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->like('code', '推荐码');
-                $filter->equal('user_id', '用户ID');
-                $filter->whereLike('user.username', '用户名');
-                $filter->whereLike('user.nickname', '用户昵称');
-                $filter->between('usage_count', '使用次数');
-                $helper->equalReferralCodeStatus();
-                $filter->between('expire_time', '过期时间')->datetime();
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionReferralCodeRepository(['user']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('code', '推荐码');
-            $show->field('user_id', '用户ID');
-            $show->field('user.username', '用户名');
-            $show->field('user.nickname', '用户昵称');
-            $show->field('usage_count', '使用次数');
-            $helper->fieldReferralCodeStatus();
-            $show->field('expire_time', '过期时间');
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionReferralCodeRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('code', '推荐码')->required();
-            $form->text('user_id', '用户ID')->required();
-            $form->display('usage_count', '使用次数');
-            $helper->selectReferralCodeStatus()->required();
-            $form->datetime('expire_time', '过期时间');
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 129
app/Module/Promotion/AdminControllers/PromotionReferralCodeUsageController.php

@@ -1,129 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionReferralCodeUsageRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 推荐码使用记录管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-referral-code-usages', names: 'dcat.admin.promotion-referral-code-usages')]
-class PromotionReferralCodeUsageController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '推荐码使用记录管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionReferralCodeUsageRepository(['user', 'codeOwner']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('code', '推荐码');
-            $grid->column('user.username', '使用者用户名');
-            $grid->column('user.nickname', '使用者昵称');
-            $grid->column('codeOwner.username', '码主用户名');
-            $grid->column('codeOwner.nickname', '码主昵称');
-            $grid->column('ip_address', 'IP地址');
-            $helper->columnReferralCodeUsageStatus();
-            $grid->column('result', '使用结果');
-            $grid->column('remark', '备注');
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->like('code', '推荐码');
-                $filter->equal('user_id', '使用者ID');
-                $filter->whereLike('user.username', '使用者用户名');
-                $filter->whereLike('user.nickname', '使用者昵称');
-                $filter->equal('code_owner_id', '码主ID');
-                $filter->whereLike('codeOwner.username', '码主用户名');
-                $filter->whereLike('codeOwner.nickname', '码主昵称');
-                $filter->like('ip_address', 'IP地址');
-                $helper->equalReferralCodeUsageStatus();
-                $filter->like('result', '使用结果');
-                $filter->like('remark', '备注');
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionReferralCodeUsageRepository(['user', 'codeOwner']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('code', '推荐码');
-            $show->field('user_id', '使用者ID');
-            $show->field('user.username', '使用者用户名');
-            $show->field('user.nickname', '使用者昵称');
-            $show->field('code_owner_id', '码主ID');
-            $show->field('codeOwner.username', '码主用户名');
-            $show->field('codeOwner.nickname', '码主昵称');
-            $show->field('ip_address', 'IP地址');
-            $show->field('user_agent', '用户代理');
-            $helper->fieldReferralCodeUsageStatus();
-            $show->field('result', '使用结果');
-            $show->field('remark', '备注');
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionReferralCodeUsageRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('code', '推荐码')->required();
-            $form->text('user_id', '使用者ID')->required();
-            $form->text('code_owner_id', '码主ID')->required();
-            $form->text('ip_address', 'IP地址');
-            $form->text('user_agent', '用户代理');
-            $helper->selectReferralCodeUsageStatus()->required();
-            $form->text('result', '使用结果');
-            $form->textarea('remark', '备注');
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 127
app/Module/Promotion/AdminControllers/PromotionTalentConfigController.php

@@ -1,127 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionTalentConfigRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 达人等级配置管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-talent-configs', names: 'dcat.admin.promotion-talent-configs')]
-class PromotionTalentConfigController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '达人等级配置管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionTalentConfigRepository(), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('level', '等级')->sortable();
-            $grid->column('name', '名称');
-            $grid->column('direct_count_required', '直推人数要求')->sortable();
-            $grid->column('promotion_count_required', '团队总人数要求')->sortable();
-            $grid->column('profit_rate', '收益比例')->sortable();
-            $grid->column('icon', '图标');
-            $grid->column('icon_url', '图标URL');
-            $grid->column('status', '状态')->switch();
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->equal('level', '等级');
-                $filter->like('name', '名称');
-                $filter->between('direct_count_required', '直推人数要求');
-                $filter->between('promotion_count_required', '团队总人数要求');
-                $filter->between('profit_rate', '收益比例');
-                $filter->equal('status', '状态')->radio([
-                    1 => '启用',
-                    0 => '禁用',
-                ]);
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionTalentConfigRepository(), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('level', '等级');
-            $show->field('name', '名称');
-            $show->field('direct_count_required', '直推人数要求');
-            $show->field('promotion_count_required', '团队总人数要求');
-            $show->field('profit_rate', '收益比例');
-            $show->field('icon', '图标');
-            $show->field('icon_url', '图标URL');
-            $show->field('benefits', '权益')->json();
-            $show->field('status', '状态')->using([
-                1 => '启用',
-                0 => '禁用',
-            ]);
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionTalentConfigRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->number('level', '等级')->min(1)->required();
-            $form->text('name', '名称')->required();
-            $form->number('direct_count_required', '直推人数要求')->min(0)->default(0)->required();
-            $form->number('promotion_count_required', '团队总人数要求')->min(0)->default(0)->required();
-            $form->rate('profit_rate', '收益比例')->min(0)->max(1)->default(0)->required();
-            $form->text('icon', '图标');
-            $form->text('icon_url', '图标URL');
-            $helper->jsonEditor('benefits', '权益')->help('权益配置,JSON格式');
-            $form->switch('status', '状态')->default(1);
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 107
app/Module/Promotion/AdminControllers/PromotionUserReferralController.php

@@ -1,107 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionUserReferralRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 用户推荐关系管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-user-referrals', names: 'dcat.admin.promotion-user-referrals')]
-class PromotionUserReferralController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '用户推荐关系管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionUserReferralRepository(['user', 'referrer']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('user.username', '用户名');
-            $grid->column('user.nickname', '用户昵称');
-            $grid->column('referrer.username', '推荐人用户名');
-            $grid->column('referrer.nickname', '推荐人昵称');
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->equal('user_id', '用户ID');
-                $filter->equal('referrer_id', '推荐人ID');
-                $filter->whereLike('user.username', '用户名');
-                $filter->whereLike('user.nickname', '用户昵称');
-                $filter->whereLike('referrer.username', '推荐人用户名');
-                $filter->whereLike('referrer.nickname', '推荐人昵称');
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionUserReferralRepository(['user', 'referrer']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('user_id', '用户ID');
-            $show->field('user.username', '用户名');
-            $show->field('user.nickname', '用户昵称');
-            $show->field('referrer_id', '推荐人ID');
-            $show->field('referrer.username', '推荐人用户名');
-            $show->field('referrer.nickname', '推荐人昵称');
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionUserReferralRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('user_id', '用户ID')->required();
-            $form->text('referrer_id', '推荐人ID')->required();
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 111
app/Module/Promotion/AdminControllers/PromotionUserRelationCacheController.php

@@ -1,111 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionUserRelationCacheRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 用户关系缓存管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-user-relation-caches', names: 'dcat.admin.promotion-user-relation-caches')]
-class PromotionUserRelationCacheController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '用户关系缓存管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionUserRelationCacheRepository(['user', 'ancestor']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('user.username', '用户名');
-            $grid->column('user.nickname', '用户昵称');
-            $grid->column('ancestor.username', '祖先用户名');
-            $grid->column('ancestor.nickname', '祖先昵称');
-            $grid->column('level', '层级')->sortable();
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->equal('user_id', '用户ID');
-                $filter->whereLike('user.username', '用户名');
-                $filter->whereLike('user.nickname', '用户昵称');
-                $filter->equal('ancestor_id', '祖先ID');
-                $filter->whereLike('ancestor.username', '祖先用户名');
-                $filter->whereLike('ancestor.nickname', '祖先昵称');
-                $filter->equal('level', '层级');
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionUserRelationCacheRepository(['user', 'ancestor']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('user_id', '用户ID');
-            $show->field('user.username', '用户名');
-            $show->field('user.nickname', '用户昵称');
-            $show->field('ancestor_id', '祖先ID');
-            $show->field('ancestor.username', '祖先用户名');
-            $show->field('ancestor.nickname', '祖先昵称');
-            $show->field('level', '层级');
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionUserRelationCacheRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('user_id', '用户ID')->required();
-            $form->text('ancestor_id', '祖先ID')->required();
-            $form->number('level', '层级')->min(1)->default(1)->required();
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 110
app/Module/Promotion/AdminControllers/PromotionUserTalentController.php

@@ -1,110 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\AdminControllers;
-
-use App\Module\Promotion\AdminControllers\Helper\FilterHelper;
-use App\Module\Promotion\AdminControllers\Helper\FormHelper;
-use App\Module\Promotion\AdminControllers\Helper\GridHelper;
-use App\Module\Promotion\AdminControllers\Helper\ShowHelper;
-use App\Module\Promotion\Repositorys\PromotionUserTalentRepository;
-use Dcat\Admin\Form;
-use Dcat\Admin\Grid;
-use Dcat\Admin\Show;
-use UCore\DcatAdmin\AdminController;
-use Spatie\RouteAttributes\Attributes\Resource;
-
-/**
- * 用户达人等级管理控制器
- *
- * @package App\Module\Promotion\AdminControllers
- */
-#[Resource('promotion-user-talents', names: 'dcat.admin.promotion-user-talents')]
-class PromotionUserTalentController extends AdminController
-{
-    /**
-     * 标题
-     *
-     * @var string
-     */
-    protected $title = '用户达人等级管理';
-
-    /**
-     * 列表页
-     *
-     * @return Grid
-     */
-    protected function grid()
-    {
-        return Grid::make(new PromotionUserTalentRepository(['user']), function (Grid $grid) {
-            $helper = new GridHelper($grid, $this);
-            $grid->column('id', 'ID')->sortable();
-            $grid->column('user.username', '用户名');
-            $grid->column('user.nickname', '用户昵称');
-            $grid->column('talent_level', '达人等级')->sortable();
-            $grid->column('direct_count', '直推人数')->sortable();
-            $grid->column('promotion_count', '团队总人数')->sortable();
-            $grid->column('created_at', '创建时间');
-            $grid->column('updated_at', '更新时间');
-
-            // 筛选
-            $grid->filter(function ($filter) {
-                $helper = new FilterHelper($filter, $this);
-                $helper->equal('id', 'ID');
-                $filter->equal('user_id', '用户ID');
-                $filter->whereLike('user.username', '用户名');
-                $filter->whereLike('user.nickname', '用户昵称');
-                $filter->equal('talent_level', '达人等级');
-                $filter->between('direct_count', '直推人数');
-                $filter->between('promotion_count', '团队总人数');
-                $filter->between('created_at', '创建时间')->datetime();
-            });
-
-            return $grid;
-        });
-    }
-
-    /**
-     * 详情页
-     *
-     * @param mixed $id
-     * @return Show
-     */
-    protected function detail($id)
-    {
-        return Show::make($id, new PromotionUserTalentRepository(['user']), function (Show $show) {
-            $helper = new ShowHelper($show, $this);
-            $helper->field('id', 'ID');
-            $show->field('user_id', '用户ID');
-            $show->field('user.username', '用户名');
-            $show->field('user.nickname', '用户昵称');
-            $show->field('talent_level', '达人等级');
-            $show->field('direct_count', '直推人数');
-            $show->field('promotion_count', '团队总人数');
-            $show->field('created_at', '创建时间');
-            $show->field('updated_at', '更新时间');
-
-            return $show;
-        });
-    }
-
-    /**
-     * 表单
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        return Form::make(new PromotionUserTalentRepository(), function (Form $form) {
-            $helper = new FormHelper($form, $this);
-            $form->display('id', 'ID');
-            $form->text('user_id', '用户ID')->required();
-            $form->number('talent_level', '达人等级')->min(0)->default(0)->required();
-            $form->number('direct_count', '直推人数')->min(0)->default(0)->required();
-            $form->number('promotion_count', '团队总人数')->min(0)->default(0)->required();
-            $form->display('created_at', '创建时间');
-            $form->display('updated_at', '更新时间');
-
-            return $form;
-        });
-    }
-}

+ 0 - 60
app/Module/Promotion/Commands/CleanExpiredReferralCodesCommand.php

@@ -1,60 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Commands;
-
-use App\Module\Promotion\Services\ReferralCodeService;
-use Illuminate\Console\Command;
-
-/**
- * 清理过期推荐码命令
- *
- * 用于清理过期的推荐码,释放数据库空间。
- */
-class CleanExpiredReferralCodesCommand extends Command
-{
-    /**
-     * 命令名称
-     *
-     * @var string
-     */
-    protected $signature = 'promotion:clean-expired-referral-codes {--debug-info : 显示详细信息}';
-
-    /**
-     * 命令描述
-     *
-     * @var string
-     */
-    protected $description = '清理过期的推荐码';
-
-    /**
-     * 执行命令
-     *
-     * @return int
-     */
-    public function handle()
-    {
-        $this->info('开始清理过期推荐码...');
-
-        $showDebugInfo = $this->option('debug-info');
-
-        try {
-            $count = ReferralCodeService::cleanExpiredReferralCodes();
-
-            if ($showDebugInfo) {
-                $this->info("共清理了 {$count} 个过期推荐码");
-            } else {
-                $this->info("清理完成");
-            }
-
-            return 0;
-        } catch (\Exception $e) {
-            $this->error("清理过期推荐码失败: " . $e->getMessage());
-
-            if ($showDebugInfo) {
-                $this->error($e->getTraceAsString());
-            }
-
-            return 1;
-        }
-    }
-}

+ 0 - 114
app/Module/Promotion/Commands/RebuildRelationCacheCommand.php

@@ -1,114 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Commands;
-
-use App\Module\Promotion\Logics\RelationCacheLogic;
-use App\Module\Promotion\Models\PromotionUserReferral;
-use Illuminate\Console\Command;
-
-/**
- * 重建关系缓存命令
- *
- * 用于重建用户关系缓存,确保缓存数据的准确性。
- */
-class RebuildRelationCacheCommand extends Command
-{
-    /**
-     * 命令名称
-     *
-     * @var string
-     */
-    protected $signature = 'promotion:rebuild-relation-cache {--user-id= : 指定用户ID} {--debug-info : 显示详细信息}';
-
-    /**
-     * 命令描述
-     *
-     * @var string
-     */
-    protected $description = '重建用户关系缓存';
-
-    /**
-     * 关系缓存逻辑类
-     *
-     * @var RelationCacheLogic
-     */
-    protected $relationCacheLogic;
-
-    /**
-     * 创建命令实例
-     *
-     * @param RelationCacheLogic $relationCacheLogic 关系缓存逻辑类
-     * @return void
-     */
-    public function __construct(RelationCacheLogic $relationCacheLogic)
-    {
-        parent::__construct();
-        $this->relationCacheLogic = $relationCacheLogic;
-    }
-
-    /**
-     * 执行命令
-     *
-     * @return int
-     */
-    public function handle()
-    {
-        $this->info('开始重建关系缓存...');
-
-        $userId = $this->option('user-id');
-        $showDebugInfo = $this->option('debug-info');
-
-        try {
-            if ($userId) {
-                // 重建指定用户的关系缓存
-                $this->relationCacheLogic->rebuildUserRelationCache($userId);
-
-                if ($showDebugInfo) {
-                    $this->info("用户 {$userId} 的关系缓存重建完成");
-                } else {
-                    $this->info("重建完成");
-                }
-            } else {
-                // 重建所有用户的关系缓存
-                $this->relationCacheLogic->clearAllRelationCache();
-
-                $users = PromotionUserReferral::all();
-                $total = $users->count();
-                $current = 0;
-
-                if ($showDebugInfo) {
-                    $this->info("共有 {$total} 个用户需要重建关系缓存");
-                    $bar = $this->output->createProgressBar($total);
-                    $bar->start();
-                }
-
-                foreach ($users as $user) {
-                    $this->relationCacheLogic->buildUserRelationCache($user->user_id);
-                    $current++;
-
-                    if ($showDebugInfo) {
-                        $bar->advance();
-                    }
-                }
-
-                if ($showDebugInfo) {
-                    $bar->finish();
-                    $this->newLine();
-                    $this->info("所有用户的关系缓存重建完成");
-                } else {
-                    $this->info("重建完成");
-                }
-            }
-
-            return 0;
-        } catch (\Exception $e) {
-            $this->error("重建关系缓存失败: " . $e->getMessage());
-
-            if ($showDebugInfo) {
-                $this->error($e->getTraceAsString());
-            }
-
-            return 1;
-        }
-    }
-}

+ 0 - 120
app/Module/Promotion/Commands/UpdateTalentLevelsCommand.php

@@ -1,120 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Commands;
-
-use App\Module\Promotion\Logics\TalentLogic;
-use App\Module\Promotion\Models\PromotionUserTalent;
-use Illuminate\Console\Command;
-
-/**
- * 更新达人等级命令
- *
- * 用于更新所有用户的达人等级,确保等级数据的准确性。
- */
-class UpdateTalentLevelsCommand extends Command
-{
-    /**
-     * 命令名称
-     *
-     * @var string
-     */
-    protected $signature = 'promotion:update-talent-levels {--user-id= : 指定用户ID} {--debug-info : 显示详细信息}';
-
-    /**
-     * 命令描述
-     *
-     * @var string
-     */
-    protected $description = '更新用户达人等级';
-
-    /**
-     * 达人等级逻辑类
-     *
-     * @var TalentLogic
-     */
-    protected $talentLogic;
-
-    /**
-     * 创建命令实例
-     *
-     * @param TalentLogic $talentLogic 达人等级逻辑类
-     * @return void
-     */
-    public function __construct(TalentLogic $talentLogic)
-    {
-        parent::__construct();
-        $this->talentLogic = $talentLogic;
-    }
-
-    /**
-     * 执行命令
-     *
-     * @return int
-     */
-    public function handle()
-    {
-        $this->info('开始更新达人等级...');
-
-        $userId = $this->option('user-id');
-        $showDebugInfo = $this->option('debug-info');
-
-        try {
-            if ($userId) {
-                // 更新指定用户的达人等级
-                $result = $this->talentLogic->checkAndUpdateTalentLevel($userId);
-
-                if ($showDebugInfo) {
-                    if ($result) {
-                        $talent = PromotionUserTalent::where('user_id', $userId)->first();
-                        $this->info("用户 {$userId} 的达人等级更新为 {$talent->talent_level}");
-                    } else {
-                        $this->info("用户 {$userId} 的达人等级未变更");
-                    }
-                } else {
-                    $this->info("更新完成");
-                }
-            } else {
-                // 更新所有用户的达人等级
-                $users = PromotionUserTalent::all();
-                $total = $users->count();
-                $updated = 0;
-
-                if ($showDebugInfo) {
-                    $this->info("共有 {$total} 个用户需要更新达人等级");
-                    $bar = $this->output->createProgressBar($total);
-                    $bar->start();
-                }
-
-                foreach ($users as $user) {
-                    $result = $this->talentLogic->checkAndUpdateTalentLevel($user->user_id);
-
-                    if ($result) {
-                        $updated++;
-                    }
-
-                    if ($showDebugInfo) {
-                        $bar->advance();
-                    }
-                }
-
-                if ($showDebugInfo) {
-                    $bar->finish();
-                    $this->newLine();
-                    $this->info("共更新了 {$updated} 个用户的达人等级");
-                } else {
-                    $this->info("更新完成");
-                }
-            }
-
-            return 0;
-        } catch (\Exception $e) {
-            $this->error("更新达人等级失败: " . $e->getMessage());
-
-            if ($showDebugInfo) {
-                $this->error($e->getTraceAsString());
-            }
-
-            return 1;
-        }
-    }
-}

+ 0 - 6
app/Module/Promotion/Databases/GenerateSql/README.md

@@ -1,6 +0,0 @@
-# 自动生成的SQL文件目录
-
-**警告:这是自动生成的目录,请勿手动修改此目录下的任何文件!**
-
-此目录下的SQL文件由系统自动生成,用于记录数据库表结构。
-如需修改表结构,请修改对应的模型文件,然后重新运行生成命令。

+ 0 - 26
app/Module/Promotion/Databases/GenerateSql/team_invite_rewards.sql

@@ -1,26 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_invite_rewards 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionInviteReward
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_invite_rewards` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint NOT NULL COMMENT '获得奖励的用户ID',
-  `invited_user_id` bigint NOT NULL COMMENT '被邀请的用户ID',
-  `reward_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '奖励类型:item=物品,coin=货币,exp=经验',
-  `reward_id` bigint NOT NULL COMMENT '奖励ID(物品ID或货币类型ID)',
-  `reward_amount` int NOT NULL COMMENT '奖励数量',
-  `reward_source` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'register' COMMENT '奖励来源:register=注册,upgrade=升级,task=任务',
-  `status` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '状态:0=未发放,1=已发放,2=已过期',
-  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_invited_user_id` (`invited_user_id`) USING BTREE,
-  KEY `idx_reward_type` (`reward_type`) USING BTREE,
-  KEY `idx_reward_source` (`reward_source`) USING BTREE,
-  KEY `idx_status` (`status`) USING BTREE,
-  KEY `idx_created_at` (`created_at`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请奖励记录表';

+ 0 - 19
app/Module/Promotion/Databases/GenerateSql/team_profit_rules.sql

@@ -1,19 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_profit_rules 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionProfitRule
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_profit_rules` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `source_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '来源类型',
-  `direct_profit_rate` decimal(5,4) NOT NULL COMMENT '直推分成比例',
-  `max_indirect_level` int NOT NULL DEFAULT '20' COMMENT '最大间推层级',
-  `status` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '状态:1有效,0无效',
-  `rules` json DEFAULT NULL COMMENT '特殊规则',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `idx_source_type` (`source_type`) USING BTREE,
-  KEY `idx_status` (`status`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='收益分成规则表';

+ 0 - 24
app/Module/Promotion/Databases/GenerateSql/team_profits.sql

@@ -1,24 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_profits 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionProfit
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_profits` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint NOT NULL COMMENT '获得收益的用户ID',
-  `promotion_member_id` bigint NOT NULL COMMENT '团队成员ID',
-  `source_id` bigint NOT NULL COMMENT '收益来源ID',
-  `source_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收益来源类型',
-  `item_id` bigint NOT NULL COMMENT '物品ID',
-  `profit_amount` int NOT NULL COMMENT '分成收益数量',
-  `profit_rate` decimal(5,4) NOT NULL COMMENT '分成比例',
-  `relation_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '关系类型:1直推,2间推',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_promotion_member_id` (`promotion_member_id`) USING BTREE,
-  KEY `idx_source` (`source_type`,`source_id`) USING BTREE,
-  KEY `idx_relation_type` (`relation_type`) USING BTREE,
-  KEY `idx_created_at` (`created_at`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='团队收益记录表';

+ 0 - 19
app/Module/Promotion/Databases/GenerateSql/team_referral_changes.sql

@@ -1,19 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_referral_changes 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionReferralChange
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_referral_changes` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint NOT NULL COMMENT '用户ID',
-  `old_referrer_id` bigint DEFAULT NULL COMMENT '旧推荐人ID',
-  `new_referrer_id` bigint NOT NULL COMMENT '新推荐人ID',
-  `change_time` timestamp NOT NULL COMMENT '修改时间',
-  `change_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改原因',
-  `changed_by` bigint NOT NULL COMMENT '操作人ID',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_change_time` (`change_time`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推荐关系修改记录表';

+ 0 - 25
app/Module/Promotion/Databases/GenerateSql/team_referral_code_usages.sql

@@ -1,25 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_referral_code_usages 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionReferralCodeUsage
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_referral_code_usages` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '使用的邀请码',
-  `code_owner_id` bigint NOT NULL COMMENT '邀请码所有者用户ID',
-  `user_id` bigint NOT NULL COMMENT '使用邀请码的用户ID',
-  `ip_address` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用时的IP地址',
-  `user_agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用时的用户代理',
-  `status` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '状态:0=失败,1=成功,2=已撤销',
-  `result` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用结果描述',
-  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  KEY `idx_code` (`code`) USING BTREE,
-  KEY `idx_code_owner_id` (`code_owner_id`) USING BTREE,
-  KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_status` (`status`) USING BTREE,
-  KEY `idx_created_at` (`created_at`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请码使用记录表';

+ 0 - 20
app/Module/Promotion/Databases/GenerateSql/team_referral_codes.sql

@@ -1,20 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_referral_codes 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionReferralCode
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_referral_codes` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint NOT NULL COMMENT '用户ID',
-  `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '推荐码',
-  `usage_count` int NOT NULL DEFAULT '0' COMMENT '使用次数',
-  `status` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '状态:1有效,0无效',
-  `expire_time` timestamp NULL DEFAULT NULL COMMENT '过期时间,NULL表示永不过期',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `idx_code` (`code`) USING BTREE,
-  UNIQUE KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_status` (`status`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推荐码表';

+ 0 - 20
app/Module/Promotion/Databases/GenerateSql/team_talent_configs.sql

@@ -1,20 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_talent_configs 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionTalentConfig
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_talent_configs` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `level` tinyint unsigned NOT NULL COMMENT '等级',
-  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '等级名称',
-  `direct_count_required` int NOT NULL COMMENT '所需直推人数',
-  `promotion_count_required` int NOT NULL COMMENT '所需团队总人数',
-  `profit_rate` decimal(5,4) NOT NULL COMMENT '间推分成比例',
-  `benefits` json DEFAULT NULL COMMENT '等级权益',
-  `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '等级图标',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `idx_level` (`level`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='达人等级配置表';

+ 0 - 16
app/Module/Promotion/Databases/GenerateSql/team_user_referrals.sql

@@ -1,16 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_user_referrals 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionUserReferral
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_user_referrals` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint NOT NULL COMMENT '用户ID',
-  `referrer_id` bigint NOT NULL COMMENT '直接推荐人ID',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_referrer_id` (`referrer_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户直接推荐关系表';

+ 0 - 22
app/Module/Promotion/Databases/GenerateSql/team_user_relation_cache.sql

@@ -1,22 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_user_relation_cache 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionUserRelationCache
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_user_relation_cache` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint NOT NULL COMMENT '用户ID',
-  `related_user_id` bigint NOT NULL COMMENT '关联用户ID(上级)',
-  `level` tinyint unsigned NOT NULL COMMENT '关系层级:1直接,2间接',
-  `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关系路径,格式:1,2,3',
-  `depth` tinyint unsigned NOT NULL COMMENT '层级深度,从1开始',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `idx_user_relation` (`user_id`,`related_user_id`) USING BTREE,
-  KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_related_user_id` (`related_user_id`) USING BTREE,
-  KEY `idx_level` (`level`) USING BTREE,
-  KEY `idx_depth` (`depth`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户关系缓存表';

+ 0 - 18
app/Module/Promotion/Databases/GenerateSql/team_user_talents.sql

@@ -1,18 +0,0 @@
--- ******************************************************************
--- 表 kku_promotion_user_talents 的创建SQL
--- 对应的Model: App\Module\Promotion\Models\PromotionUserTalent
--- 警告: 此文件由系统自动生成,禁止修改!
--- ******************************************************************
-
-CREATE TABLE `kku_promotion_user_talents` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint NOT NULL COMMENT '用户ID',
-  `talent_level` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '达人等级:0无,1初级,2中级,3高级,4资深,5顶级',
-  `direct_count` int NOT NULL DEFAULT '0' COMMENT '直推人数',
-  `promotion_count` int 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`) USING BTREE,
-  UNIQUE KEY `idx_user_id` (`user_id`) USING BTREE,
-  KEY `idx_talent_level` (`talent_level`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='达人等级表';

+ 0 - 61
app/Module/Promotion/Docs/README.md

@@ -1,61 +0,0 @@
-# 团队模块文档
-
-## 文档目录
-
-### 1. 基础设计文档
-
-- [设计概述](设计概述.md) - 模块的整体设计思路和架构
-- [数据库设计](数据库设计.md) - 详细的数据库表结构和关系设计
-- [模块接口](模块接口.md) - 模块对外提供的服务接口
-- [枚举定义](枚举定义.md) - 模块中使用的所有枚举类型定义
-
-### 2. 功能领域文档
-
-- [推荐关系系统](推荐关系系统.md) - 推荐关系的建立、维护和查询
-- [达人等级系统](达人等级系统.md) - 达人等级的计算、升级和权益
-- [团队收益系统](团队收益系统.md) - 团队收益的计算、分配和记录
-- [直间推收益机制](直间推收益机制.md) - 直间推播种收获贡献百分比农作物收益的实现机制
-
-### 3. 开发与实现文档
-
-- [开发指南](开发指南.md) - 模块开发的快速入门指南
-- [事件系统](事件系统.md) - 模块的事件系统设计与实现
-- [缓存策略](缓存策略.md) - 团队模块的缓存策略设计与实现
-
-### 4. 模块集成文档
-
-- [与Farm模块集成](与Farm模块集成.md) - 团队模块与农场模块的集成方案
-- [与User模块集成](与User模块集成.md) - 团队模块与用户模块的集成方案
-- [与GameItems模块集成](与GameItems模块集成.md) - 团队模块与物品模块的集成方案
-
-## 文档更新记录
-
-| 日期 | 文档 | 更新内容 |
-|------|------|---------|
-| 2023-05-10 | 全部文档 | 初始创建 |
-| 2023-05-11 | 与Farm模块集成 | 添加团队模块与农场模块的集成方案 |
-| 2023-05-11 | 枚举定义 | 添加团队模块的枚举类型定义 |
-| 2023-05-12 | 推荐关系系统 | 更新为只保存直接上级关系 + 缓存策略的方案 |
-| 2023-05-12 | 数据库设计 | 更新推荐关系表结构,添加推荐关系修改记录表 |
-| 2023-05-12 | 缓存策略 | 添加团队模块的缓存策略设计与实现文档 |
-| 2023-05-15 | 直间推收益机制 | 添加直间推播种收获贡献百分比农作物收益的实现机制文档 |
-| 2023-05-15 | 与Farm模块集成 | 更新集成文档,强调直间推收益机制的实现 |
-| 2023-05-15 | 数据库设计 | 更新团队收益记录表,添加relation_type字段区分直推和间推收益 |
-| 2023-05-16 | 推荐关系系统 | 更新推荐关系系统文档,添加用户关系缓存表的设计与实现 |
-
-## 文档规范
-
-1. **命名规范**:文档文件名使用中文,以便于理解
-2. **格式规范**:使用Markdown格式,遵循统一的标题层级
-3. **内容规范**:每个文档应包含概述、正文和总结三部分
-4. **示例规范**:代码示例应包含注释,使用```php标记
-
-## 待完成文档
-
-1. **与Task模块集成** - 团队模块与任务系统的集成方案
-2. **测试指南** - 团队模块的测试方法和示例
-3. **监控与告警** - 团队模块的监控指标和告警策略
-
-## 联系方式
-
-如有文档相关问题,请联系团队模块文档负责人。

+ 0 - 197
app/Module/Promotion/Docs/create.sql

@@ -1,197 +0,0 @@
--- 团队模块数据库创建脚本
--- 包含所有团队模块相关表的创建语句
-
--- 1. 用户推荐关系表 (promotion_user_referrals)
--- 存储用户与其直接推荐人(直接上级)的关系
-CREATE TABLE IF NOT EXISTS `kku_promotion_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',
-  `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_referrer_id` (`referrer_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户直接推荐关系表';
-
--- 2. 达人等级表 (promotion_user_talents)
--- 存储用户的达人等级信息,包括直推人数和团队总人数
-CREATE TABLE IF NOT EXISTS `kku_promotion_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 '直推人数',
-  `promotion_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. 团队收益记录表 (promotion_profits)
--- 记录团队成员产生的分成收益
-CREATE TABLE IF NOT EXISTS `kku_promotion_profits` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '获得收益的用户ID',
-  `promotion_member_id` bigint(20) NOT NULL COMMENT '团队成员ID',
-  `source_id` bigint(20) NOT NULL COMMENT '收益来源ID',
-  `source_type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收益来源类型',
-  `item_id` bigint(20) NOT NULL COMMENT '物品ID',
-  `profit_amount` int(11) NOT NULL COMMENT '分成收益数量',
-  `profit_rate` decimal(5,4) NOT NULL COMMENT '分成比例',
-  `relation_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '关系类型:1直推,2间推',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_promotion_member_id` (`promotion_member_id`),
-  KEY `idx_source` (`source_type`,`source_id`),
-  KEY `idx_relation_type` (`relation_type`),
-  KEY `idx_created_at` (`created_at`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='团队收益记录表';
-
--- 4. 推荐码表 (promotion_referral_codes)
--- 存储用户的推荐码信息
-CREATE TABLE IF NOT EXISTS `kku_promotion_referral_codes` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `code` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '推荐码',
-  `usage_count` int(11) NOT NULL DEFAULT '0' COMMENT '使用次数',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:1有效,0无效',
-  `expire_time` timestamp NULL DEFAULT NULL COMMENT '过期时间,NULL表示永不过期',
-  `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_code` (`code`),
-  UNIQUE KEY `idx_user_id` (`user_id`),
-  KEY `idx_status` (`status`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推荐码表';
-
--- 5. 达人等级配置表 (promotion_talent_configs)
--- 存储不同达人等级的配置信息
-CREATE TABLE IF NOT EXISTS `kku_promotion_talent_configs` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `level` tinyint(3) unsigned NOT NULL COMMENT '等级',
-  `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '等级名称',
-  `direct_count_required` int(11) NOT NULL COMMENT '所需直推人数',
-  `promotion_count_required` int(11) NOT NULL COMMENT '所需团队总人数',
-  `profit_rate` decimal(5,4) NOT NULL COMMENT '间推分成比例',
-  `benefits` json DEFAULT NULL COMMENT '等级权益',
-  `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL 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_level` (`level`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='达人等级配置表';
-
--- 6. 收益分成规则表 (promotion_profit_rules)
--- 存储不同来源的收益分成规则
-CREATE TABLE IF NOT EXISTS `kku_promotion_profit_rules` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `source_type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '来源类型',
-  `direct_profit_rate` decimal(5,4) NOT NULL COMMENT '直推分成比例',
-  `max_indirect_level` int(11) NOT NULL DEFAULT '20' COMMENT '最大间推层级',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:1有效,0无效',
-  `rules` json DEFAULT NULL 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_source_type` (`source_type`),
-  KEY `idx_status` (`status`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='收益分成规则表';
-
--- 7. 推荐关系修改记录表 (promotion_referral_changes)
--- 记录用户推荐关系的修改历史
-CREATE TABLE IF NOT EXISTS `kku_promotion_referral_changes` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `old_referrer_id` bigint(20) DEFAULT NULL COMMENT '旧推荐人ID',
-  `new_referrer_id` bigint(20) NOT NULL COMMENT '新推荐人ID',
-  `change_time` timestamp NOT NULL COMMENT '修改时间',
-  `change_reason` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改原因',
-  `changed_by` bigint(20) NOT NULL COMMENT '操作人ID',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_change_time` (`change_time`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推荐关系修改记录表';
-
--- 8. 用户关系缓存表 (promotion_user_relation_cache)
--- 用于存储用户之间的所有推荐关系(包括上下级关系)
-CREATE TABLE IF NOT EXISTS `kku_promotion_user_relation_cache` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `related_user_id` bigint(20) NOT NULL COMMENT '关联用户ID(上级)',
-  `level` tinyint(3) unsigned NOT NULL COMMENT '关系层级:1直接,2间接',
-  `path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关系路径,格式:1,2,3',
-  `depth` tinyint(3) unsigned NOT NULL COMMENT '层级深度,从1开始',
-  `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_relation` (`user_id`,`related_user_id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_related_user_id` (`related_user_id`),
-  KEY `idx_level` (`level`),
-  KEY `idx_depth` (`depth`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户关系缓存表';
-
--- 9. 邀请奖励记录表 (promotion_invite_rewards)
--- 用于记录用户邀请他人注册时获得的奖励
-CREATE TABLE IF NOT EXISTS `kku_promotion_invite_rewards` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '获得奖励的用户ID',
-  `invited_user_id` bigint(20) NOT NULL COMMENT '被邀请的用户ID',
-  `reward_type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '奖励类型:item=物品,coin=货币,exp=经验',
-  `reward_id` bigint(20) NOT NULL COMMENT '奖励ID(物品ID或货币类型ID)',
-  `reward_amount` int(11) NOT NULL COMMENT '奖励数量',
-  `reward_source` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'register' COMMENT '奖励来源:register=注册,upgrade=升级,task=任务',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:0=未发放,1=已发放,2=已过期',
-  `remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_invited_user_id` (`invited_user_id`),
-  KEY `idx_reward_type` (`reward_type`),
-  KEY `idx_reward_source` (`reward_source`),
-  KEY `idx_status` (`status`),
-  KEY `idx_created_at` (`created_at`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请奖励记录表';
-
--- 10. 邀请码使用记录表 (promotion_referral_code_usages)
--- 用于详细记录每次邀请码的使用情况
-CREATE TABLE IF NOT EXISTS `kku_promotion_referral_code_usages` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `code` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '使用的邀请码',
-  `code_owner_id` bigint(20) NOT NULL COMMENT '邀请码所有者用户ID',
-  `user_id` bigint(20) NOT NULL COMMENT '使用邀请码的用户ID',
-  `ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用时的IP地址',
-  `user_agent` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用时的用户代理',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:0=失败,1=成功,2=已撤销',
-  `result` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用结果描述',
-  `remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_code` (`code`),
-  KEY `idx_code_owner_id` (`code_owner_id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_status` (`status`),
-  KEY `idx_created_at` (`created_at`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请码使用记录表';
-
--- 初始化数据
-
--- 1. 达人等级配置数据
-INSERT INTO `kku_promotion_talent_configs` (`level`, `name`, `direct_count_required`, `promotion_count_required`, `profit_rate`, `benefits`) VALUES
-(1, '初级达人', 5, 10, 0.0100, '{"farm_output_bonus": 0.01}'),
-(2, '中级达人', 10, 30, 0.0150, '{"farm_output_bonus": 0.02}'),
-(3, '高级达人', 20, 50, 0.0200, '{"farm_output_bonus": 0.03, "daily_gift": {"item_id": 1001, "amount": 1}}'),
-(4, '资深达人', 30, 100, 0.0250, '{"farm_output_bonus": 0.04, "daily_gift": {"item_id": 1001, "amount": 2}}'),
-(5, '顶级达人', 50, 200, 0.0300, '{"farm_output_bonus": 0.05, "daily_gift": {"item_id": 1001, "amount": 3}, "special_privileges": ["vip_customer_service", "exclusive_avatar_frame"]}');
-
--- 2. 收益分成规则数据
-INSERT INTO `kku_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}'),
-('task_complete', 0.0300, 10, 1, '{"min_amount": 5, "max_amount": 500}'),
-('item_sell', 0.0200, 5, 1, '{"min_amount": 1, "max_amount": 100, "excluded_items": [1001, 1002]}');

+ 0 - 1424
app/Module/Promotion/Docs/推荐关系系统.md

@@ -1,1424 +0,0 @@
-# 推荐关系系统
-
-## 1. 概述
-
-推荐关系系统是团队模块的核心组成部分,负责管理用户之间的推荐关系、团队结构和推荐码。该系统通过建立用户间的直推和间推关系,形成多层级的团队结构,为收益分成和达人等级提供基础数据支持。
-
-## 2. 推荐关系类型
-
-### 2.1 直推关系
-
-直推关系是指用户A直接推荐用户B注册,则用户A是用户B的直推上级,用户B是用户A的直推下级。
-
-```
-用户A ──直推──> 用户B
-```
-
-直推关系具有以下特点:
-- 一个用户只能有一个直推上级
-- 一个用户可以有多个直推下级
-- 直推关系不可更改,一旦建立永久有效
-- 直推上级可获得下级收益的固定比例分成(通常为5%)
-
-### 2.2 间推关系
-
-间推关系是指通过直推关系形成的间接推荐关系。例如,用户A推荐用户B,用户B推荐用户C,则用户A是用户C的间推上级,用户C是用户A的间推下级。
-
-```
-用户A ──直推──> 用户B ──直推──> 用户C
-用户A ──间推──> 用户C
-```
-
-间推关系具有以下特点:
-- 一个用户可以有多个间推上级
-- 一个用户可以有多个间推下级
-- 间推关系通过直推关系自动建立
-- 间推上级可获得下级收益的部分分成,比例取决于达人等级
-
-### 2.3 团队结构
-
-用户的所有直推和间推下级构成该用户的团队。团队结构是一个多层级的树状结构,用户在其中可以同时扮演上级和下级的角色。
-
-```
-            用户A
-           /     \
-        用户B     用户C
-       /    \        \
-    用户D   用户E     用户F
-```
-
-在上图中:
-- 用户A的直推下级:用户B、用户C
-- 用户A的间推下级:用户D、用户E、用户F
-- 用户A的团队成员:用户B、用户C、用户D、用户E、用户F
-
-## 3. 数据结构设计
-
-### 3.1 用户推荐关系表 (promotion_user_referrals)
-
-用户推荐关系表采用简化设计,只存储用户与其直接上级(直推关系)的关系,间接关系通过缓存或实时计算获取。
-
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 用户ID |
-| referrer_id | bigint | 直接推荐人ID |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-示例数据:
-```
-id | user_id | referrer_id | created_at
----|---------|------------|------------
-1  | 2       | 1          | 2023-05-01 10:00:00
-2  | 3       | 2          | 2023-05-01 11:00:00
-3  | 4       | 3          | 2023-05-01 12:00:00
-```
-
-在上面的示例中:
-- 用户1直推了用户2
-- 用户2直推了用户3
-- 用户3直推了用户4
-
-通过这种链式关系,可以计算出间接推荐关系:
-- 用户1间接推荐了用户3(通过用户2)
-- 用户1间接推荐了用户4(通过用户2和用户3)
-- 用户2间接推荐了用户4(通过用户3)
-
-### 3.2 推荐码表 (promotion_referral_codes)
-
-推荐码表存储用户的推荐码信息,用于邀请新用户注册。
-
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 用户ID |
-| code | varchar | 推荐码 |
-| usage_count | int | 使用次数 |
-| status | tinyint | 状态(1=有效,0=无效) |
-| expire_time | timestamp | 过期时间,NULL表示永不过期 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-## 4. 核心功能
-
-### 4.1 推荐关系建立
-
-当新用户注册并使用推荐码时,系统会建立推荐关系:
-
-```php
-/**
- * 建立推荐关系
- */
-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("用户已有推荐人,不能重复设置");
-        }
-
-        // 验证是否形成循环推荐
-        if ($this->checkCircularReferral($userId, $referrerId)) {
-            throw new ReferralException("不能形成循环推荐关系");
-        }
-
-        // 创建直推关系
-        $this->referralRepository->create([
-            'user_id' => $userId,
-            'referrer_id' => $referrerId
-        ]);
-
-        // 更新推荐人的直推人数
-        $this->talentRepository->incrementDirectCount($referrerId);
-
-        // 清除相关缓存
-        $this->clearReferralCaches($userId, null, $referrerId);
-
-        // 更新推荐人的团队人数
-        $this->updatePromotionCounts($referrerId);
-
-        // 触发推荐关系创建事件
-        event(new ReferralCreatedEvent($userId, $referrerId));
-
-        // 检查并更新达人等级
-        $this->talentService->checkAndUpdateTalentLevel($referrerId);
-
-        return true;
-    });
-}
-
-/**
- * 更新用户及其所有上级的团队人数
- */
-private function updatePromotionCounts(int $userId): void
-{
-    // 更新当前用户的团队人数
-    $directCount = $this->countDirectReferrals($userId);
-    $promotionCount = $this->calculatePromotionCount($userId);
-    $this->talentRepository->updateCounts($userId, $directCount, $promotionCount);
-
-    // 递归更新所有上级的团队人数
-    $directReferrer = $this->referralRepository->getDirectReferrer($userId);
-    if ($directReferrer) {
-        $this->updatePromotionCounts($directReferrer->referrer_id);
-    }
-}
-
-/**
- * 计算用户的团队总人数
- */
-private function calculatePromotionCount(int $userId): int
-{
-    // 获取所有团队成员
-    $allMembers = $this->getAllPromotionMembers($userId);
-    return count($allMembers);
-}
-```
-
-### 4.2 推荐码生成
-
-系统为每个用户生成唯一的推荐码,用于邀请新用户:
-
-```php
-/**
- * 生成推荐码
- */
-public function generateReferralCode(int $userId): string
-{
-    // 检查用户是否已有推荐码
-    $existingCode = $this->referralCodeRepository->getByUserId($userId);
-    if ($existingCode) {
-        return $existingCode->code;
-    }
-
-    // 生成唯一推荐码
-    $code = $this->generateUniqueCode();
-
-    // 保存推荐码
-    $this->referralCodeRepository->create([
-        'user_id' => $userId,
-        'code' => $code,
-        'usage_count' => 0,
-        'status' => 1
-    ]);
-
-    return $code;
-}
-
-/**
- * 生成唯一推荐码
- */
-private function generateUniqueCode(): string
-{
-    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
-    $length = 6;
-
-    do {
-        $code = '';
-        for ($i = 0; $i < $length; $i++) {
-            $code .= $characters[random_int(0, strlen($characters) - 1)];
-        }
-    } while ($this->referralCodeRepository->codeExists($code));
-
-    return $code;
-}
-```
-
-### 4.3 推荐关系查询
-
-系统提供多种方式查询推荐关系,使用缓存优化查询性能:
-
-```php
-/**
- * 获取用户的所有上级(包括直接和间接)
- */
-public function getAllReferrers(int $userId): array
-{
-    // 尝试从缓存获取
-    $cacheKey = "promotion:user:{$userId}:all_referrers";
-    $cachedReferrers = Redis::get($cacheKey);
-
-    if ($cachedReferrers !== null) {
-        return json_decode($cachedReferrers, true);
-    }
-
-    // 缓存不存在,计算所有上级
-    $allReferrers = [];
-    $this->calculateAllReferrers($userId, $allReferrers);
-
-    // 缓存结果
-    Redis::setex($cacheKey, 86400, json_encode($allReferrers)); // 缓存1天
-
-    return $allReferrers;
-}
-
-/**
- * 递归计算用户的所有上级
- */
-private function calculateAllReferrers(int $userId, array &$allReferrers, int $level = 0, int $maxLevel = 20): void
-{
-    // 限制最大层级
-    if ($level >= $maxLevel) {
-        return;
-    }
-
-    // 获取直接上级
-    $directReferrer = $this->referralRepository->getDirectReferrer($userId);
-    if (!$directReferrer) {
-        return;
-    }
-
-    $referrerId = $directReferrer->referrer_id;
-
-    // 添加到结果集
-    $allReferrers[] = [
-        'user_id' => $referrerId,
-        'level' => $level == 0 ? 1 : 2, // 1=直推, 2=间推
-        'created_at' => $directReferrer->created_at
-    ];
-
-    // 递归获取上级的上级
-    $this->calculateAllReferrers($referrerId, $allReferrers, $level + 1, $maxLevel);
-}
-
-/**
- * 获取用户的所有团队成员(包括直接和间接)
- */
-public function getAllPromotionMembers(int $userId, int $page = 1, int $pageSize = 20): array
-{
-    // 尝试从缓存获取
-    $cacheKey = "promotion:user:{$userId}:all_members";
-    $cachedMembers = Redis::get($cacheKey);
-
-    $allMembers = [];
-    if ($cachedMembers !== null) {
-        $allMembers = json_decode($cachedMembers, true);
-    } else {
-        // 缓存不存在,计算所有下级
-        $this->calculateAllPromotionMembers($userId, $allMembers);
-
-        // 缓存结果
-        Redis::setex($cacheKey, 86400, json_encode($allMembers)); // 缓存1天
-    }
-
-    // 计算总数
-    $total = count($allMembers);
-
-    // 分页
-    $offset = ($page - 1) * $pageSize;
-    $pagedMembers = array_slice($allMembers, $offset, $pageSize);
-
-    // 获取成员详细信息
-    $members = [];
-    foreach ($pagedMembers as $member) {
-        $userInfo = $this->userRepository->find($member['user_id']);
-        if ($userInfo) {
-            $members[] = [
-                'user_id' => $userInfo->id,
-                'username' => $userInfo->username,
-                'avatar' => $userInfo->avatar,
-                'level' => $member['level'],
-                'created_at' => $member['created_at']
-            ];
-        }
-    }
-
-    // 返回结果
-    return [
-        'total' => $total,
-        'page' => $page,
-        'page_size' => $pageSize,
-        'total_pages' => ceil($total / $pageSize),
-        'members' => $members
-    ];
-}
-
-/**
- * 递归计算用户的所有团队成员
- */
-private function calculateAllPromotionMembers(int $userId, array &$allMembers, int $level = 0, int $maxLevel = 20): void
-{
-    // 限制最大层级
-    if ($level >= $maxLevel) {
-        return;
-    }
-
-    // 获取直接下级
-    $directMembers = $this->referralRepository->getDirectMembers($userId);
-
-    foreach ($directMembers as $member) {
-        $memberId = $member->user_id;
-
-        // 添加到结果集
-        $allMembers[] = [
-            'user_id' => $memberId,
-            'level' => $level == 0 ? 1 : 2, // 1=直推, 2=间推
-            'created_at' => $member->created_at
-        ];
-
-        // 递归获取下级的下级
-        $this->calculateAllPromotionMembers($memberId, $allMembers, $level + 1, $maxLevel);
-    }
-}
-
-/**
- * 清除推荐关系相关的缓存
- */
-private function clearReferralCaches(int $userId, ?int $oldReferrerId, int $newReferrerId): void
-{
-    // 清除用户自身的缓存
-    Redis::del("promotion:user:{$userId}:all_referrers");
-
-    // 清除旧推荐人相关的缓存
-    if ($oldReferrerId) {
-        Redis::del("promotion:user:{$oldReferrerId}:all_members");
-
-        // 获取旧推荐人的所有上级,清除他们的团队成员缓存
-        $oldUpperReferrers = $this->getAllReferrers($oldReferrerId);
-        foreach ($oldUpperReferrers as $referrer) {
-            Redis::del("promotion:user:{$referrer['user_id']}:all_members");
-        }
-    }
-
-    // 清除新推荐人相关的缓存
-    Redis::del("promotion:user:{$newReferrerId}:all_members");
-
-    // 获取新推荐人的所有上级,清除他们的团队成员缓存
-    $newUpperReferrers = $this->getAllReferrers($newReferrerId);
-    foreach ($newUpperReferrers as $referrer) {
-        Redis::del("promotion:user:{$referrer['user_id']}:all_members");
-    }
-
-    // 获取用户的所有下级,清除他们的上级缓存
-    $allMembers = $this->getAllPromotionMembers($userId);
-    foreach ($allMembers['members'] as $member) {
-        Redis::del("promotion:user:{$member['user_id']}:all_referrers");
-    }
-}
-```
-
-### 4.4 推荐码验证与使用记录
-
-用户注册时,系统验证推荐码并获取推荐人ID。验证过程包括:
-
-1. 查询推荐码是否存在
-2. 验证推荐码的有效性(状态是否为有效)
-3. 检查推荐码是否已过期
-4. 更新推荐码的使用次数
-5. 记录邀请码使用情况(无论成功与否)
-6. 返回推荐码对应的推荐人ID
-
-验证成功后,系统将使用返回的推荐人ID建立推荐关系。
-
-系统会详细记录每次邀请码的使用情况,包括:
-
-1. **使用的邀请码**:记录用户输入的邀请码
-2. **邀请码所有者**:记录邀请码属于哪个用户
-3. **使用者信息**:记录使用邀请码的用户ID、IP地址和用户代理
-4. **使用结果**:记录使用是否成功,以及失败原因
-5. **使用时间**:记录邀请码使用的时间
-
-邀请码使用记录可用于:
-
-1. **邀请统计**:统计用户成功邀请的人数
-2. **防止刷邀请**:检测同一IP地址短时间内多次使用邀请码的情况
-3. **邀请追踪**:追踪邀请链路,分析用户邀请行为
-4. **问题排查**:当用户反馈邀请码问题时,可查询使用记录进行排查
-
-### 4.5 邀请奖励发放
-
-当用户成功邀请他人注册或被邀请用户达成特定条件(如升级、完成任务等)时,系统会发放邀请奖励。奖励发放流程包括:
-
-1. **验证用户关系**:确认邀请人和被邀请人的推荐关系存在
-2. **获取奖励配置**:根据奖励来源(注册、升级、任务等)获取对应的奖励配置
-3. **检查重复发放**:确保同一来源的奖励不会重复发放(注册奖励除外)
-4. **创建奖励记录**:在邀请奖励记录表中创建奖励记录
-5. **发放实际奖励**:根据奖励类型(物品、货币、经验等)调用相应服务发放实际奖励
-6. **更新奖励状态**:将奖励记录状态更新为已发放
-7. **触发奖励事件**:触发邀请奖励发放事件,供其他模块响应
-
-系统支持多种奖励类型:
-- **物品奖励**:向用户背包添加指定物品
-- **货币奖励**:向用户账户添加指定类型的货币
-- **经验奖励**:为用户增加经验值
-
-### 4.6 邀请奖励查询
-
-系统提供多种方式查询邀请奖励记录,支持按用户、被邀请用户、奖励类型、来源和状态进行筛选:
-
-1. **获取用户的邀请奖励记录**:查询用户获得的所有邀请奖励,支持分页和多种筛选条件
-2. **获取被邀请用户产生的奖励记录**:查询特定被邀请用户为他人产生的所有奖励记录
-3. **统计用户邀请奖励总量**:统计用户获得的各类型奖励总量和邀请总人数
-
-查询结果包含详细的奖励信息,如奖励类型、数量、来源、状态等,以及相关用户的基本信息(用户名、头像等)。
-
-### 4.7 邀请码使用记录查询
-
-系统提供多种方式查询邀请码的使用记录,支持按邀请码、邀请码所有者、使用者和使用结果等条件进行筛选:
-
-1. **查询特定邀请码的使用记录**:查询某个邀请码的所有使用记录,包括成功和失败的记录
-2. **查询用户使用的邀请码记录**:查询特定用户使用过的所有邀请码记录
-3. **查询邀请码所有者的邀请记录**:查询特定用户的邀请码被他人使用的记录
-4. **查询特定状态的邀请码使用记录**:查询成功、失败或被撤销的邀请码使用记录
-5. **统计邀请码所有者的邀请人数**:统计用户成功邀请的总人数
-6. **查询特定时间段的邀请记录**:查询某个时间段内的邀请码使用情况
-7. **查询特定IP地址的邀请记录**:查询来自特定IP地址的邀请码使用记录,用于防止刷邀请
-
-查询结果包含详细的邀请码使用信息,如邀请码、使用者、使用时间、使用结果等,以及相关用户的基本信息。
-
-## 5. 推荐关系存储策略
-
-### 5.1 直接关系存储 + 缓存策略
-
-团队模块采用只存储直接推荐关系,通过缓存或实时计算处理间接关系的策略。这种设计有以下优点:
-
-1. **数据结构简化**:只需存储直接推荐关系,大幅减少数据表的记录数量
-2. **存储空间优化**:减少了数据库存储空间的使用
-3. **关系修改灵活**:修改推荐关系更加简单,只需更新一条记录
-4. **缓存加速查询**:通过缓存加速查询,保持查询性能
-5. **按需计算**:间接关系按需计算,减少不必要的计算
-
-### 5.2 存储空间与查询效率的权衡
-
-直接关系存储 + 缓存策略在存储空间和查询效率之间取得了良好的平衡:
-
-| 存储方式 | 存储空间 | 查询效率 | 维护成本 | 修改灵活性 |
-|---------|---------|---------|---------|----------|
-| 仅存储直推关系(无缓存) | 低 | 低(需递归查询) | 低 | 高 |
-| 仅存储直推关系(有缓存) | 低 + 缓存空间 | 高(缓存命中)/ 中(缓存未命中) | 中 | 高 |
-| 扁平化存储 | 高 | 高(一次查询) | 中 | 低 |
-| 直推关系 + 缓存表 | 中 | 高(一次查询) | 中 | 高 |
-
-对于团队模块,直接关系存储 + 缓存策略是最佳选择,因为:
-- 在保持较高查询效率的同时,大幅减少了存储空间
-- 提高了推荐关系修改的灵活性,支持用户更换上级
-- 缓存机制可以有效减轻递归查询的性能问题
-- 缓存策略可以根据业务需求灵活调整
-
-### 5.3 缓存策略
-
-为了提高查询效率,系统采用多层缓存策略:
-
-#### 5.3.1 内存缓存(Redis)
-
-1. **缓存内容**:
-   - 用户的所有上级(包括直接和间接)
-   - 用户的所有下级(包括直接和间接)
-
-2. **缓存键设计**:
-   ```
-   // 用户的所有上级
-   key: promotion:user:{userId}:all_referrers
-   value: [referrerId1, referrerId2, ...]
-
-   // 用户的所有下级
-   key: promotion:user:{userId}:all_members
-   value: [memberId1, memberId2, ...]
-   ```
-
-3. **缓存更新策略**:
-   - **懒加载更新**:当查询用户的上级或下级时,如果缓存不存在,则计算并缓存
-   - **主动更新**:当推荐关系发生变化时,主动更新相关用户的缓存
-   - **定期刷新**:定期任务刷新活跃用户的缓存,确保数据一致性
-
-4. **缓存过期时间**:
-   - 设置合理的缓存过期时间,如1天
-   - 对于活跃用户和大型团队的领导者,可以设置更长的缓存时间
-
-#### 5.3.2 数据库缓存表
-
-为了进一步提高查询效率,特别是在Redis缓存失效或需要复杂查询时,系统引入了用户关系缓存表:
-
-##### 5.3.2.1 用户关系缓存表 (promotion_user_relation_cache)
-
-用户关系缓存表是一个统一的缓存表,用于存储用户之间的所有推荐关系(包括上下级关系)。通过合理设计字段和索引,一张表可以同时满足查询用户上级和下级的需求,减少数据冗余,简化维护。
-
-**表结构设计**:
-
-```sql
-CREATE TABLE `promotion_user_relation_cache` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `related_user_id` bigint(20) NOT NULL COMMENT '关联用户ID(上级)',
-  `level` tinyint(3) unsigned NOT NULL COMMENT '关系层级:1直接,2间接',
-  `path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关系路径,格式:1,2,3',
-  `depth` tinyint(3) unsigned NOT NULL COMMENT '层级深度,从1开始',
-  `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_relation` (`user_id`,`related_user_id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_related_user_id` (`related_user_id`),
-  KEY `idx_level` (`level`),
-  KEY `idx_depth` (`depth`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户关系缓存表';
-```
-
-**字段说明**:
-
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 用户ID(下级) |
-| related_user_id | bigint | 关联用户ID(上级) |
-| level | tinyint | 关系层级:1直接,2间接 |
-| path | varchar | 关系路径,格式:1,2,3 |
-| depth | tinyint | 层级深度,从1开始 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-**主要功能**:
-- 快速查询用户的所有上级(直推和间推)
-- 快速查询用户的所有下级(直推和间推)
-- 支持按层级、深度等条件进行复杂查询
-- 为收益分成系统和团队统计提供高效的数据支持
-
-**示例数据**:
-```
-id | user_id | related_user_id | level | path      | depth
----|---------|----------------|-------|-----------|------
-1  | 4       | 3              | 1     | 3         | 1
-2  | 4       | 2              | 2     | 3,2       | 2
-3  | 4       | 1              | 2     | 3,2,1     | 3
-4  | 3       | 2              | 1     | 2         | 1
-5  | 3       | 1              | 2     | 2,1       | 2
-6  | 2       | 1              | 1     | 1         | 1
-```
-
-在上面的示例中:
-- 用户4的直接上级是用户3(level=1)
-- 用户4的间接上级是用户2和用户1(level=2)
-- 用户3的直接上级是用户2(level=1)
-- 用户3的间接上级是用户1(level=2)
-- 用户2的直接上级是用户1(level=1)
-
-**查询示例**:
-
-1. 查询用户4的所有上级:
-```sql
-SELECT * FROM promotion_user_relation_cache WHERE user_id = 4;
-```
-
-2. 查询用户1的所有下级:
-```sql
-SELECT * FROM promotion_user_relation_cache WHERE related_user_id = 1;
-```
-
-3. 查询用户2的直接下级:
-```sql
-SELECT u.* FROM users u
-JOIN promotion_user_relation_cache r ON u.id = r.user_id
-WHERE r.related_user_id = 2 AND r.level = 1;
-```
-
-4. 查询用户1的第2代下级:
-```sql
-SELECT u.* FROM users u
-JOIN promotion_user_relation_cache r ON u.id = r.user_id
-WHERE r.related_user_id = 1 AND r.depth = 2;
-```
-
-##### 5.3.2.2 缓存表优势与应用场景
-
-**缓存表优势**:
-- **数据统一性**:单一表存储所有关系,减少数据冗余,简化维护
-- **持久化存储**:不受内存限制,数据持久保存
-- **复杂查询支持**:支持SQL的各种复杂查询条件和聚合函数
-- **关联查询能力**:可与其他表进行关联查询,扩展数据分析能力
-- **减轻内存压力**:减少对Redis等内存缓存的依赖,降低缓存失效的影响
-- **高效统计分析**:支持团队规模、层级分布等复杂统计分析
-- **存储空间优化**:相比维护两张独立的缓存表,减少了约50%的存储空间
-
-**应用场景**:
-- **收益分成计算**:快速查找用户的所有上级,计算分成
-- **团队规模统计**:快速统计用户的团队规模,评定达人等级
-- **层级分布分析**:分析团队的层级分布,了解团队结构
-- **特定代数查询**:查询用户的特定代数下级,如20代以内的团队成员
-- **团队关系可视化**:为团队树形图和关系图提供数据支持
-- **双向关系查询**:同时支持上级和下级的高效查询
-
-##### 5.3.2.3 缓存表数据维护机制
-
-**初始化机制**:
-- 用户注册并建立推荐关系时,初始化相关缓存数据
-- 系统启动或升级时,可执行全量初始化,确保数据完整性
-
-```php
-/**
- * 初始化用户的关系缓存
- */
-public function initializeUserRelationCache(int $userId): int
-{
-    // 删除用户现有缓存
-    $this->relationCacheRepository->deleteByConditions([
-        'user_id' => $userId
-    ]);
-
-    // 获取直接上级
-    $directReferrer = $this->referralRepository->getDirectReferrer($userId);
-    if (!$directReferrer) {
-        return 0;
-    }
-
-    $count = 0;
-    $referrerId = $directReferrer->referrer_id;
-
-    // 添加直接上级缓存
-    $this->relationCacheRepository->create([
-        'user_id' => $userId,
-        'related_user_id' => $referrerId,
-        'level' => 1,
-        'path' => (string)$referrerId,
-        'depth' => 1
-    ]);
-    $count++;
-
-    // 获取上级的所有上级
-    $upperReferrers = $this->relationCacheRepository->findByConditions([
-        'user_id' => $referrerId
-    ]);
-
-    // 添加间接上级缓存
-    foreach ($upperReferrers as $upperReferrer) {
-        $this->relationCacheRepository->create([
-            'user_id' => $userId,
-            'related_user_id' => $upperReferrer->related_user_id,
-            'level' => 2,
-            'path' => $referrerId . ',' . $upperReferrer->path,
-            'depth' => $upperReferrer->depth + 1
-        ]);
-        $count++;
-    }
-
-    return $count;
-}
-```
-
-**更新机制**:
-- 用户变更上级时,同步更新关系缓存
-- 推荐关系变化时,级联更新所有相关用户的缓存
-
-```php
-/**
- * 更新用户关系缓存
- */
-public function updateUserRelationCache(int $userId, int $oldReferrerId, int $newReferrerId): void
-{
-    DB::transaction(function () use ($userId, $oldReferrerId, $newReferrerId) {
-        // 1. 删除用户及其所有下级与旧上级及其所有上级的关系缓存
-        if ($oldReferrerId) {
-            // 获取用户的所有下级ID
-            $downlineIds = $this->getDownlineIds($userId);
-            $downlineIds[] = $userId; // 包括用户自身
-
-            // 获取旧上级的所有上级ID
-            $upperReferrerIds = $this->getUpperReferrerIds($oldReferrerId);
-            $upperReferrerIds[] = $oldReferrerId; // 包括直接上级
-
-            // 删除关系缓存
-            foreach ($downlineIds as $downlineId) {
-                foreach ($upperReferrerIds as $upperReferrerId) {
-                    $this->relationCacheRepository->deleteByConditions([
-                        'user_id' => $downlineId,
-                        'related_user_id' => $upperReferrerId
-                    ]);
-                }
-            }
-        }
-
-        // 2. 为用户及其所有下级创建与新上级及其所有上级的关系缓存
-        if ($newReferrerId) {
-            // 初始化用户的关系缓存
-            $this->initializeUserRelationCache($userId);
-
-            // 获取用户的所有下级
-            $downlines = $this->getDownlines($userId);
-
-            // 更新所有下级的关系缓存
-            foreach ($downlines as $downline) {
-                $this->initializeUserRelationCache($downline['user_id']);
-            }
-        }
-    });
-}
-```
-
-**校验与修复**:
-- 定期执行缓存数据校验,检查与实际推荐关系的一致性
-- 发现不一致时自动修复,确保数据准确性
-
-```php
-/**
- * 验证用户关系缓存
- */
-private function validateUserRelationCache(int $userId): bool
-{
-    // 获取直接上级
-    $directReferrer = $this->referralRepository->getDirectReferrer($userId);
-
-    if (!$directReferrer) {
-        // 用户没有上级,缓存应该为空
-        $cacheCount = $this->relationCacheRepository->countByConditions([
-            'user_id' => $userId
-        ]);
-        return $cacheCount === 0;
-    }
-
-    // 获取缓存的直接上级
-    $cachedDirectReferrer = $this->relationCacheRepository->findByConditions([
-        'user_id' => $userId,
-        'level' => 1
-    ])->first();
-
-    if (!$cachedDirectReferrer || $cachedDirectReferrer->related_user_id != $directReferrer->referrer_id) {
-        return false;
-    }
-
-    // 验证间接上级
-    // 递归计算实际的间接上级
-    $actualIndirectReferrers = $this->calculateIndirectReferrers($directReferrer->referrer_id);
-
-    // 获取缓存的间接上级
-    $cachedIndirectReferrers = $this->relationCacheRepository->findByConditions([
-        'user_id' => $userId,
-        'level' => 2
-    ]);
-
-    // 比较间接上级数量
-    if (count($actualIndirectReferrers) != count($cachedIndirectReferrers)) {
-        return false;
-    }
-
-    // 比较间接上级ID
-    $actualReferrerIds = collect($actualIndirectReferrers)->pluck('referrer_id')->toArray();
-    $cachedReferrerIds = $cachedIndirectReferrers->pluck('related_user_id')->toArray();
-
-    sort($actualReferrerIds);
-    sort($cachedReferrerIds);
-
-    return $actualReferrerIds == $cachedReferrerIds;
-}
-```
-
-**性能优化**:
-- 批量处理大规模数据更新
-- 异步处理非关键路径的缓存更新
-- 分片处理大型团队的缓存维护
-- 定期优化表和索引,保持查询性能
-
-##### 5.3.2.4 缓存表查询示例
-
-**查询用户的所有上级**:
-```php
-/**
- * 获取用户的所有上级
- */
-public function getAllReferrers(int $userId, int $level = 0, int $maxDepth = 20): array
-{
-    $conditions = ['user_id' => $userId];
-
-    if ($level > 0) {
-        $conditions['level'] = $level;
-    }
-
-    if ($maxDepth > 0) {
-        $conditions['depth'] = ['<=', $maxDepth];
-    }
-
-    $relations = $this->relationCacheRepository->findByConditions($conditions);
-
-    $referrers = [];
-    foreach ($relations as $relation) {
-        $referrers[] = [
-            'user_id' => $relation->related_user_id,
-            'level' => $relation->level,
-            'depth' => $relation->depth,
-            'path' => $relation->path
-        ];
-    }
-
-    return $referrers;
-}
-```
-
-**查询用户的所有团队成员**:
-```php
-/**
- * 获取用户的所有团队成员
- */
-public function getAllPromotionMembers(int $userId, int $level = 0, int $maxDepth = 20, int $page = 1, int $pageSize = 20): array
-{
-    $conditions = ['related_user_id' => $userId];
-
-    if ($level > 0) {
-        $conditions['level'] = $level;
-    }
-
-    if ($maxDepth > 0) {
-        $conditions['depth'] = ['<=', $maxDepth];
-    }
-
-    // 获取总数
-    $total = $this->relationCacheRepository->countByConditions($conditions);
-
-    // 分页查询
-    $offset = ($page - 1) * $pageSize;
-    $relations = $this->relationCacheRepository->findByConditionsPaginated($conditions, $offset, $pageSize);
-
-    // 获取成员详细信息
-    $members = [];
-    foreach ($relations as $relation) {
-        $userInfo = $this->userRepository->find($relation->user_id);
-        if ($userInfo) {
-            $members[] = [
-                'user_id' => $userInfo->id,
-                'username' => $userInfo->username,
-                'avatar' => $userInfo->avatar,
-                'level' => $relation->level,
-                'depth' => $relation->depth,
-                'path' => $relation->path,
-                'created_at' => $userInfo->created_at
-            ];
-        }
-    }
-
-    return [
-        'total' => $total,
-        'page' => $page,
-        'page_size' => $pageSize,
-        'total_pages' => ceil($total / $pageSize),
-        'members' => $members
-    ];
-}
-```
-
-**查询特定代数的团队成员**:
-```php
-/**
- * 获取用户特定代数的团队成员
- */
-public function getPromotionMembersByDepth(int $userId, int $depth): array
-{
-    $relations = $this->relationCacheRepository->findByConditions([
-        'related_user_id' => $userId,
-        'depth' => $depth
-    ]);
-
-    $members = [];
-    foreach ($relations as $relation) {
-        $userInfo = $this->userRepository->find($relation->user_id);
-        if ($userInfo) {
-            $members[] = [
-                'user_id' => $userInfo->id,
-                'username' => $userInfo->username,
-                'level' => $relation->level,
-                'depth' => $relation->depth,
-                'path' => $relation->path
-            ];
-        }
-    }
-
-    return $members;
-}
-```
-
-**统计团队规模**:
-```php
-/**
- * 统计用户的团队规模
- */
-public function countPromotionMembers(int $userId, int $level = 0): int
-{
-    $conditions = ['related_user_id' => $userId];
-
-    if ($level > 0) {
-        $conditions['level'] = $level;
-    }
-
-    return $this->relationCacheRepository->countByConditions($conditions);
-}
-```
-
-### 5.4 关系建立流程
-
-新用户注册并使用推荐码时,系统按以下流程建立推荐关系:
-
-1. 验证推荐码,获取直推推荐人ID
-2. 创建用户与直推推荐人的直推关系
-3. 清除相关缓存,包括用户自身、推荐人及其上级的缓存
-4. 更新推荐人及其上级的团队统计数据
-5. 触发推荐关系创建事件
-
-这种方式简化了关系建立流程,同时通过缓存机制保持了查询效率。
-
-## 6. 推荐码系统
-
-### 6.1 推荐码生成算法
-
-推荐码生成采用随机字符串算法,确保唯一性和安全性:
-
-1. **字符集**:使用数字和大写字母(0-9, A-Z)组成的36个字符
-2. **长度**:默认6位,可根据需求调整
-3. **唯一性检查**:生成后检查数据库中是否已存在,如存在则重新生成
-4. **安全性**:使用密码学安全的随机数生成器,避免可预测性
-
-### 6.2 推荐码使用流程
-
-推荐码的使用流程如下:
-
-1. 用户注册时输入推荐码
-2. 系统验证推荐码的有效性
-3. 获取推荐码对应的推荐人ID
-4. 建立用户与推荐人的推荐关系
-5. 更新推荐码的使用次数
-
-### 6.3 推荐链接和二维码
-
-除了纯文本推荐码外,系统还支持推荐链接和二维码:
-
-1. **推荐链接**:格式为`https://example.com/register?code=ABCDEF`
-2. **推荐二维码**:包含推荐链接的二维码图片
-
-用户可以分享推荐链接或二维码,新用户通过链接注册时自动填入推荐码。
-
-## 7. 推荐关系修改
-
-### 7.1 推荐关系修改功能
-
-在只存储直接推荐关系的设计下,系统可以支持修改用户的推荐关系(上级):
-
-```php
-/**
- * 更新用户的推荐关系
- */
-public function updateReferralRelation(int $userId, int $newReferrerId): bool
-{
-    return DB::transaction(function () use ($userId, $newReferrerId) {
-        // 验证用户和新推荐人是否存在
-        if (!$this->userRepository->exists($userId) || !$this->userRepository->exists($newReferrerId)) {
-            throw new UserNotFoundException("用户或新推荐人不存在");
-        }
-
-        // 验证是否形成循环推荐
-        if ($this->checkCircularReferral($userId, $newReferrerId)) {
-            throw new ReferralException("不能形成循环推荐关系");
-        }
-
-        // 获取旧的直接推荐人
-        $oldReferrer = $this->referralRepository->getDirectReferrer($userId);
-        $oldReferrerId = $oldReferrer ? $oldReferrer->referrer_id : null;
-
-        // 如果新旧推荐人相同,无需更新
-        if ($oldReferrerId == $newReferrerId) {
-            return true;
-        }
-
-        // 更新直接推荐关系
-        if ($oldReferrerId) {
-            $this->referralRepository->deleteDirectReferral($userId);
-        }
-
-        $this->referralRepository->createDirectReferral($userId, $newReferrerId);
-
-        // 清除相关缓存
-        $this->clearReferralCaches($userId, $oldReferrerId, $newReferrerId);
-
-        // 更新旧推荐人的直推人数和团队人数
-        if ($oldReferrerId) {
-            $this->updatePromotionCounts($oldReferrerId);
-            $this->talentService->checkAndUpdateTalentLevel($oldReferrerId);
-        }
-
-        // 更新新推荐人的直推人数和团队人数
-        $this->updatePromotionCounts($newReferrerId);
-        $this->talentService->checkAndUpdateTalentLevel($newReferrerId);
-
-        // 记录修改历史
-        $this->referralChangeRepository->create([
-            'user_id' => $userId,
-            'old_referrer_id' => $oldReferrerId,
-            'new_referrer_id' => $newReferrerId,
-            'change_time' => now(),
-            'change_reason' => request('reason', ''),
-            'changed_by' => Auth::id() ?? 0
-        ]);
-
-        // 触发推荐关系更新事件
-        event(new ReferralUpdatedEvent($userId, $oldReferrerId, $newReferrerId));
-
-        return true;
-    });
-}
-```
-
-### 7.2 推荐关系修改记录表
-
-为了记录推荐关系的修改历史,系统使用以下表结构:
-
-```sql
-CREATE TABLE `promotion_referral_changes` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `old_referrer_id` bigint(20) DEFAULT NULL COMMENT '旧推荐人ID',
-  `new_referrer_id` bigint(20) NOT NULL COMMENT '新推荐人ID',
-  `change_time` timestamp NOT NULL COMMENT '修改时间',
-  `change_reason` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改原因',
-  `changed_by` bigint(20) NOT NULL COMMENT '操作人ID',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_change_time` (`change_time`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推荐关系修改记录表';
-```
-
-### 7.3 修改限制策略
-
-为了防止频繁修改推荐关系导致系统不稳定,系统实施以下限制策略:
-
-```php
-/**
- * 验证用户是否可以修改推荐关系
- */
-private function validateReferralChangeEligibility(int $userId): void
-{
-    // 检查修改次数限制
-    $changeCount = $this->referralChangeRepository->countRecentChanges($userId, 180); // 180天内
-    if ($changeCount >= 1) {
-        throw new ReferralException("180天内只能修改一次推荐关系");
-    }
-
-    // 检查注册时间限制
-    $user = $this->userRepository->find($userId);
-    if ($user->created_at->diffInDays(now()) < 30) {
-        throw new ReferralException("注册30天内不能修改推荐关系");
-    }
-
-    // 检查团队规模限制
-    $promotionCount = $this->calculatePromotionCount($userId);
-    if ($promotionCount > 100) {
-        throw new ReferralException("团队规模超过100人不能修改推荐关系");
-    }
-}
-```
-
-## 8. 防循环推荐机制
-
-### 8.1 循环推荐问题
-
-循环推荐是指用户A推荐用户B,用户B又推荐用户A的情况,或者形成更长的循环链。这种情况会导致:
-
-1. 无限循环的推荐关系
-2. 收益分成的循环计算
-3. 团队统计数据的错误
-
-### 8.2 检测和防止机制
-
-系统通过以下机制检测和防止循环推荐:
-
-```php
-/**
- * 检查是否形成循环推荐
- */
-private function checkCircularReferral(int $userId, int $referrerId): bool
-{
-    // 如果用户ID和推荐人ID相同,直接形成循环
-    if ($userId == $referrerId) {
-        return true;
-    }
-
-    // 获取用户的所有下级
-    $allMembers = $this->getAllPromotionMembers($userId);
-
-    // 检查新推荐人是否在用户的下级中
-    foreach ($allMembers['members'] as $member) {
-        if ($member['user_id'] == $referrerId) {
-            return true;
-        }
-    }
-
-    return false;
-}
-```
-
-此外,系统还实施以下规则:
-
-1. **修改限制**:限制用户修改推荐关系的频率和条件
-2. **层级限制**:间推关系最多支持20层,防止过深的推荐链
-3. **状态验证**:只有状态正常的用户才能成为推荐人
-
-## 9. 团队统计
-
-### 9.1 直推人数统计
-
-系统实时统计用户的直推人数:
-
-```php
-/**
- * 统计用户的直推人数
- */
-public function countDirectReferrals(int $userId): int
-{
-    return $this->referralRepository->countByConditions([
-        'referrer_id' => $userId,
-        'level' => 1
-    ]);
-}
-```
-
-### 9.2 团队总人数统计
-
-系统实时统计用户的团队总人数(包括直推和间推):
-
-```php
-/**
- * 统计用户的团队总人数
- */
-public function countPromotionMembers(int $userId): int
-{
-    return $this->referralRepository->countByConditions([
-        'referrer_id' => $userId
-    ]);
-}
-```
-
-### 9.3 团队活跃度统计
-
-系统支持统计团队的活跃度,用于评估团队质量:
-
-```php
-/**
- * 统计用户团队的活跃度
- */
-public function calculatePromotionActivity(int $userId, int $days = 7): array
-{
-    // 获取团队成员ID列表
-    $memberIds = $this->referralRepository->getPromotionMemberIds($userId);
-
-    // 统计活跃用户数
-    $activeCount = $this->userActivityRepository->countActiveUsers($memberIds, $days);
-
-    // 计算活跃率
-    $totalCount = count($memberIds);
-    $activeRate = $totalCount > 0 ? $activeCount / $totalCount : 0;
-
-    return [
-        'total_members' => $totalCount,
-        'active_members' => $activeCount,
-        'active_rate' => $activeRate,
-        'days' => $days
-    ];
-}
-```
-
-## 10. 推荐关系可视化
-
-### 10.1 团队树形图
-
-系统支持生成团队的树形结构图,直观展示推荐关系:
-
-```php
-/**
- * 生成用户的团队树形图
- */
-public function generatePromotionTree(int $userId, int $maxDepth = 3): array
-{
-    // 获取用户信息
-    $user = $this->userRepository->find($userId);
-    if (!$user) {
-        return [];
-    }
-
-    // 构建根节点
-    $root = [
-        'id' => $user->id,
-        'name' => $user->username,
-        'avatar' => $user->avatar,
-        'children' => []
-    ];
-
-    // 递归构建团队树
-    $this->buildPromotionTreeNode($root, 1, $maxDepth);
-
-    return $root;
-}
-
-/**
- * 递归构建团队树节点
- */
-private function buildPromotionTreeNode(array &$node, int $currentDepth, int $maxDepth): void
-{
-    // 达到最大深度,停止递归
-    if ($currentDepth >= $maxDepth) {
-        return;
-    }
-
-    // 获取直推成员
-    $directMembers = $this->referralRepository->findByConditions([
-        'referrer_id' => $node['id'],
-        'level' => 1
-    ]);
-
-    // 构建子节点
-    foreach ($directMembers as $member) {
-        $user = $this->userRepository->find($member->user_id);
-        if ($user) {
-            $childNode = [
-                'id' => $user->id,
-                'name' => $user->username,
-                'avatar' => $user->avatar,
-                'children' => []
-            ];
-
-            // 递归构建子节点
-            $this->buildPromotionTreeNode($childNode, $currentDepth + 1, $maxDepth);
-
-            // 添加到父节点
-            $node['children'][] = $childNode;
-        }
-    }
-}
-```
-
-### 10.2 团队关系图
-
-系统支持生成团队的关系图,展示成员之间的连接:
-
-```php
-/**
- * 生成用户的团队关系图
- */
-public function generatePromotionGraph(int $userId, int $maxMembers = 50): array
-{
-    // 获取团队成员
-    $members = $this->getPromotionMembers($userId, 0, 1, $maxMembers)['members'];
-
-    // 构建节点
-    $nodes = [];
-    $nodes[] = [
-        'id' => $userId,
-        'name' => $this->userRepository->find($userId)->username,
-        'type' => 'root'
-    ];
-
-    foreach ($members as $member) {
-        $nodes[] = [
-            'id' => $member['user_id'],
-            'name' => $member['username'],
-            'type' => $member['level'] == 1 ? 'direct' : 'indirect'
-        ];
-    }
-
-    // 构建边
-    $edges = [];
-    foreach ($members as $member) {
-        $edges[] = [
-            'source' => $member['level'] == 1 ? $userId : $this->getDirectReferrerId($member['user_id']),
-            'target' => $member['user_id'],
-            'type' => $member['level'] == 1 ? 'direct' : 'indirect'
-        ];
-    }
-
-    return [
-        'nodes' => $nodes,
-        'edges' => $edges
-    ];
-}
-```
-
-## 11. 与其他系统的集成
-
-### 11.1 与用户系统的集成
-
-推荐关系系统与用户系统紧密集成:
-
-1. **用户注册**:用户注册时处理推荐码,建立推荐关系
-2. **用户状态**:用户状态变更(如封禁、注销)会影响推荐关系
-3. **用户信息**:推荐关系展示需要用户的基本信息(昵称、头像等)
-
-### 11.2 与达人等级系统的集成
-
-推荐关系系统为达人等级系统提供基础数据:
-
-1. **团队规模**:直推人数和团队总人数用于计算达人等级
-2. **团队活跃度**:团队活跃度可作为达人等级的附加条件
-3. **等级变更**:推荐关系变化可能触发达人等级变更
-
-### 11.3 与收益分成系统的集成
-
-推荐关系系统为收益分成系统提供关系数据:
-
-1. **分成对象**:确定哪些上级可以获得分成
-2. **分成比例**:根据推荐关系类型(直推/间推)确定基础分成比例
-3. **分成计算**:提供推荐链路,用于计算多级分成
-
-## 12. 性能优化
-
-### 12.1 查询优化
-
-针对推荐关系的高频查询,系统采用以下优化措施:
-
-1. **索引优化**:为`user_id`、`referrer_id`和`level`字段建立合适的索引
-2. **复合索引**:为常用的查询条件组合建立复合索引
-3. **查询缓存**:缓存频繁查询的结果,如用户的直推人数和团队总人数
-4. **分页查询**:大数据量查询采用分页机制,避免一次加载过多数据
-
-### 12.2 缓存策略
-
-系统采用多级缓存策略提高性能:
-
-1. **本地缓存**:缓存单次请求中重复使用的数据
-2. **分布式缓存**:使用Redis缓存跨请求的数据
-3. **缓存更新**:推荐关系变更时主动更新缓存
-4. **缓存失效**:设置合理的缓存过期时间,平衡实时性和性能
-
-### 12.3 批量操作
-
-对于大规模数据操作,系统采用批量处理方式:
-
-1. **批量插入**:一次插入多条推荐关系记录
-2. **批量更新**:一次更新多个用户的团队统计数据
-3. **异步处理**:耗时操作放入队列异步处理
-4. **定时任务**:定期执行统计和维护任务,避免实时计算
-
-## 13. 安全性考虑
-
-### 13.1 防刷机制
-
-防止恶意用户刷取推荐关系:
-
-1. **IP限制**:限制同一IP短时间内的注册次数
-2. **设备限制**:限制同一设备短时间内的注册次数
-3. **验证码**:注册时使用验证码防止自动注册
-4. **人工审核**:对异常推荐关系进行人工审核
-
-### 13.2 数据验证
-
-严格验证输入数据,确保数据安全:
-
-1. **用户验证**:验证用户和推荐人的存在性和有效性
-2. **关系验证**:验证推荐关系的合法性,防止循环推荐
-3. **推荐码验证**:验证推荐码的有效性和状态
-4. **参数验证**:验证API参数的合法性和范围
-
-### 13.3 权限控制
-
-实施严格的权限控制,保护用户数据:
-
-1. **用户权限**:用户只能查看自己的团队数据
-2. **管理权限**:只有管理员可以查看和修改所有推荐关系
-3. **操作日志**:记录关键操作的日志,便于审计和追踪
-4. **数据脱敏**:展示团队数据时对敏感信息进行脱敏
-
-## 14. 总结
-
-推荐关系系统是团队模块的核心组成部分,通过建立用户间的直推和间推关系,形成多层级的团队结构,为收益分成和达人等级提供基础数据支持。系统采用只存储直接推荐关系 + 缓存策略的设计,在保持较高查询效率的同时,大幅减少了存储空间,并提高了推荐关系修改的灵活性。
-
-系统实现了推荐码生成、推荐关系修改、防循环推荐、团队统计和可视化等功能,通过缓存机制优化了查询性能,同时保持了数据的一致性。通过与用户系统、达人等级系统和收益分成系统的紧密集成,推荐关系系统为团队模块的其他功能提供了坚实的基础。
-
-这种设计方案特别适合需要支持推荐关系修改的场景,用户可以在特定条件下更换上级,系统会自动处理相关的缓存更新和团队统计数据更新,确保数据的一致性和完整性。

+ 0 - 548
app/Module/Promotion/Docs/数据库设计.md

@@ -1,548 +0,0 @@
-# 团队模块数据库设计
-
-## 1. 数据库表概览
-
-团队模块包含以下核心数据表:
-
-1. **promotion_user_referrals** - 用户推荐关系表
-2. **promotion_user_talents** - 达人等级表
-3. **promotion_profits** - 团队收益记录表
-4. **promotion_referral_codes** - 推荐码表
-5. **promotion_talent_configs** - 达人等级配置表
-6. **promotion_profit_rules** - 收益分成规则表
-7. **promotion_referral_changes** - 推荐关系修改记录表
-8. **promotion_user_relation_cache** - 用户关系缓存表
-9. **promotion_invite_rewards** - 邀请奖励记录表
-10. **promotion_referral_code_usages** - 邀请码使用记录表
-
-## 2. 表结构详细设计
-
-### 2.1 用户推荐关系表 (promotion_user_referrals)
-
-存储用户与其直接推荐人(直接上级)的关系,间接关系通过缓存或实时计算获取。该表是实现"直间推播种收获贡献百分比农作物收益"功能的基础。
-
-```sql
-CREATE TABLE `promotion_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',
-  `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_referrer_id` (`referrer_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户直接推荐关系表';
-```
-
-> 注意:表中只存储直接推荐关系(直推),间接推荐关系(间推)通过递归查询或缓存获取。这种设计简化了数据结构,同时通过缓存机制保证了查询效率。
-
-### 2.2 达人等级表 (promotion_user_talents)
-
-存储用户的达人等级信息,包括直推人数和团队总人数。
-
-```sql
-CREATE TABLE `promotion_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 '直推人数',
-  `promotion_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='达人等级表';
-```
-
-### 2.3 团队收益记录表 (promotion_profits)
-
-记录团队成员产生的分成收益,是实现"直间推播种收获贡献百分比农作物收益"功能的核心表。
-
-```sql
-CREATE TABLE `promotion_profits` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '获得收益的用户ID',
-  `promotion_member_id` bigint(20) NOT NULL COMMENT '团队成员ID',
-  `source_id` bigint(20) NOT NULL COMMENT '收益来源ID',
-  `source_type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收益来源类型',
-  `item_id` bigint(20) NOT NULL COMMENT '物品ID',
-  `profit_amount` int(11) NOT NULL COMMENT '分成收益数量',
-  `profit_rate` decimal(5,4) NOT NULL COMMENT '分成比例',
-  `relation_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '关系类型:1直推,2间推',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_promotion_member_id` (`promotion_member_id`),
-  KEY `idx_source` (`source_type`,`source_id`),
-  KEY `idx_relation_type` (`relation_type`),
-  KEY `idx_created_at` (`created_at`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='团队收益记录表';
-```
-
-> 注意:`relation_type`字段用于区分直推和间推收益,便于统计和分析。`source_type`为'farm_harvest'时表示农场收获收益,是团队收益的主要来源。
-
-### 2.4 推荐码表 (promotion_referral_codes)
-
-存储用户的推荐码信息。
-
-```sql
-CREATE TABLE `promotion_referral_codes` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `code` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '推荐码',
-  `usage_count` int(11) NOT NULL DEFAULT '0' COMMENT '使用次数',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:1有效,0无效',
-  `expire_time` timestamp NULL DEFAULT NULL COMMENT '过期时间,NULL表示永不过期',
-  `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_code` (`code`),
-  UNIQUE KEY `idx_user_id` (`user_id`),
-  KEY `idx_status` (`status`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推荐码表';
-```
-
-### 2.5 达人等级配置表 (promotion_talent_configs)
-
-存储不同达人等级的配置信息。
-
-```sql
-CREATE TABLE `promotion_talent_configs` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `level` tinyint(3) unsigned NOT NULL COMMENT '等级',
-  `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '等级名称',
-  `direct_count_required` int(11) NOT NULL COMMENT '所需直推人数',
-  `promotion_count_required` int(11) NOT NULL COMMENT '所需团队总人数',
-  `profit_rate` decimal(5,4) NOT NULL COMMENT '间推分成比例',
-  `benefits` json DEFAULT NULL COMMENT '等级权益',
-  `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL 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_level` (`level`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='达人等级配置表';
-```
-
-### 2.6 收益分成规则表 (promotion_profit_rules)
-
-存储不同来源的收益分成规则。
-
-```sql
-CREATE TABLE `promotion_profit_rules` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `source_type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '来源类型',
-  `direct_profit_rate` decimal(5,4) NOT NULL COMMENT '直推分成比例',
-  `max_indirect_level` int(11) NOT NULL DEFAULT '20' COMMENT '最大间推层级',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:1有效,0无效',
-  `rules` json DEFAULT NULL 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_source_type` (`source_type`),
-  KEY `idx_status` (`status`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='收益分成规则表';
-```
-
-### 2.7 推荐关系修改记录表 (promotion_referral_changes)
-
-记录用户推荐关系的修改历史。
-
-```sql
-CREATE TABLE `promotion_referral_changes` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `old_referrer_id` bigint(20) DEFAULT NULL COMMENT '旧推荐人ID',
-  `new_referrer_id` bigint(20) NOT NULL COMMENT '新推荐人ID',
-  `change_time` timestamp NOT NULL COMMENT '修改时间',
-  `change_reason` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改原因',
-  `changed_by` bigint(20) NOT NULL COMMENT '操作人ID',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_change_time` (`change_time`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推荐关系修改记录表';
-```
-
-### 2.8 用户关系缓存表 (promotion_user_relation_cache)
-
-用户关系缓存表是一个统一的缓存表,用于存储用户之间的所有推荐关系(包括上下级关系)。通过合理设计字段和索引,一张表可以同时满足查询用户上级和下级的需求,减少数据冗余,简化维护。
-
-```sql
-CREATE TABLE `promotion_user_relation_cache` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
-  `related_user_id` bigint(20) NOT NULL COMMENT '关联用户ID(上级)',
-  `level` tinyint(3) unsigned NOT NULL COMMENT '关系层级:1直接,2间接',
-  `path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关系路径,格式:1,2,3',
-  `depth` tinyint(3) unsigned NOT NULL COMMENT '层级深度,从1开始',
-  `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_relation` (`user_id`,`related_user_id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_related_user_id` (`related_user_id`),
-  KEY `idx_level` (`level`),
-  KEY `idx_depth` (`depth`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户关系缓存表';
-```
-
-**字段说明**:
-
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 用户ID(下级) |
-| related_user_id | bigint | 关联用户ID(上级) |
-| level | tinyint | 关系层级:1直接,2间接 |
-| path | varchar | 关系路径,格式:1,2,3 |
-| depth | tinyint | 层级深度,从1开始 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-### 2.9 邀请奖励记录表 (promotion_invite_rewards)
-
-邀请奖励记录表用于记录用户邀请他人注册时获得的奖励,支持多种奖励类型和来源追踪。
-
-```sql
-CREATE TABLE `promotion_invite_rewards` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `user_id` bigint(20) NOT NULL COMMENT '获得奖励的用户ID',
-  `invited_user_id` bigint(20) NOT NULL COMMENT '被邀请的用户ID',
-  `reward_type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '奖励类型:item=物品,coin=货币,exp=经验',
-  `reward_id` bigint(20) NOT NULL COMMENT '奖励ID(物品ID或货币类型ID)',
-  `reward_amount` int(11) NOT NULL COMMENT '奖励数量',
-  `reward_source` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'register' COMMENT '奖励来源:register=注册,upgrade=升级,task=任务',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:0=未发放,1=已发放,2=已过期',
-  `remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_invited_user_id` (`invited_user_id`),
-  KEY `idx_reward_type` (`reward_type`),
-  KEY `idx_reward_source` (`reward_source`),
-  KEY `idx_status` (`status`),
-  KEY `idx_created_at` (`created_at`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请奖励记录表';
-```
-
-**字段说明**:
-
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 获得奖励的用户ID |
-| invited_user_id | bigint | 被邀请的用户ID |
-| reward_type | varchar | 奖励类型:item=物品,coin=货币,exp=经验 |
-| reward_id | bigint | 奖励ID(物品ID或货币类型ID) |
-| reward_amount | int | 奖励数量 |
-| reward_source | varchar | 奖励来源:register=注册,upgrade=升级,task=任务 |
-| status | tinyint | 状态:0=未发放,1=已发放,2=已过期 |
-| remark | varchar | 备注 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-**示例数据**:
-```
-id | user_id | invited_user_id | reward_type | reward_id | reward_amount | reward_source | status | created_at
----|---------|----------------|------------|-----------|--------------|--------------|--------|------------
-1  | 1       | 2              | item        | 1001      | 5            | register     | 1      | 2023-05-01 10:00:00
-2  | 1       | 3              | coin        | 1         | 100          | register     | 1      | 2023-05-02 11:00:00
-3  | 2       | 4              | exp         | 0         | 50           | register     | 1      | 2023-05-03 12:00:00
-4  | 1       | 2              | item        | 1002      | 1            | upgrade      | 1      | 2023-05-10 10:00:00
-```
-
-在上面的示例中:
-- 用户1邀请用户2注册,获得了5个ID为1001的物品奖励
-- 用户1邀请用户3注册,获得了100个ID为1的货币奖励
-- 用户2邀请用户4注册,获得了50点经验值奖励
-- 当用户2升级时,用户1获得了1个ID为1002的物品奖励
-
-### 2.10 邀请码使用记录表 (promotion_referral_code_usages)
-
-邀请码使用记录表用于详细记录每次邀请码的使用情况,包括谁使用了哪个邀请码、何时使用、使用结果等信息。
-
-```sql
-CREATE TABLE `promotion_referral_code_usages` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `code` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '使用的邀请码',
-  `code_owner_id` bigint(20) NOT NULL COMMENT '邀请码所有者用户ID',
-  `user_id` bigint(20) NOT NULL COMMENT '使用邀请码的用户ID',
-  `ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用时的IP地址',
-  `user_agent` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用时的用户代理',
-  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态:0=失败,1=成功,2=已撤销',
-  `result` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '使用结果描述',
-  `remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
-  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_code` (`code`),
-  KEY `idx_code_owner_id` (`code_owner_id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_status` (`status`),
-  KEY `idx_created_at` (`created_at`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邀请码使用记录表';
-```
-
-**字段说明**:
-
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| code | varchar | 使用的邀请码 |
-| code_owner_id | bigint | 邀请码所有者用户ID |
-| user_id | bigint | 使用邀请码的用户ID |
-| ip_address | varchar | 使用时的IP地址 |
-| user_agent | varchar | 使用时的用户代理 |
-| status | tinyint | 状态:0=失败,1=成功,2=已撤销 |
-| result | varchar | 使用结果描述 |
-| remark | varchar | 备注 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-**示例数据**:
-```
-id | code     | code_owner_id | user_id | ip_address    | status | result                | created_at
----|----------|--------------|---------|---------------|--------|----------------------|------------
-1  | ABC123   | 1            | 2       | 192.168.1.1   | 1      | 注册成功               | 2023-05-01 10:00:00
-2  | DEF456   | 3            | 4       | 192.168.1.2   | 1      | 注册成功               | 2023-05-02 11:00:00
-3  | ABC123   | 1            | 5       | 192.168.1.3   | 0      | 邀请码已过期            | 2023-05-03 12:00:00
-4  | GHI789   | 6            | 7       | 192.168.1.4   | 2      | 管理员撤销             | 2023-05-04 13:00:00
-```
-
-在上面的示例中:
-- 用户2成功使用了用户1的邀请码ABC123注册
-- 用户4成功使用了用户3的邀请码DEF456注册
-- 用户5尝试使用用户1的邀请码ABC123,但失败了,原因是邀请码已过期
-- 用户7使用了用户6的邀请码GHI789,但后来被管理员撤销了
-
-1. 查询用户4的所有上级:
-```sql
-SELECT * FROM promotion_user_relation_cache WHERE user_id = 4;
-```
-
-2. 查询用户1的所有下级:
-```sql
-SELECT * FROM promotion_user_relation_cache WHERE related_user_id = 1;
-```
-
-3. 查询用户2的直接下级:
-```sql
-SELECT u.* FROM users u
-JOIN promotion_user_relation_cache r ON u.id = r.user_id
-WHERE r.related_user_id = 2 AND r.level = 1;
-```
-
-4. 查询用户1的第2代下级:
-```sql
-SELECT u.* FROM users u
-JOIN promotion_user_relation_cache r ON u.id = r.user_id
-WHERE r.related_user_id = 1 AND r.depth = 2;
-```
-
-> 注意:该表是缓存表,其数据可以通过`promotion_user_referrals`表重新计算生成。使用单一表存储所有关系,减少了数据冗余,简化了维护,同时通过合理的索引设计,保证了查询效率。
-
-## 3. 数据关系
-
-### 3.1 主要关系图
-
-```
-                                    ┌───────────────────┐
-                                    │promotion_talent_configs│
-                                    └─────────┬─────────┘
-                                              │
-                                              ▼
-┌───────────────────┐            ┌───────────────────┐
-│promotion_user_referrals│◄───────────┤ promotion_user_talents │
-└─────────┬─────────┘            └─────────┬─────────┘
-          │                                 │
-          │                                 │
-          ├─────────────┐                   │
-          │             │                   │
-          ▼             ▼                   │
-┌───────────────────┐  ┌───────────────────┐│
-│promotion_referral_codes│  │promotion_user_relation_cache│
-└───────────────────┘  └───────────────────┘│
-                                            │
-                                            │
-                                            ▼
-                                  ┌───────────────────┐
-                                  │   promotion_profits    │
-                                  └─────────┬─────────┘
-                                            │
-                                            │
-                                            ▼
-                                  ┌───────────────────┐
-                                  │ promotion_profit_rules │
-                                  └───────────────────┘
-```
-
-### 3.2 关系说明
-
-1. **用户与推荐关系**:一个用户只有一个直接推荐人,但可以有多个被推荐人(1:N)
-2. **用户与达人等级**:一个用户有一个达人等级记录(1:1)
-3. **用户与推荐码**:一个用户有一个推荐码(1:1)
-4. **达人等级与配置**:用户达人等级对应配置表中的等级(N:1)
-5. **用户与收益记录**:一个用户可以有多条收益记录(1:N)
-6. **收益记录与规则**:收益记录根据来源类型对应不同的分成规则(N:1)
-7. **用户与推荐关系修改**:一个用户可以有多条推荐关系修改记录(1:N)
-8. **用户与关系缓存**:一个用户可以有多条关系缓存记录,包括与其上级和下级的关系(1:N)
-9. **推荐关系与关系缓存**:推荐关系表中的直接关系是关系缓存表的数据来源,关系缓存表通过计算扩展为完整的上下级关系网络
-10. **用户与邀请奖励**:一个用户可以有多条邀请奖励记录(1:N)
-11. **被邀请用户与邀请奖励**:一个被邀请用户可以关联多条邀请奖励记录(1:N),例如注册奖励和升级奖励
-12. **推荐码与使用记录**:一个推荐码可以有多条使用记录(1:N)
-13. **用户与邀请码使用**:一个用户可以使用多个邀请码(1:N),但每个邀请码只能被一个用户成功使用
-14. **邀请码所有者与使用记录**:一个邀请码所有者可以有多条邀请码被使用的记录(1:N)
-
-## 4. 索引设计
-
-### 4.1 主键索引
-
-所有表都使用自增的`id`字段作为主键。
-
-### 4.2 唯一索引
-
-- `promotion_user_referrals`: `user_id`(确保每个用户只有一个直接推荐人)
-- `promotion_user_talents`: `user_id`(确保每个用户只有一条达人记录)
-- `promotion_referral_codes`: `code`(确保推荐码唯一)
-- `promotion_referral_codes`: `user_id`(确保每个用户只有一个推荐码)
-- `promotion_talent_configs`: `level`(确保等级唯一)
-- `promotion_profit_rules`: `source_type`(确保来源类型唯一)
-- `promotion_user_relation_cache`: `user_id,related_user_id`(确保用户与上级的关系唯一)
-
-### 4.3 普通索引
-
-- `promotion_user_referrals`: `referrer_id`
-- `promotion_user_talents`: `talent_level`
-- `promotion_profits`: `user_id`, `promotion_member_id`, `source_type,source_id`, `created_at`
-- `promotion_referral_codes`: `status`
-- `promotion_profit_rules`: `status`
-- `promotion_referral_changes`: `user_id`, `change_time`
-- `promotion_user_relation_cache`: `user_id`, `related_user_id`, `level`, `depth`(支持各种查询场景)
-- `promotion_invite_rewards`: `user_id`, `invited_user_id`, `reward_type`, `reward_source`, `status`, `created_at`(支持多种查询和统计场景)
-- `promotion_referral_code_usages`: `code`, `code_owner_id`, `user_id`, `status`, `created_at`(支持邀请码使用记录的多种查询场景)
-
-## 5. JSON字段结构
-
-### 5.1 达人等级权益JSON (benefits)
-
-```json
-{
-  "farm_output_bonus": 0.05,
-  "daily_gift": {
-    "item_id": 1001,
-    "amount": 1
-  },
-  "special_privileges": [
-    "vip_customer_service",
-    "exclusive_avatar_frame"
-  ]
-}
-```
-
-### 5.2 收益分成特殊规则JSON (rules)
-
-```json
-{
-  "min_amount": 10,
-  "max_amount": 1000,
-  "excluded_items": [1001, 1002],
-  "special_rates": [
-    {"talent_level": 5, "bonus_rate": 0.01}
-  ]
-}
-```
-
-## 6. 数据初始化
-
-### 6.1 达人等级配置数据
-
-初始化5级达人的配置数据:
-
-```sql
-INSERT INTO `promotion_talent_configs` (`level`, `name`, `direct_count_required`, `promotion_count_required`, `profit_rate`, `benefits`) VALUES
-(1, '初级达人', 5, 10, 0.0100, '{"farm_output_bonus": 0.01}'),
-(2, '中级达人', 10, 30, 0.0150, '{"farm_output_bonus": 0.02}'),
-(3, '高级达人', 20, 50, 0.0200, '{"farm_output_bonus": 0.03, "daily_gift": {"item_id": 1001, "amount": 1}}'),
-(4, '资深达人', 30, 100, 0.0250, '{"farm_output_bonus": 0.04, "daily_gift": {"item_id": 1001, "amount": 2}}'),
-(5, '顶级达人', 50, 200, 0.0300, '{"farm_output_bonus": 0.05, "daily_gift": {"item_id": 1001, "amount": 3}, "special_privileges": ["vip_customer_service", "exclusive_avatar_frame"]}');
-```
-
-### 6.2 收益分成规则数据
-
-初始化基本的收益分成规则:
-
-```sql
-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}'),
-('task_complete', 0.0300, 10, 1, '{"min_amount": 5, "max_amount": 500}'),
-('item_sell', 0.0200, 5, 1, '{"min_amount": 1, "max_amount": 100, "excluded_items": [1001, 1002]}');
-```
-
-### 6.3 新用户初始化
-
-新用户注册时,需要:
-1. 创建用户达人记录,设置达人等级为0
-2. 生成用户专属推荐码
-3. 如有推荐人,建立推荐关系
-
-## 7. 数据维护
-
-### 7.1 定期任务
-
-1. **达人等级更新**:定期检查和更新用户的达人等级
-2. **推荐码清理**:定期清理过期或无效的推荐码
-3. **收益统计**:定期统计和汇总团队收益数据
-
-### 7.2 数据清理
-
-1. **收益记录归档**:定期归档过旧的收益记录
-2. **无效关系清理**:清理已注销用户的推荐关系
-
-### 7.3 数据备份
-
-定期备份关键数据表,特别是推荐关系表和达人等级表。
-
-## 8. 性能优化
-
-### 8.1 分表策略
-
-当用户数量增长到一定规模时,可以考虑按用户ID范围对`promotion_user_referrals`和`promotion_profits`表进行分表。
-
-### 8.2 缓存策略
-
-1. 缓存达人等级配置和分成规则等静态数据
-2. 缓存用户的推荐关系和达人信息等频繁访问的数据
-3. 使用Redis缓存用户的所有上级(包括直接和间接)
-4. 使用Redis缓存用户的所有下级(包括直接和间接)
-5. 使用数据库缓存表(`promotion_user_relation_cache`)持久化存储用户的上下级关系
-6. 设置合理的缓存过期时间,如1天
-7. 推荐关系变更时主动更新相关缓存和缓存表
-8. 定期校验和修复缓存表数据,确保与实际推荐关系一致
-
-### 8.3 批量操作
-
-使用批量插入和更新操作处理大量数据,如批量更新达人等级。
-
-## 9. 安全考虑
-
-### 9.1 数据加密
-
-对敏感数据进行加密存储,如推荐码的生成算法。
-
-### 9.2 访问控制
-
-严格控制数据访问权限,确保用户只能访问自己的团队数据。
-
-### 9.3 操作日志
-
-记录关键操作的日志,如达人等级变更、推荐关系建立等。
-
-## 10. 总结
-
-团队模块的数据库设计采用关系型数据库,通过合理的表结构设计和索引优化,支持用户推荐关系、达人等级和团队收益分成等核心功能。设计注重数据完整性、查询效率和可扩展性,能够满足大规模用户场景下的性能需求。
-
-本设计采用只存储直接推荐关系 + 缓存策略的方案,在保持较高查询效率的同时,大幅减少了存储空间,并提高了推荐关系修改的灵活性。通过缓存机制优化了查询性能,同时保持了数据的一致性。
-
-通过JSON字段存储复杂配置,提供了灵活的扩展能力,同时通过合理的数据维护策略确保系统长期稳定运行。推荐关系修改记录表的设计,支持了用户推荐关系的可变更性,同时保留了完整的修改历史,便于审计和追踪。

+ 0 - 342
app/Module/Promotion/Docs/枚举定义.md

@@ -1,342 +0,0 @@
-# 团队模块枚举定义
-
-## 1. 概述
-
-本文档定义了团队模块中使用的所有枚举类型,包括推荐关系类型、达人等级、收益来源类型等。这些枚举类型在模块的各个部分都有使用,是理解模块功能的重要基础。
-
-## 2. 推荐关系相关枚举
-
-### 2.1 推荐层级 (REFERRAL_LEVEL)
-
-推荐层级枚举定义了用户之间的推荐关系类型。
-
-```php
-namespace App\Module\Promotion\Enums;
-
-enum REFERRAL_LEVEL: int {
-    case DIRECT = 1;     // 直推关系
-    case INDIRECT = 2;   // 间推关系
-}
-```
-
-#### 推荐层级说明
-
-| 层级类型 | 值 | 说明 | 分成权益 |
-|---------|---|------|---------|
-| 直推关系 | 1 | 用户A直接推荐用户B | 固定比例分成(通常为5%) |
-| 间推关系 | 2 | 用户A通过中间用户间接推荐用户C | 根据达人等级获得分成 |
-
-## 3. 达人等级相关枚举
-
-### 3.1 达人等级 (TALENT_LEVEL)
-
-达人等级枚举定义了用户的达人等级。
-
-```php
-namespace App\Module\Promotion\Enums;
-
-enum TALENT_LEVEL: int {
-    case NONE = 0;       // 非达人
-    case JUNIOR = 1;     // 初级达人
-    case INTERMEDIATE = 2; // 中级达人
-    case SENIOR = 3;     // 高级达人
-    case EXPERT = 4;     // 资深达人
-    case MASTER = 5;     // 顶级达人
-}
-```
-
-#### 达人等级说明
-
-| 达人等级 | 值 | 名称 | 升级条件 | 间推分成比例 |
-|---------|---|------|---------|------------|
-| 非达人 | 0 | 非达人 | 默认 | 0% |
-| 初级达人 | 1 | 初级达人 | 直推5人且团队总人数≥10 | 1% |
-| 中级达人 | 2 | 中级达人 | 直推10人且团队总人数≥30 | 1.5% |
-| 高级达人 | 3 | 高级达人 | 直推20人且团队总人数≥50 | 2% |
-| 资深达人 | 4 | 资深达人 | 直推30人且团队总人数≥100 | 2.5% |
-| 顶级达人 | 5 | 顶级达人 | 直推50人且团队总人数≥200 | 3% |
-
-## 4. 收益相关枚举
-
-### 4.1 收益来源类型 (PROFIT_SOURCE_TYPE)
-
-收益来源类型枚举定义了团队收益的来源。
-
-```php
-namespace App\Module\Promotion\Enums;
-
-enum PROFIT_SOURCE_TYPE: string {
-    case FARM_HARVEST = 'farm_harvest';   // 农场收获
-    case TASK_COMPLETE = 'task_complete'; // 任务完成
-    case ITEM_SELL = 'item_sell';         // 物品出售
-}
-```
-
-#### 收益来源类型说明
-
-| 来源类型 | 值 | 说明 | 默认直推分成 |
-|---------|---|------|------------|
-| 农场收获 | farm_harvest | 来自Farm模块的作物收获 | 5% |
-| 任务完成 | task_complete | 来自Task模块的任务奖励 | 3% |
-| 物品出售 | item_sell | 来自GameItems模块的物品出售 | 2% |
-
-### 4.2 收益记录状态 (PROFIT_RECORD_STATUS)
-
-收益记录状态枚举定义了团队收益记录的状态。
-
-```php
-namespace App\Module\Promotion\Enums;
-
-enum PROFIT_RECORD_STATUS: int {
-    case PENDING = 0;    // 待处理
-    case SUCCESS = 1;    // 成功
-    case FAILED = 2;     // 失败
-}
-```
-
-#### 收益记录状态说明
-
-| 状态 | 值 | 说明 |
-|------|---|------|
-| 待处理 | 0 | 收益记录已创建但尚未处理 |
-| 成功 | 1 | 收益已成功分配到用户账户 |
-| 失败 | 2 | 收益分配失败,需要重试或人工处理 |
-
-## 5. 团队任务相关枚举
-
-### 5.1 团队任务类型 (TEAM_TASK_TYPE)
-
-团队任务类型枚举定义了团队可以执行的任务类型。
-
-```php
-namespace App\Module\Promotion\Enums;
-
-enum TEAM_TASK_TYPE: string {
-    case PLANTING = 'planting';       // 种植任务
-    case HARVESTING = 'harvesting';   // 收获任务
-    case REFERRAL = 'referral';       // 推荐任务
-    case ACTIVITY = 'activity';       // 活跃度任务
-}
-```
-
-#### 团队任务类型说明
-
-| 任务类型 | 值 | 说明 | 完成条件 |
-|---------|---|------|---------|
-| 种植任务 | planting | 团队成员种植特定作物 | 累计种植数量达标 |
-| 收获任务 | harvesting | 团队成员收获特定作物 | 累计收获数量达标 |
-| 推荐任务 | referral | 团队成员发展新成员 | 新增团队成员数量达标 |
-| 活跃度任务 | activity | 团队成员保持活跃 | 活跃成员比例达标 |
-
-### 5.2 团队任务状态 (TEAM_TASK_STATUS)
-
-团队任务状态枚举定义了团队任务的状态。
-
-```php
-namespace App\Module\Promotion\Enums;
-
-enum TEAM_TASK_STATUS: int {
-    case ACTIVE = 1;     // 进行中
-    case COMPLETED = 2;  // 已完成
-    case EXPIRED = 3;    // 已过期
-    case CANCELLED = 4;  // 已取消
-}
-```
-
-#### 团队任务状态说明
-
-| 状态 | 值 | 说明 |
-|------|---|------|
-| 进行中 | 1 | 任务正在进行中 |
-| 已完成 | 2 | 任务已完成并发放奖励 |
-| 已过期 | 3 | 任务未完成但已过期 |
-| 已取消 | 4 | 任务被创建者或管理员取消 |
-
-## 6. 推荐码相关枚举
-
-### 6.1 推荐码状态 (REFERRAL_CODE_STATUS)
-
-推荐码状态枚举定义了推荐码的状态。
-
-```php
-namespace App\Module\Promotion\Enums;
-
-enum REFERRAL_CODE_STATUS: int {
-    case INACTIVE = 0;   // 未激活
-    case ACTIVE = 1;     // 有效
-    case DISABLED = 2;   // 已禁用
-}
-```
-
-#### 推荐码状态说明
-
-| 状态 | 值 | 说明 |
-|------|---|------|
-| 未激活 | 0 | 推荐码已生成但尚未激活 |
-| 有效 | 1 | 推荐码有效,可以使用 |
-| 已禁用 | 2 | 推荐码已被禁用,无法使用 |
-
-## 7. 枚举使用示例
-
-### 7.1 推荐关系类型判断
-
-```php
-// 判断是否为直推关系
-public function isDirectReferral(int $level): bool
-{
-    return $level == REFERRAL_LEVEL::DIRECT;
-}
-
-// 获取推荐关系描述
-public function getReferralLevelDescription(int $level): string
-{
-    switch ($level) {
-        case REFERRAL_LEVEL::DIRECT:
-            return '直接推荐';
-        case REFERRAL_LEVEL::INDIRECT:
-            return '间接推荐';
-        default:
-            return '未知关系';
-    }
-}
-```
-
-### 7.2 达人等级判断
-
-```php
-// 判断是否为达人
-public function isTalent(int $level): bool
-{
-    return $level > TALENT_LEVEL::NONE;
-}
-
-// 获取达人等级名称
-public function getTalentLevelName(int $level): string
-{
-    switch ($level) {
-        case TALENT_LEVEL::NONE:
-            return '非达人';
-        case TALENT_LEVEL::JUNIOR:
-            return '初级达人';
-        case TALENT_LEVEL::INTERMEDIATE:
-            return '中级达人';
-        case TALENT_LEVEL::SENIOR:
-            return '高级达人';
-        case TALENT_LEVEL::EXPERT:
-            return '资深达人';
-        case TALENT_LEVEL::MASTER:
-            return '顶级达人';
-        default:
-            return '未知等级';
-    }
-}
-```
-
-### 7.3 收益来源类型判断
-
-```php
-// 判断是否为农场收益
-public function isFarmProfit(string $sourceType): bool
-{
-    return $sourceType == PROFIT_SOURCE_TYPE::FARM_HARVEST;
-}
-
-// 获取收益来源描述
-public function getProfitSourceDescription(string $sourceType): string
-{
-    switch ($sourceType) {
-        case PROFIT_SOURCE_TYPE::FARM_HARVEST:
-            return '农场收获';
-        case PROFIT_SOURCE_TYPE::TASK_COMPLETE:
-            return '任务完成';
-        case PROFIT_SOURCE_TYPE::ITEM_SELL:
-            return '物品出售';
-        default:
-            return '未知来源';
-    }
-}
-```
-
-### 7.4 团队任务状态判断
-
-```php
-// 判断任务是否可以参与
-public function isTaskJoinable(int $status): bool
-{
-    return $status == TEAM_TASK_STATUS::ACTIVE;
-}
-
-// 获取任务状态描述
-public function getTaskStatusDescription(int $status): string
-{
-    switch ($status) {
-        case TEAM_TASK_STATUS::ACTIVE:
-            return '进行中';
-        case TEAM_TASK_STATUS::COMPLETED:
-            return '已完成';
-        case TEAM_TASK_STATUS::EXPIRED:
-            return '已过期';
-        case TEAM_TASK_STATUS::CANCELLED:
-            return '已取消';
-        default:
-            return '未知状态';
-    }
-}
-```
-
-## 8. 枚举扩展指南
-
-如需添加新的枚举值,请按照以下步骤操作:
-
-1. 在对应的枚举类中添加新的枚举值
-2. 更新相关的业务逻辑,处理新的枚举值
-3. 更新前端展示逻辑,显示新的枚举值
-4. 更新文档,说明新的枚举值的含义和用法
-
-例如,添加新的达人等级:
-
-```php
-// 在TALENT_LEVEL枚举中添加新的达人等级
-enum TALENT_LEVEL: int {
-    case NONE = 0;       // 非达人
-    case JUNIOR = 1;     // 初级达人
-    case INTERMEDIATE = 2; // 中级达人
-    case SENIOR = 3;     // 高级达人
-    case EXPERT = 4;     // 资深达人
-    case MASTER = 5;     // 顶级达人
-    case LEGENDARY = 6;  // 传奇达人(新增)
-}
-```
-
-然后更新相关的业务逻辑:
-
-```php
-// 在TalentService中添加新达人等级的分成比例
-public function getTalentProfitRate(int $level): float
-{
-    switch ($level) {
-        case TALENT_LEVEL::NONE:
-            return 0.0;
-        case TALENT_LEVEL::JUNIOR:
-            return 0.01;
-        case TALENT_LEVEL::INTERMEDIATE:
-            return 0.015;
-        case TALENT_LEVEL::SENIOR:
-            return 0.02;
-        case TALENT_LEVEL::EXPERT:
-            return 0.025;
-        case TALENT_LEVEL::MASTER:
-            return 0.03;
-        case TALENT_LEVEL::LEGENDARY:  // 新增
-            return 0.035;
-        default:
-            return 0.0;
-    }
-}
-```
-
-## 9. 总结
-
-本文档定义了团队模块中使用的所有枚举类型,包括推荐关系类型、达人等级、收益来源类型等。这些枚举类型是模块功能的重要基础,理解这些枚举类型有助于理解模块的整体功能和业务逻辑。
-
-在开发过程中,应该严格按照枚举定义使用这些类型,避免使用魔法数字或字符串,以提高代码的可读性和可维护性。如需添加新的枚举值,请按照枚举扩展指南进行操作,确保相关的业务逻辑和文档都得到更新。

+ 0 - 828
app/Module/Promotion/Docs/模块接口.md

@@ -1,828 +0,0 @@
-# 团队模块接口
-
-## 1. 概述
-
-团队模块对外提供一系列服务接口,用于管理用户推荐关系、达人等级和团队收益分成。这些接口主要供其他模块调用,实现模块间的交互和数据共享。本文档详细说明了团队模块提供的服务接口、参数和返回值。
-
-## 2. 接口规范
-
-### 2.1 接口命名规范
-
-- 接口方法名采用驼峰命名法,如`createReferralRelation`
-- 接口方法名应清晰表达功能,动词开头,如`getUserReferrers`
-- 查询类接口使用`get`前缀,如`getUserTalentInfo`
-- 创建类接口使用`create`前缀,如`createReferralCode`
-- 更新类接口使用`update`前缀,如`updateUserTalent`
-- 删除类接口使用`delete`前缀,如`deleteReferralRelation`
-- 检查类接口使用`check`前缀,如`checkReferralCode`
-
-### 2.2 参数规范
-
-- 必选参数放在前面,可选参数放在后面
-- 参数类型明确,使用强类型
-- 复杂参数使用数组或对象传递
-- 敏感参数不直接暴露,如密码等
-
-### 2.3 返回值规范
-
-- 返回值类型明确,使用强类型
-- 成功操作返回布尔值或操作结果
-- 查询操作返回数据对象或数组
-- 异常情况抛出异常,不返回错误码
-
-### 2.4 异常处理
-
-- 业务异常使用自定义异常类,如`ReferralException`
-- 异常信息清晰明确,便于定位问题
-- 异常包含错误码和错误信息
-- 调用方需捕获并处理异常
-
-## 3. 推荐关系服务接口 (ReferralService)
-
-### 3.1 建立推荐关系
-
-```php
-/**
- * 建立推荐关系
- * 
- * @param int $userId 用户ID
- * @param int $referrerId 推荐人ID
- * @return bool 是否成功
- * @throws UserNotFoundException 用户不存在异常
- * @throws ReferralException 推荐关系异常
- */
-public function createReferralRelation(int $userId, int $referrerId): bool;
-```
-
-**功能说明**:
-- 建立用户与推荐人之间的推荐关系
-- 同时建立直推和间推关系
-- 更新推荐人的直推人数和团队总人数
-- 触发检查达人等级
-
-**调用示例**:
-```php
-try {
-    $result = $referralService->createReferralRelation(1001, 1000);
-    if ($result) {
-        // 推荐关系建立成功
-    }
-} catch (UserNotFoundException $e) {
-    // 用户不存在
-} catch (ReferralException $e) {
-    // 推荐关系异常
-}
-```
-
-### 3.2 获取用户的推荐人
-
-```php
-/**
- * 获取用户的推荐人
- * 
- * @param int $userId 用户ID
- * @param int $level 推荐层级(1=直推,2=间推,0=全部)
- * @return array 推荐人列表
- */
-public function getUserReferrers(int $userId, int $level = 0): array;
-```
-
-**功能说明**:
-- 获取用户的所有推荐人(上级)
-- 可以指定只获取直推或间推关系
-- 返回推荐人的基本信息和推荐关系
-
-**调用示例**:
-```php
-// 获取所有推荐人
-$allReferrers = $referralService->getUserReferrers(1001);
-
-// 只获取直推推荐人
-$directReferrers = $referralService->getUserReferrers(1001, 1);
-```
-
-### 3.3 获取用户的团队成员
-
-```php
-/**
- * 获取用户的团队成员
- * 
- * @param int $userId 用户ID
- * @param int $level 推荐层级(1=直推,2=间推,0=全部)
- * @param int $page 页码
- * @param int $pageSize 每页数量
- * @return array 团队成员列表和分页信息
- */
-public function getPromotionMembers(int $userId, int $level = 0, int $page = 1, int $pageSize = 20): array;
-```
-
-**功能说明**:
-- 获取用户的所有团队成员(下级)
-- 可以指定只获取直推或间推成员
-- 支持分页查询
-- 返回团队成员的基本信息和推荐关系
-
-**调用示例**:
-```php
-// 获取所有团队成员,第1页,每页20条
-$allMembers = $referralService->getPromotionMembers(1000);
-
-// 只获取直推成员,第1页,每页50条
-$directMembers = $referralService->getPromotionMembers(1000, 1, 1, 50);
-```
-
-### 3.4 检查推荐关系
-
-```php
-/**
- * 检查用户是否是另一用户的推荐人
- * 
- * @param int $userId 用户ID
- * @param int $memberId 成员ID
- * @param int $level 推荐层级(1=直推,2=间推,0=任意层级)
- * @return bool 是否存在推荐关系
- */
-public function checkReferralRelation(int $userId, int $memberId, int $level = 0): bool;
-```
-
-**功能说明**:
-- 检查用户是否是另一用户的推荐人
-- 可以指定检查直推或间推关系
-- 返回布尔值表示是否存在推荐关系
-
-**调用示例**:
-```php
-// 检查用户1000是否是用户1001的推荐人(任意层级)
-$isReferrer = $referralService->checkReferralRelation(1000, 1001);
-
-// 检查用户1000是否是用户1001的直推推荐人
-$isDirectReferrer = $referralService->checkReferralRelation(1000, 1001, 1);
-```
-
-### 3.5 生成推荐码
-
-```php
-/**
- * 生成用户推荐码
- * 
- * @param int $userId 用户ID
- * @return string 推荐码
- * @throws UserNotFoundException 用户不存在异常
- */
-public function generateReferralCode(int $userId): string;
-```
-
-**功能说明**:
-- 为用户生成唯一的推荐码
-- 如果用户已有推荐码,则返回现有推荐码
-- 推荐码可用于邀请新用户注册
-
-**调用示例**:
-```php
-try {
-    $code = $referralService->generateReferralCode(1000);
-    // 生成的推荐码
-} catch (UserNotFoundException $e) {
-    // 用户不存在
-}
-```
-
-### 3.6 验证推荐码
-
-```php
-/**
- * 验证推荐码并获取推荐人ID
- * 
- * @param string $code 推荐码
- * @return int|null 推荐人ID,无效返回null
- */
-public function verifyReferralCode(string $code): ?int;
-```
-
-**功能说明**:
-- 验证推荐码的有效性
-- 返回推荐码对应的用户ID
-- 无效推荐码返回null
-
-**调用示例**:
-```php
-$referrerId = $referralService->verifyReferralCode('ABC123');
-if ($referrerId !== null) {
-    // 有效的推荐码,获取到推荐人ID
-} else {
-    // 无效的推荐码
-}
-```
-
-## 4. 达人等级服务接口 (TalentService)
-
-### 4.1 获取用户达人信息
-
-```php
-/**
- * 获取用户达人信息
- * 
- * @param int $userId 用户ID
- * @return array 达人信息
- */
-public function getUserTalentInfo(int $userId): array;
-```
-
-**功能说明**:
-- 获取用户的达人等级信息
-- 包括达人等级、直推人数、团队总人数等
-- 同时返回达人等级对应的权益信息
-
-**调用示例**:
-```php
-$talentInfo = $talentService->getUserTalentInfo(1000);
-// 达人信息数组
-```
-
-### 4.2 检查并更新达人等级
-
-```php
-/**
- * 检查并更新用户达人等级
- * 
- * @param int $userId 用户ID
- * @return bool 是否有等级变化
- */
-public function checkAndUpdateTalentLevel(int $userId): bool;
-```
-
-**功能说明**:
-- 检查用户的团队规模,计算新的达人等级
-- 如果等级有变化,更新用户的达人等级
-- 等级提升时触发达人升级事件
-
-**调用示例**:
-```php
-$levelChanged = $talentService->checkAndUpdateTalentLevel(1000);
-if ($levelChanged) {
-    // 达人等级有变化
-}
-```
-
-### 4.3 获取达人等级配置
-
-```php
-/**
- * 获取达人等级配置
- * 
- * @param int $level 达人等级,0表示获取所有等级
- * @return array 达人等级配置
- */
-public function getTalentLevelConfig(int $level = 0): array;
-```
-
-**功能说明**:
-- 获取指定达人等级的配置信息
-- 包括等级名称、升级条件、权益等
-- 可以获取所有等级的配置信息
-
-**调用示例**:
-```php
-// 获取所有达人等级配置
-$allConfigs = $talentService->getTalentLevelConfig();
-
-// 获取3级达人的配置
-$level3Config = $talentService->getTalentLevelConfig(3);
-```
-
-### 4.4 获取达人等级分成比例
-
-```php
-/**
- * 获取达人等级的间推分成比例
- * 
- * @param int $level 达人等级
- * @return float 分成比例
- */
-public function getTalentProfitRate(int $level): float;
-```
-
-**功能说明**:
-- 获取指定达人等级的间推分成比例
-- 用于计算团队收益分成
-- 非达人(0级)返回0
-
-**调用示例**:
-```php
-// 获取3级达人的分成比例
-$rate = $talentService->getTalentProfitRate(3);
-// 返回0.02 (2%)
-```
-
-## 5. 团队收益服务接口 (PromotionProfitService)
-
-### 5.1 计算团队收益分成
-
-```php
-/**
- * 计算团队收益分成
- * 
- * @param int $userId 产生收益的用户ID
- * @param string $sourceType 收益来源类型
- * @param int $sourceId 收益来源ID
- * @param int $itemId 物品ID
- * @param int $amount 收益数量
- * @return bool 是否成功
- */
-public function calculatePromotionProfit(int $userId, string $sourceType, int $sourceId, int $itemId, int $amount): bool;
-```
-
-**功能说明**:
-- 计算用户产生收益时的团队分成
-- 根据推荐关系和达人等级计算分成比例
-- 记录分成收益并添加到推荐人账户
-- 支持多种收益来源类型
-
-**调用示例**:
-```php
-// 用户1001收获农场作物,产生100个物品ID为2001的收益
-$result = $promotionProfitService->calculatePromotionProfit(1001, 'farm_harvest', 5001, 2001, 100);
-if ($result) {
-    // 分成计算成功
-}
-```
-
-### 5.2 获取用户团队收益统计
-
-```php
-/**
- * 获取用户团队收益统计
- * 
- * @param int $userId 用户ID
- * @param string $sourceType 收益来源类型,空字符串表示所有类型
- * @param string $timeRange 时间范围(today,yesterday,week,month,all)
- * @return array 收益统计
- */
-public function getUserPromotionProfitStats(int $userId, string $sourceType = '', string $timeRange = 'all'): array;
-```
-
-**功能说明**:
-- 获取用户的团队收益统计数据
-- 可以按收益来源类型和时间范围筛选
-- 返回总收益、直推收益、间推收益等统计数据
-
-**调用示例**:
-```php
-// 获取用户1000的所有团队收益统计
-$allStats = $promotionProfitService->getUserPromotionProfitStats(1000);
-
-// 获取用户1000的本月农场收益统计
-$farmMonthStats = $promotionProfitService->getUserPromotionProfitStats(1000, 'farm_harvest', 'month');
-```
-
-### 5.3 获取用户团队收益记录
-
-```php
-/**
- * 获取用户团队收益记录
- * 
- * @param int $userId 用户ID
- * @param string $sourceType 收益来源类型,空字符串表示所有类型
- * @param int $page 页码
- * @param int $pageSize 每页数量
- * @return array 收益记录和分页信息
- */
-public function getUserPromotionProfitRecords(int $userId, string $sourceType = '', int $page = 1, int $pageSize = 20): array;
-```
-
-**功能说明**:
-- 获取用户的团队收益详细记录
-- 可以按收益来源类型筛选
-- 支持分页查询
-- 返回收益记录的详细信息
-
-**调用示例**:
-```php
-// 获取用户1000的所有团队收益记录,第1页,每页20条
-$allRecords = $promotionProfitService->getUserPromotionProfitRecords(1000);
-
-// 获取用户1000的农场收益记录,第1页,每页50条
-$farmRecords = $promotionProfitService->getUserPromotionProfitRecords(1000, 'farm_harvest', 1, 50);
-```
-
-### 5.4 获取收益分成规则
-
-```php
-/**
- * 获取收益分成规则
- * 
- * @param string $sourceType 收益来源类型
- * @return array 分成规则
- */
-public function getProfitRule(string $sourceType): array;
-```
-
-**功能说明**:
-- 获取指定收益来源类型的分成规则
-- 包括直推分成比例、最大间推层级等
-- 用于计算团队收益分成
-
-**调用示例**:
-```php
-// 获取农场收益的分成规则
-$farmRule = $promotionProfitService->getProfitRule('farm_harvest');
-```
-
-## 6. 事件接口
-
-团队模块会触发以下事件,其他模块可以监听这些事件:
-
-### 6.1 达人等级提升事件 (TalentLevelUpEvent)
-
-```php
-/**
- * 达人等级提升事件
- */
-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;
-    }
-}
-```
-
-**事件说明**:
-- 当用户达人等级提升时触发
-- 包含用户ID、旧等级和新等级
-- 可用于任务完成、发放奖励等
-
-**监听示例**:
-```php
-// 在EventServiceProvider中注册监听器
-protected $listen = [
-    'App\Module\Promotion\Events\TalentLevelUpEvent' => [
-        'App\Module\Task\Listeners\TalentLevelUpListener',
-    ],
-];
-
-// 监听器实现
-public function handle(TalentLevelUpEvent $event)
-{
-    // 处理达人等级提升事件
-    $userId = $event->userId;
-    $newLevel = $event->newLevel;
-    
-    // 完成相关任务
-    $this->taskService->completeTask($userId, 'talent_level_up', ['level' => $newLevel]);
-}
-```
-
-### 6.2 推荐关系创建事件 (ReferralCreatedEvent)
-
-```php
-/**
- * 推荐关系创建事件
- */
-class ReferralCreatedEvent
-{
-    /**
-     * @var int 用户ID
-     */
-    public $userId;
-    
-    /**
-     * @var int 推荐人ID
-     */
-    public $referrerId;
-    
-    /**
-     * @var int 推荐层级
-     */
-    public $level;
-    
-    /**
-     * 构造函数
-     */
-    public function __construct(int $userId, int $referrerId, int $level)
-    {
-        $this->userId = $userId;
-        $this->referrerId = $referrerId;
-        $this->level = $level;
-    }
-}
-```
-
-**事件说明**:
-- 当建立新的推荐关系时触发
-- 包含用户ID、推荐人ID和推荐层级
-- 可用于任务完成、发放奖励等
-
-**监听示例**:
-```php
-// 在EventServiceProvider中注册监听器
-protected $listen = [
-    'App\Module\Promotion\Events\ReferralCreatedEvent' => [
-        'App\Module\Task\Listeners\ReferralCreatedListener',
-    ],
-];
-
-// 监听器实现
-public function handle(ReferralCreatedEvent $event)
-{
-    // 处理推荐关系创建事件
-    $userId = $event->userId;
-    $referrerId = $event->referrerId;
-    
-    // 完成相关任务
-    if ($event->level == 1) {
-        $this->taskService->completeTask($referrerId, 'direct_referral');
-    }
-}
-```
-
-## 7. 监听的事件
-
-团队模块会监听以下来自其他模块的事件:
-
-### 7.1 用户注册事件 (UserRegisteredEvent)
-
-```php
-// 用户模块中定义的事件
-namespace App\Module\User\Events;
-
-class UserRegisteredEvent
-{
-    /**
-     * @var int 用户ID
-     */
-    public $userId;
-    
-    /**
-     * @var string 推荐码
-     */
-    public $referralCode;
-    
-    /**
-     * 构造函数
-     */
-    public function __construct(int $userId, string $referralCode = '')
-    {
-        $this->userId = $userId;
-        $this->referralCode = $referralCode;
-    }
-}
-```
-
-**监听处理**:
-```php
-namespace App\Module\Promotion\Listeners;
-
-use App\Module\User\Events\UserRegisteredEvent;
-use App\Module\Promotion\Services\ReferralService;
-
-class UserRegisteredListener
-{
-    /**
-     * @var ReferralService
-     */
-    protected $referralService;
-    
-    /**
-     * 构造函数
-     */
-    public function __construct(ReferralService $referralService)
-    {
-        $this->referralService = $referralService;
-    }
-    
-    /**
-     * 处理事件
-     */
-    public function handle(UserRegisteredEvent $event)
-    {
-        // 处理用户注册事件
-        $userId = $event->userId;
-        $referralCode = $event->referralCode;
-        
-        // 验证推荐码
-        if (!empty($referralCode)) {
-            $referrerId = $this->referralService->verifyReferralCode($referralCode);
-            if ($referrerId !== null) {
-                // 建立推荐关系
-                $this->referralService->createReferralRelation($userId, $referrerId);
-            }
-        }
-        
-        // 生成用户推荐码
-        $this->referralService->generateReferralCode($userId);
-    }
-}
-```
-
-### 7.2 作物收获事件 (CropHarvestedEvent)
-
-```php
-// 农场模块中定义的事件
-namespace App\Module\Farm\Events;
-
-class CropHarvestedEvent
-{
-    /**
-     * @var int 用户ID
-     */
-    public $userId;
-    
-    /**
-     * @var int 作物ID
-     */
-    public $cropId;
-    
-    /**
-     * @var int 产出物品ID
-     */
-    public $itemId;
-    
-    /**
-     * @var int 产出数量
-     */
-    public $amount;
-    
-    /**
-     * 构造函数
-     */
-    public function __construct(int $userId, int $cropId, int $itemId, int $amount)
-    {
-        $this->userId = $userId;
-        $this->cropId = $cropId;
-        $this->itemId = $itemId;
-        $this->amount = $amount;
-    }
-}
-```
-
-**监听处理**:
-```php
-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)
-    {
-        // 处理作物收获事件
-        $userId = $event->userId;
-        $cropId = $event->cropId;
-        $itemId = $event->itemId;
-        $amount = $event->amount;
-        
-        // 计算团队收益分成
-        $this->promotionProfitService->calculatePromotionProfit(
-            $userId,
-            'farm_harvest',
-            $cropId,
-            $itemId,
-            $amount
-        );
-    }
-}
-```
-
-## 8. 接口使用示例
-
-### 8.1 用户注册时建立推荐关系
-
-```php
-// 用户注册处理
-public function register(Request $request)
-{
-    // 创建用户
-    $userId = $this->userService->createUser($request->all());
-    
-    // 处理推荐码
-    $referralCode = $request->input('referral_code');
-    if (!empty($referralCode)) {
-        try {
-            // 验证推荐码
-            $referrerId = $this->referralService->verifyReferralCode($referralCode);
-            if ($referrerId !== null) {
-                // 建立推荐关系
-                $this->referralService->createReferralRelation($userId, $referrerId);
-            }
-        } catch (\Exception $e) {
-            // 处理异常
-            Log::error('建立推荐关系失败', [
-                'user_id' => $userId,
-                'referral_code' => $referralCode,
-                'error' => $e->getMessage()
-            ]);
-        }
-    }
-    
-    // 生成用户推荐码
-    $this->referralService->generateReferralCode($userId);
-    
-    // 返回结果
-    return response()->json([
-        'success' => true,
-        'user_id' => $userId
-    ]);
-}
-```
-
-### 8.2 作物收获时计算团队收益
-
-```php
-// 作物收获处理
-public function harvestCrop(int $cropId)
-{
-    return DB::transaction(function () use ($cropId) {
-        // 收获作物
-        $result = $this->cropService->harvestCrop($cropId);
-        
-        // 获取收获信息
-        $userId = $result['user_id'];
-        $itemId = $result['item_id'];
-        $amount = $result['amount'];
-        
-        // 计算团队收益分成
-        $this->promotionProfitService->calculatePromotionProfit(
-            $userId,
-            'farm_harvest',
-            $cropId,
-            $itemId,
-            $amount
-        );
-        
-        // 触发作物收获事件
-        event(new CropHarvestedEvent($userId, $cropId, $itemId, $amount));
-        
-        return $result;
-    });
-}
-```
-
-### 8.3 获取用户团队信息
-
-```php
-// 获取用户团队信息
-public function getUserPromotionInfo(int $userId)
-{
-    // 获取用户达人信息
-    $talentInfo = $this->talentService->getUserTalentInfo($userId);
-    
-    // 获取直推成员
-    $directMembers = $this->referralService->getPromotionMembers($userId, 1, 1, 10);
-    
-    // 获取团队收益统计
-    $profitStats = $this->promotionProfitService->getUserPromotionProfitStats($userId);
-    
-    // 获取最近收益记录
-    $recentProfits = $this->promotionProfitService->getUserPromotionProfitRecords($userId, '', 1, 5);
-    
-    // 返回结果
-    return [
-        'talent_info' => $talentInfo,
-        'direct_members' => $directMembers,
-        'profit_stats' => $profitStats,
-        'recent_profits' => $recentProfits
-    ];
-}
-```
-
-## 9. 总结
-
-团队模块提供了丰富的服务接口,用于管理用户推荐关系、达人等级和团队收益分成。这些接口设计清晰、功能完善,能够满足团队系统的各种需求。通过事件机制,团队模块与其他模块保持松耦合的交互方式,提高了系统的可维护性和可扩展性。在使用这些接口时,需要注意异常处理和事务管理,确保数据的一致性和完整性。

+ 0 - 129
app/Module/Promotion/Docs/直间推收益机制.md

@@ -1,129 +0,0 @@
-# 直间推收益机制
-
-## 1. 概述
-
-直间推收益机制是团队模块的核心功能之一,通过建立用户间的推荐关系,在团队成员产生收益时,按照一定比例分配给上级推荐人,形成多层级的收益分成体系,鼓励用户发展团队,形成良性的社交生态。
-
-## 2. 推荐关系定义
-
-### 2.1 直推关系
-
-用户A直接推荐用户B注册,则用户A是用户B的直推上级(直接推荐人)。直推关系是一级关系,直接存储在数据库中。
-
-### 2.2 间推关系
-
-用户A推荐用户B,用户B推荐用户C,则用户A是用户C的间推上级。间推关系是多级关系,可以通过直推关系递归计算得到,或通过缓存优化查询性能。
-
-### 2.3 团队成员
-
-用户的所有直推和间推下级构成该用户的团队。团队规模是衡量用户影响力的重要指标,也是达人等级评定的主要依据。
-
-## 3. 收益分成比例
-
-### 3.1 直推分成比例
-
-直推上级获得下级收益的**5%**。这一比例固定不变,不受达人等级影响。
-
-例如:用户B收获农作物获得100单位收益,其直推上级用户A将获得5单位分成收益。
-
-### 3.2 间推分成比例
-
-间推分成比例与达人等级相关,具体如下:
-
-| 达人等级 | 名称 | 间推分成比例 |
-|---------|------|------------|
-| 0 | 非达人 | 0% |
-| 1 | 初级达人 | 1% |
-| 2 | 中级达人 | 1.5% |
-| 3 | 高级达人 | 2% |
-| 4 | 资深达人 | 2.5% |
-| 5 | 顶级达人 | 3% |
-
-例如:用户C收获农作物获得100单位收益,其间推上级用户A若为顶级达人,将获得3单位分成收益。
-
-### 3.3 分成范围限制
-
-间推分成仅对**20代以内**的团队成员有效。超过20代的间推关系不产生收益分成。
-
-这一限制是为了控制收益分配的深度,避免过度分散收益,同时也是出于系统性能考虑。
-
-## 4. 收益来源类型
-
-### 4.1 农场收获收益
-
-当团队成员在农场收获作物时,系统会根据收获数量计算分成收益。
-
-收益计算公式:
-- 直推分成 = 收获数量 × 5%
-- 间推分成 = 收获数量 × 达人等级对应分成比例
-
-### 4.2 其他可能的收益来源
-
-系统设计支持扩展其他收益来源类型,如:
-- 任务完成奖励
-- 活动参与奖励
-- 商店销售收益
-
-每种收益来源可以配置不同的分成规则。
-
-## 5. 收益分成流程
-
-### 5.1 收益产生
-
-1. 用户完成收益产生动作(如收获农作物)
-2. 系统记录原始收益
-3. 触发收益分成事件
-
-### 5.2 分成计算
-
-1. 获取用户的所有上级(直推和间推)
-2. 根据推荐关系类型和达人等级计算分成比例
-3. 计算每个上级的分成金额
-
-### 5.3 分成发放
-
-1. 记录分成收益明细
-2. 将分成收益添加到上级账户
-3. 通知上级收到团队收益
-
-## 6. 示例场景
-
-假设推荐链为:A → B → C → D(A推荐B,B推荐C,C推荐D)
-
-当D收获农作物获得1000单位收益时:
-
-1. C作为D的直推上级,获得:1000 × 5% = 50单位
-2. B作为D的间推上级(假设B是中级达人),获得:1000 × 1.5% = 15单位
-3. A作为D的间推上级(假设A是顶级达人),获得:1000 × 3% = 30单位
-
-总分成:50 + 15 + 30 = 95单位(占原始收益的9.5%)
-
-## 7. 注意事项
-
-1. **收益上限**:系统可能设置单次分成的上限,防止极端情况下的过度分成
-2. **最小分成单位**:分成计算结果会四舍五入到最小单位,避免出现小数
-3. **分成记录**:所有分成操作都会详细记录,便于用户查询和系统审计
-4. **达人等级变化**:当用户达人等级变化时,将立即影响其间推分成比例
-5. **推荐关系变更**:推荐关系一旦建立,通常不允许变更,以维护系统稳定性
-
-## 8. 与其他模块的交互
-
-### 8.1 与Farm模块交互
-
-- 监听Farm模块的作物收获事件
-- 获取收获数量和作物类型
-- 计算并分配团队收益
-
-### 8.2 与User模块交互
-
-- 获取用户基本信息
-- 验证用户状态和权限
-
-### 8.3 与GameItems模块交互
-
-- 将分成收益添加到用户物品库
-- 记录收益来源和分成比例
-
-## 9. 总结
-
-直间推收益机制是团队系统的核心功能,通过合理的分成比例设计,既鼓励用户发展直接下级,也激励用户提升达人等级以获得更高的间推分成。这种多层级的收益分成体系,有效促进了用户社交网络的扩展和活跃度的提升,是游戏社交生态的重要支撑。

+ 0 - 793
app/Module/Promotion/Docs/缓存策略.md

@@ -1,793 +0,0 @@
-# 团队模块缓存策略
-
-## 1. 概述
-
-团队模块采用只存储直接推荐关系 + 缓存策略的设计方案,通过缓存机制优化查询性能,同时保持数据的一致性。本文档详细说明团队模块的缓存策略,包括缓存内容、缓存键设计、缓存更新策略和缓存失效机制。
-
-## 2. 缓存内容
-
-### 2.1 推荐关系缓存
-
-推荐关系是团队模块最核心的数据,也是查询频率最高的数据。系统缓存以下推荐关系数据:
-
-1. **用户的所有上级**:包括直接上级(直推)和间接上级(间推)
-2. **用户的所有下级**:包括直接下级(直推)和间接下级(间推)
-3. **用户的直推人数**:用户直接推荐的人数
-4. **用户的团队总人数**:用户团队中的总人数(包括直推和间推)
-
-### 2.2 达人等级缓存
-
-达人等级相关的数据变更频率较低,但查询频率较高:
-
-1. **用户的达人等级**:用户当前的达人等级
-2. **达人等级配置**:各个达人等级的配置信息
-3. **达人分成比例**:各个达人等级对应的分成比例
-
-### 2.3 收益分成规则缓存
-
-收益分成规则是相对静态的数据,适合长期缓存:
-
-1. **分成规则**:不同来源类型的分成规则
-2. **直推分成比例**:直推关系的分成比例
-3. **间推分成比例**:间推关系的分成比例(与达人等级相关)
-
-## 3. 缓存键设计
-
-### 3.1 推荐关系缓存键
-
-```
-// 用户的所有上级(包括直接和间接)
-promotion:user:{userId}:all_referrers
-
-// 用户的所有下级(包括直接和间接)
-promotion:user:{userId}:all_members
-
-// 用户的直推人数
-promotion:user:{userId}:direct_count
-
-// 用户的团队总人数
-promotion:user:{userId}:promotion_count
-```
-
-### 3.2 达人等级缓存键
-
-```
-// 用户的达人等级
-promotion:user:{userId}:talent_level
-
-// 达人等级配置
-promotion:talent_config:{level}
-
-// 所有达人等级配置
-promotion:talent_configs
-```
-
-### 3.3 收益分成规则缓存键
-
-```
-// 分成规则
-promotion:profit_rule:{sourceType}
-
-// 所有分成规则
-promotion:profit_rules
-```
-
-## 4. 缓存值结构
-
-### 4.1 推荐关系缓存值
-
-```json
-// 用户的所有上级
-[
-  {
-    "user_id": 1,
-    "level": 1,
-    "created_at": "2023-05-01 10:00:00"
-  },
-  {
-    "user_id": 2,
-    "level": 2,
-    "created_at": "2023-05-01 10:00:00"
-  }
-]
-
-// 用户的所有下级
-[
-  {
-    "user_id": 3,
-    "level": 1,
-    "created_at": "2023-05-01 11:00:00"
-  },
-  {
-    "user_id": 4,
-    "level": 2,
-    "created_at": "2023-05-01 12:00:00"
-  }
-]
-
-// 用户的直推人数
-5
-
-// 用户的团队总人数
-20
-```
-
-### 4.2 达人等级缓存值
-
-```json
-// 用户的达人等级
-{
-  "talent_level": 3,
-  "direct_count": 20,
-  "promotion_count": 50
-}
-
-// 达人等级配置
-{
-  "level": 3,
-  "name": "高级达人",
-  "direct_count_required": 20,
-  "promotion_count_required": 50,
-  "profit_rate": 0.02,
-  "benefits": {
-    "farm_output_bonus": 0.03,
-    "daily_gift": {
-      "item_id": 1001,
-      "amount": 1
-    }
-  }
-}
-```
-
-### 4.3 收益分成规则缓存值
-
-```json
-// 分成规则
-{
-  "source_type": "farm_harvest",
-  "direct_profit_rate": 0.05,
-  "max_indirect_level": 20,
-  "status": 1,
-  "rules": {
-    "min_amount": 10,
-    "max_amount": 1000
-  }
-}
-```
-
-## 5. 缓存更新策略
-
-### 5.1 懒加载更新
-
-对于查询频率较高但不需要实时性的数据,采用懒加载更新策略:
-
-```php
-/**
- * 获取用户的所有上级(懒加载更新)
- */
-public function getAllReferrers(int $userId): array
-{
-    // 缓存键
-    $cacheKey = "promotion:user:{$userId}:all_referrers";
-    
-    // 尝试从缓存获取
-    $cachedData = Redis::get($cacheKey);
-    if ($cachedData !== null) {
-        return json_decode($cachedData, true);
-    }
-    
-    // 缓存未命中,计算数据
-    $allReferrers = [];
-    $this->calculateAllReferrers($userId, $allReferrers);
-    
-    // 缓存数据
-    Redis::setex($cacheKey, 86400, json_encode($allReferrers)); // 缓存1天
-    
-    return $allReferrers;
-}
-```
-
-### 5.2 主动更新
-
-对于变更频率较低但需要实时性的数据,采用主动更新策略:
-
-```php
-/**
- * 更新用户的推荐关系(主动更新)
- */
-public function updateReferralRelation(int $userId, int $newReferrerId): bool
-{
-    // 更新数据库
-    $result = $this->referralRepository->updateReferrer($userId, $newReferrerId);
-    
-    if ($result) {
-        // 清除相关缓存
-        $this->clearReferralCaches($userId, $this->getOldReferrerId($userId), $newReferrerId);
-    }
-    
-    return $result;
-}
-
-/**
- * 清除推荐关系相关的缓存
- */
-private function clearReferralCaches(int $userId, ?int $oldReferrerId, int $newReferrerId): void
-{
-    // 清除用户自身的缓存
-    Redis::del("promotion:user:{$userId}:all_referrers");
-    
-    // 清除旧推荐人相关的缓存
-    if ($oldReferrerId) {
-        Redis::del("promotion:user:{$oldReferrerId}:all_members");
-        Redis::del("promotion:user:{$oldReferrerId}:direct_count");
-        Redis::del("promotion:user:{$oldReferrerId}:promotion_count");
-        
-        // 清除旧推荐人的所有上级的缓存
-        $oldUpperReferrers = $this->getAllReferrers($oldReferrerId);
-        foreach ($oldUpperReferrers as $referrer) {
-            Redis::del("promotion:user:{$referrer['user_id']}:all_members");
-            Redis::del("promotion:user:{$referrer['user_id']}:promotion_count");
-        }
-    }
-    
-    // 清除新推荐人相关的缓存
-    Redis::del("promotion:user:{$newReferrerId}:all_members");
-    Redis::del("promotion:user:{$newReferrerId}:direct_count");
-    Redis::del("promotion:user:{$newReferrerId}:promotion_count");
-    
-    // 清除新推荐人的所有上级的缓存
-    $newUpperReferrers = $this->getAllReferrers($newReferrerId);
-    foreach ($newUpperReferrers as $referrer) {
-        Redis::del("promotion:user:{$referrer['user_id']}:all_members");
-        Redis::del("promotion:user:{$referrer['user_id']}:promotion_count");
-    }
-    
-    // 清除用户的所有下级的缓存
-    $allMembers = $this->getAllPromotionMembers($userId);
-    foreach ($allMembers['members'] as $member) {
-        Redis::del("promotion:user:{$member['user_id']}:all_referrers");
-    }
-}
-```
-
-### 5.3 定期刷新
-
-对于变更频率较低且不需要实时性的数据,采用定期刷新策略:
-
-```php
-/**
- * 定期刷新达人等级配置缓存
- */
-public function refreshTalentConfigCache(): void
-{
-    // 获取所有达人等级配置
-    $configs = $this->talentConfigRepository->getAll();
-    
-    // 缓存所有配置
-    Redis::setex("promotion:talent_configs", 86400 * 7, json_encode($configs)); // 缓存7天
-    
-    // 缓存单个配置
-    foreach ($configs as $config) {
-        Redis::setex("promotion:talent_config:{$config->level}", 86400 * 7, json_encode($config));
-    }
-}
-```
-
-## 6. 缓存失效机制
-
-### 6.1 过期时间设置
-
-不同类型的数据设置不同的过期时间:
-
-| 数据类型 | 过期时间 | 说明 |
-|---------|---------|------|
-| 推荐关系 | 1天 | 变更频率中等,查询频率高 |
-| 达人等级 | 1天 | 变更频率低,查询频率高 |
-| 达人配置 | 7天 | 变更频率极低,查询频率高 |
-| 分成规则 | 7天 | 变更频率极低,查询频率高 |
-
-### 6.2 主动失效
-
-在以下情况下主动使缓存失效:
-
-1. **推荐关系变更**:用户的推荐关系发生变更时
-2. **达人等级变更**:用户的达人等级发生变更时
-3. **配置更新**:达人等级配置或分成规则更新时
-4. **用户状态变更**:用户状态发生变更(如封禁、注销)时
-
-```php
-/**
- * 更新用户的达人等级
- */
-public function updateTalentLevel(int $userId, int $newLevel): bool
-{
-    // 更新数据库
-    $result = $this->talentRepository->updateLevel($userId, $newLevel);
-    
-    if ($result) {
-        // 清除相关缓存
-        Redis::del("promotion:user:{$userId}:talent_level");
-    }
-    
-    return $result;
-}
-```
-
-### 6.3 批量失效
-
-在系统维护或数据迁移时,可能需要批量使缓存失效:
-
-```php
-/**
- * 批量清除推荐关系缓存
- */
-public function batchClearReferralCaches(array $userIds): void
-{
-    foreach ($userIds as $userId) {
-        Redis::del("promotion:user:{$userId}:all_referrers");
-        Redis::del("promotion:user:{$userId}:all_members");
-        Redis::del("promotion:user:{$userId}:direct_count");
-        Redis::del("promotion:user:{$userId}:promotion_count");
-    }
-}
-```
-
-## 7. 缓存预热
-
-### 7.1 系统启动预热
-
-系统启动时,预热一些核心数据的缓存:
-
-```php
-/**
- * 系统启动预热
- */
-public function warmupCacheOnStartup(): void
-{
-    // 预热达人等级配置
-    $this->refreshTalentConfigCache();
-    
-    // 预热分成规则
-    $this->refreshProfitRuleCache();
-}
-```
-
-### 7.2 用户活跃度预热
-
-根据用户活跃度,预热高活跃用户的缓存:
-
-```php
-/**
- * 预热活跃用户的缓存
- */
-public function warmupActiveUserCache(int $days = 7): void
-{
-    // 获取活跃用户
-    $activeUsers = $this->userActivityRepository->getActiveUsers($days);
-    
-    // 预热用户的推荐关系缓存
-    foreach ($activeUsers as $user) {
-        $this->getAllReferrers($user->id);
-        $this->getAllPromotionMembers($user->id);
-    }
-}
-```
-
-### 7.3 大型团队预热
-
-预热大型团队领导者的缓存:
-
-```php
-/**
- * 预热大型团队领导者的缓存
- */
-public function warmupLargePromotionCache(int $minPromotionSize = 100): void
-{
-    // 获取大型团队领导者
-    $leaders = $this->talentRepository->getUsersByMinPromotionSize($minPromotionSize);
-    
-    // 预热领导者的团队缓存
-    foreach ($leaders as $leader) {
-        $this->getAllPromotionMembers($leader->user_id);
-    }
-}
-```
-
-## 8. 缓存监控
-
-### 8.1 缓存命中率监控
-
-监控缓存的命中率,评估缓存效果:
-
-```php
-/**
- * 记录缓存命中
- */
-private function recordCacheHit(string $cacheType): void
-{
-    Redis::incr("promotion:cache:hit:{$cacheType}");
-    Redis::incr("promotion:cache:total:{$cacheType}");
-}
-
-/**
- * 记录缓存未命中
- */
-private function recordCacheMiss(string $cacheType): void
-{
-    Redis::incr("promotion:cache:miss:{$cacheType}");
-    Redis::incr("promotion:cache:total:{$cacheType}");
-}
-
-/**
- * 获取缓存命中率
- */
-public function getCacheHitRate(string $cacheType): float
-{
-    $hit = (int)Redis::get("promotion:cache:hit:{$cacheType}") ?: 0;
-    $total = (int)Redis::get("promotion:cache:total:{$cacheType}") ?: 1;
-    
-    return $hit / $total;
-}
-```
-
-### 8.2 缓存大小监控
-
-监控缓存的大小,避免缓存过大:
-
-```php
-/**
- * 获取缓存大小统计
- */
-public function getCacheSize(): array
-{
-    $sizes = [];
-    
-    // 获取推荐关系缓存大小
-    $sizes['referrers'] = $this->estimateCacheSize("promotion:user:*:all_referrers");
-    $sizes['members'] = $this->estimateCacheSize("promotion:user:*:all_members");
-    
-    // 获取达人等级缓存大小
-    $sizes['talent'] = $this->estimateCacheSize("promotion:user:*:talent_level");
-    
-    // 获取配置缓存大小
-    $sizes['config'] = $this->estimateCacheSize("promotion:talent_config:*");
-    
-    return $sizes;
-}
-
-/**
- * 估算缓存大小
- */
-private function estimateCacheSize(string $pattern): int
-{
-    $keys = Redis::keys($pattern);
-    $size = 0;
-    
-    foreach ($keys as $key) {
-        $size += Redis::strlen($key);
-    }
-    
-    return $size;
-}
-```
-
-### 8.3 缓存异常监控
-
-监控缓存异常,及时发现问题:
-
-```php
-/**
- * 记录缓存异常
- */
-private function recordCacheException(string $cacheType, string $message): void
-{
-    Redis::incr("promotion:cache:exception:{$cacheType}");
-    Log::error("Cache exception: {$cacheType} - {$message}");
-}
-```
-
-## 9. 缓存优化
-
-### 9.1 缓存压缩
-
-对大型缓存数据进行压缩,减少内存占用:
-
-```php
-/**
- * 压缩缓存数据
- */
-private function compressCache(array $data): string
-{
-    return gzcompress(json_encode($data), 9);
-}
-
-/**
- * 解压缓存数据
- */
-private function decompressCache(string $data): array
-{
-    return json_decode(gzuncompress($data), true);
-}
-```
-
-### 9.2 分级缓存
-
-实现分级缓存策略,提高缓存效率:
-
-```php
-/**
- * 获取用户的所有上级(分级缓存)
- */
-public function getAllReferrers(int $userId): array
-{
-    // 尝试从本地缓存获取
-    $localCache = $this->getLocalCache("referrers_{$userId}");
-    if ($localCache !== null) {
-        return $localCache;
-    }
-    
-    // 尝试从Redis缓存获取
-    $cacheKey = "promotion:user:{$userId}:all_referrers";
-    $cachedData = Redis::get($cacheKey);
-    if ($cachedData !== null) {
-        $data = json_decode($cachedData, true);
-        $this->setLocalCache("referrers_{$userId}", $data);
-        return $data;
-    }
-    
-    // 计算数据
-    $allReferrers = [];
-    $this->calculateAllReferrers($userId, $allReferrers);
-    
-    // 缓存数据
-    Redis::setex($cacheKey, 86400, json_encode($allReferrers));
-    $this->setLocalCache("referrers_{$userId}", $allReferrers);
-    
-    return $allReferrers;
-}
-```
-
-### 9.3 缓存预分片
-
-对大型团队的缓存进行预分片,避免单个缓存过大:
-
-```php
-/**
- * 获取用户的所有团队成员(预分片)
- */
-public function getAllPromotionMembers(int $userId): array
-{
-    // 获取团队规模
-    $promotionCount = $this->getPromotionCount($userId);
-    
-    // 如果团队规模大于阈值,使用分片缓存
-    if ($promotionCount > 1000) {
-        return $this->getAllPromotionMembersSharded($userId);
-    }
-    
-    // 否则使用普通缓存
-    return $this->getAllPromotionMembersNormal($userId);
-}
-
-/**
- * 获取用户的所有团队成员(分片版)
- */
-private function getAllPromotionMembersSharded(int $userId): array
-{
-    $allMembers = [];
-    $shardCount = 10;
-    
-    // 获取所有分片
-    for ($i = 0; $i < $shardCount; $i++) {
-        $cacheKey = "promotion:user:{$userId}:all_members:shard:{$i}";
-        $cachedData = Redis::get($cacheKey);
-        
-        if ($cachedData !== null) {
-            $allMembers = array_merge($allMembers, json_decode($cachedData, true));
-        } else {
-            // 计算该分片的数据
-            $shardMembers = $this->calculatePromotionMembersShard($userId, $i, $shardCount);
-            Redis::setex($cacheKey, 86400, json_encode($shardMembers));
-            $allMembers = array_merge($allMembers, $shardMembers);
-        }
-    }
-    
-    return $allMembers;
-}
-```
-
-## 10. 缓存一致性
-
-### 10.1 写入确认
-
-在更新数据库后,确保缓存更新成功:
-
-```php
-/**
- * 更新用户的推荐关系(写入确认)
- */
-public function updateReferralRelation(int $userId, int $newReferrerId): bool
-{
-    // 更新数据库
-    $result = $this->referralRepository->updateReferrer($userId, $newReferrerId);
-    
-    if ($result) {
-        // 清除相关缓存
-        $cacheCleared = $this->clearReferralCaches($userId, $this->getOldReferrerId($userId), $newReferrerId);
-        
-        // 如果缓存清除失败,记录日志
-        if (!$cacheCleared) {
-            Log::error("Failed to clear cache for user {$userId} referral update");
-        }
-    }
-    
-    return $result;
-}
-```
-
-### 10.2 事务一致性
-
-在事务中同时更新数据库和缓存:
-
-```php
-/**
- * 更新用户的达人等级(事务一致性)
- */
-public function updateTalentLevel(int $userId, int $newLevel): bool
-{
-    return DB::transaction(function () use ($userId, $newLevel) {
-        // 更新数据库
-        $result = $this->talentRepository->updateLevel($userId, $newLevel);
-        
-        if ($result) {
-            // 清除相关缓存
-            Redis::del("promotion:user:{$userId}:talent_level");
-        }
-        
-        return $result;
-    });
-}
-```
-
-### 10.3 最终一致性
-
-对于不需要强一致性的数据,采用最终一致性策略:
-
-```php
-/**
- * 更新用户的团队统计数据(最终一致性)
- */
-public function updatePromotionStats(int $userId): void
-{
-    // 将任务加入队列,异步执行
-    dispatch(new UpdatePromotionStatsJob($userId));
-}
-
-/**
- * 异步更新团队统计数据
- */
-public function handleUpdatePromotionStats(int $userId): void
-{
-    // 计算直推人数
-    $directCount = $this->countDirectReferrals($userId);
-    
-    // 计算团队总人数
-    $promotionCount = $this->calculatePromotionCount($userId);
-    
-    // 更新数据库
-    $this->talentRepository->updateCounts($userId, $directCount, $promotionCount);
-    
-    // 更新缓存
-    Redis::setex("promotion:user:{$userId}:direct_count", 86400, $directCount);
-    Redis::setex("promotion:user:{$userId}:promotion_count", 86400, $promotionCount);
-}
-```
-
-## 11. 缓存安全
-
-### 11.1 数据脱敏
-
-对缓存中的敏感数据进行脱敏:
-
-```php
-/**
- * 获取用户的团队成员(数据脱敏)
- */
-public function getPromotionMembersWithMasking(int $userId): array
-{
-    $members = $this->getAllPromotionMembers($userId);
-    
-    // 对敏感数据进行脱敏
-    foreach ($members as &$member) {
-        if (isset($member['username'])) {
-            $member['username'] = $this->maskUsername($member['username']);
-        }
-    }
-    
-    return $members;
-}
-
-/**
- * 对用户名进行脱敏
- */
-private function maskUsername(string $username): string
-{
-    if (strlen($username) <= 2) {
-        return $username;
-    }
-    
-    return substr($username, 0, 1) . str_repeat('*', strlen($username) - 2) . substr($username, -1);
-}
-```
-
-### 11.2 访问控制
-
-实施缓存访问控制,防止未授权访问:
-
-```php
-/**
- * 验证用户是否有权限访问团队数据
- */
-private function validatePromotionAccess(int $userId, int $promotionLeaderId): bool
-{
-    // 如果是自己的团队数据,允许访问
-    if ($userId == $promotionLeaderId) {
-        return true;
-    }
-    
-    // 如果是管理员,允许访问
-    if ($this->isAdmin($userId)) {
-        return true;
-    }
-    
-    // 如果是团队成员,允许访问
-    $referrers = $this->getAllReferrers($userId);
-    foreach ($referrers as $referrer) {
-        if ($referrer['user_id'] == $promotionLeaderId) {
-            return true;
-        }
-    }
-    
-    return false;
-}
-```
-
-### 11.3 数据加密
-
-对敏感缓存数据进行加密:
-
-```php
-/**
- * 加密缓存数据
- */
-private function encryptCache(array $data): string
-{
-    $serialized = json_encode($data);
-    return encrypt($serialized);
-}
-
-/**
- * 解密缓存数据
- */
-private function decryptCache(string $data): array
-{
-    $decrypted = decrypt($data);
-    return json_decode($decrypted, true);
-}
-```
-
-## 12. 总结
-
-团队模块的缓存策略是只存储直接推荐关系 + 缓存方案的核心组成部分,通过合理的缓存设计和优化,在保持较高查询效率的同时,大幅减少了存储空间,并提高了推荐关系修改的灵活性。
-
-缓存策略的关键点包括:
-
-1. **分层缓存**:针对不同类型的数据采用不同的缓存策略
-2. **主动更新**:在数据变更时主动更新或清除相关缓存
-3. **缓存预热**:对核心数据和高频访问数据进行预热
-4. **缓存监控**:监控缓存的命中率、大小和异常情况
-5. **缓存优化**:通过压缩、分级和预分片等技术优化缓存性能
-6. **缓存一致性**:确保数据库和缓存的一致性
-7. **缓存安全**:保护缓存中的敏感数据
-
-通过这些策略,团队模块能够在大规模用户场景下保持良好的性能和可靠性,同时支持推荐关系的灵活修改。

+ 0 - 348
app/Module/Promotion/Docs/设计概述.md

@@ -1,348 +0,0 @@
-# 团队模块设计概述
-
-## 1. 模块定位
-
-团队模块是开心农场系统的核心模块之一,负责管理用户之间的推荐关系、团队结构、达人等级和收益分成机制。该模块通过建立用户间的直推和间推关系,形成团队结构,并在团队成员产生收益时进行分成,鼓励用户发展团队,形成良性的社交生态。
-
-## 2. 设计目标
-
-1. **建立完整的用户推荐体系**:支持直推和间推关系,形成多层级的团队结构
-2. **实现灵活的达人等级系统**:根据团队规模和活跃度评定用户的达人等级
-3. **提供公平的收益分成机制**:根据推荐关系和达人等级分配团队收益
-4. **支持多种收益来源**:支持农场收获、任务完成等多种收益来源的分成
-5. **保证系统的可扩展性**:预留达人等级、分成比例和收益来源的扩展空间
-
-## 3. 架构设计
-
-### 3.1 模块结构
-
-团队模块采用分层架构设计,包括以下层次:
-
-```
-                  ┌─────────────┐
-                  │  Controller │  控制器层:处理HTTP请求
-                  └──────┬──────┘
-                         │
-                         ▼
-┌─────────────┐   ┌─────────────┐
-│    Event    │◄──┤   Service   │  服务层:对外提供服务接口
-└─────────────┘   └──────┬──────┘
-                         │
-                         ▼
-                  ┌─────────────┐
-                  │    Logic    │  逻辑层:实现业务逻辑
-                  └──────┬──────┘
-                         │
-                         ▼
-                  ┌─────────────┐
-                  │ Repository  │  仓库层:数据访问和持久化
-                  └──────┬──────┘
-                         │
-                         ▼
-                  ┌─────────────┐
-                  │    Model    │  模型层:数据结构定义
-                  └─────────────┘
-```
-
-### 3.2 核心组件
-
-1. **Service**:对外提供服务接口,是模块的主要入口
-   - ReferralService:推荐关系服务
-   - TalentService:达人等级服务
-   - PromotionProfitService:团队收益服务
-   - ReferralCodeService:推荐码服务
-
-2. **Logic**:实现业务逻辑,处理复杂的业务规则
-   - ReferralLogic:推荐关系逻辑
-   - TalentLogic:达人等级逻辑
-   - ProfitLogic:收益分成逻辑
-
-3. **Repository**:数据访问和持久化,封装数据库操作
-   - UserReferralRepository:用户推荐关系仓库
-   - UserTalentRepository:用户达人等级仓库
-   - PromotionProfitRepository:团队收益记录仓库
-
-4. **Model**:数据结构定义,对应数据库表
-   - UserReferral:用户推荐关系模型
-   - UserTalent:用户达人等级模型
-   - PromotionProfit:团队收益记录模型
-
-5. **Event**:事件定义,用于模块间通信
-   - TalentLevelUpEvent:达人等级提升事件
-   - ReferralCreatedEvent:推荐关系创建事件
-   - PromotionProfitGeneratedEvent:团队收益生成事件
-
-### 3.3 依赖关系
-
-团队模块与其他模块的依赖关系:
-
-```
-┌─────────────┐      ┌─────────────┐      ┌─────────────┐
-│  User模块   │◄────►│  Promotion模块   │◄────►│  Farm模块   │
-└─────────────┘      └──────┬──────┘      └─────────────┘
-                            │
-                            ▼
-                     ┌─────────────┐
-                     │GameItems模块│
-                     └─────────────┘
-```
-
-- **User模块**:提供用户基本信息,接收推荐关系
-- **Farm模块**:提供收获事件,接收团队收益分成
-- **GameItems模块**:提供物品操作接口,处理收益物品的添加
-
-## 4. 核心流程
-
-### 4.1 推荐关系建立流程
-
-```
-┌─────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
-│  用户   │     │ UserService │     │ReferralService│    │ReferralLogic│
-└────┬────┘     └──────┬──────┘     └───────┬─────┘     └───────┬─────┘
-     │                 │                    │                   │
-     │ 注册(推荐码)     │                    │                   │
-     │────────────────►│                    │                   │
-     │                 │                    │                   │
-     │                 │ 验证推荐码          │                   │
-     │                 │───────────────────►│                   │
-     │                 │                    │                   │
-     │                 │                    │ 解析推荐人ID       │
-     │                 │                    │───────────────────►
-     │                 │                    │                   │
-     │                 │                    │                   │
-     │                 │                    │◄───────────────────
-     │                 │                    │                   │
-     │                 │                    │ 建立推荐关系       │
-     │                 │                    │───────────────────►
-     │                 │                    │                   │
-     │                 │                    │                   │
-     │                 │                    │◄───────────────────
-     │                 │                    │                   │
-     │                 │◄───────────────────│                   │
-     │                 │                    │                   │
-     │◄────────────────│                    │                   │
-     │                 │                    │                   │
-```
-
-### 4.2 达人等级升级流程
-
-```
-┌─────────────┐     ┌─────────────┐     ┌─────────────┐
-│ReferralService│    │TalentService │    │ TalentLogic │
-└───────┬─────┘     └───────┬─────┘     └───────┬─────┘
-        │                   │                   │
-        │ 建立推荐关系       │                   │
-        │───────────────────┼───────────────────┼────►
-        │                   │                   │
-        │ 触发检查达人等级   │                   │
-        │───────────────────►                   │
-        │                   │                   │
-        │                   │ 获取团队规模       │
-        │                   │───────────────────►
-        │                   │                   │
-        │                   │                   │
-        │                   │◄───────────────────
-        │                   │                   │
-        │                   │ 计算新达人等级     │
-        │                   │───────────────────►
-        │                   │                   │
-        │                   │                   │
-        │                   │◄───────────────────
-        │                   │                   │
-        │                   │ 更新达人等级       │
-        │                   │───────────────────►
-        │                   │                   │
-        │                   │                   │
-        │                   │◄───────────────────
-        │                   │                   │
-        │                   │ 触发等级提升事件   │
-        │                   │───────────────────►
-        │                   │                   │
-```
-
-### 4.3 团队收益分成流程
-
-```
-┌─────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
-│Farm模块  │     │PromotionProfitService│  │ ProfitLogic │    │GameItems模块│
-└────┬────┘     └───────┬─────┘     └───────┬─────┘     └───────┬─────┘
-     │                  │                   │                   │
-     │ 收获事件          │                   │                   │
-     │─────────────────►│                   │                   │
-     │                  │                   │                   │
-     │                  │ 获取推荐关系       │                   │
-     │                  │───────────────────►                   │
-     │                  │                   │                   │
-     │                  │                   │                   │
-     │                  │◄───────────────────                   │
-     │                  │                   │                   │
-     │                  │ 计算分成比例       │                   │
-     │                  │───────────────────►                   │
-     │                  │                   │                   │
-     │                  │                   │                   │
-     │                  │◄───────────────────                   │
-     │                  │                   │                   │
-     │                  │ 记录分成收益       │                   │
-     │                  │───────────────────►                   │
-     │                  │                   │                   │
-     │                  │                   │                   │
-     │                  │◄───────────────────                   │
-     │                  │                   │                   │
-     │                  │ 添加收益物品       │                   │
-     │                  │───────────────────┼───────────────────►
-     │                  │                   │                   │
-     │                  │                   │                   │
-     │                  │◄───────────────────┼───────────────────
-     │                  │                   │                   │
-```
-
-## 5. 关键设计点
-
-### 5.1 推荐关系存储
-
-团队模块采用扁平化存储推荐关系,即直接存储用户与其所有上级(直推和间推)的关系,而不是仅存储直接推荐关系。这种设计有以下优点:
-
-1. **查询效率高**:查询用户的所有上级或下级只需一次数据库查询
-2. **计算负担小**:不需要在运行时递归计算多级关系
-3. **维护成本低**:新增用户只需添加与其所有上级的关系记录
-
-示例数据结构:
-```
-user_id | referrer_id | level
---------|------------|------
-   2    |     1      |   1    # 用户1直推了用户2
-   3    |     2      |   1    # 用户2直推了用户3
-   3    |     1      |   2    # 用户1间推了用户3
-```
-
-### 5.2 达人等级计算
-
-达人等级计算采用定期更新和事件触发相结合的方式:
-
-1. **事件触发更新**:当用户团队规模变化时(如新增团队成员),触发达人等级检查
-2. **定期批量更新**:定时任务定期检查和更新所有用户的达人等级
-3. **缓存优化**:缓存用户的达人等级信息,减少频繁查询
-
-### 5.3 收益分成策略
-
-收益分成采用灵活的策略模式设计:
-
-1. **来源适配器**:为不同的收益来源(如农场收获、任务完成)提供适配器
-2. **分成规则引擎**:根据推荐关系和达人等级计算分成比例
-3. **分成上限控制**:设置分成总比例上限,确保系统可持续运营
-
-### 5.4 事件驱动通信
-
-模块间采用事件驱动的松耦合通信方式:
-
-1. **发布-订阅模式**:模块发布事件,其他模块订阅并处理
-2. **异步处理**:收益分成等耗时操作采用异步处理
-3. **失败重试**:关键操作失败后支持重试机制
-
-## 6. 扩展性设计
-
-### 6.1 达人等级扩展
-
-达人等级系统设计为可扩展的:
-
-1. **配置化等级**:达人等级条件和权益通过配置表定义
-2. **动态权益**:达人权益可动态配置,支持不同类型的权益
-3. **等级评定规则**:支持扩展等级评定规则,如增加活跃度指标
-
-### 6.2 收益来源扩展
-
-收益分成系统支持多种收益来源:
-
-1. **来源注册机制**:新的收益来源可通过注册机制接入
-2. **统一分成接口**:提供统一的分成计算和处理接口
-3. **来源特定规则**:支持为不同来源配置特定的分成规则
-
-### 6.3 分成规则扩展
-
-分成规则设计为可扩展的:
-
-1. **规则引擎**:使用规则引擎处理复杂的分成逻辑
-2. **规则配置**:分成比例和条件通过配置表定义
-3. **规则版本**:支持规则版本管理,便于规则调整和升级
-
-## 7. 安全性设计
-
-### 7.1 数据验证
-
-所有输入数据进行严格验证:
-
-1. **用户身份验证**:验证操作用户的身份和权限
-2. **数据完整性验证**:验证输入数据的完整性和有效性
-3. **业务规则验证**:验证操作是否符合业务规则
-
-### 7.2 防刷机制
-
-防止恶意刷取团队收益:
-
-1. **操作频率限制**:限制用户操作频率
-2. **异常行为检测**:检测和阻止异常的团队行为
-3. **收益上限控制**:设置单用户收益上限
-
-### 7.3 数据隔离
-
-确保数据安全和隔离:
-
-1. **用户数据隔离**:用户只能访问自己的团队数据
-2. **权限分级**:不同角色拥有不同的数据访问权限
-3. **敏感数据保护**:加密存储敏感数据
-
-## 8. 性能优化
-
-### 8.1 数据库优化
-
-优化数据库设计和查询:
-
-1. **索引设计**:为常用查询字段建立合适的索引
-2. **分表策略**:大表采用分表策略,提高查询效率
-3. **批量操作**:使用批量插入和更新,减少数据库操作次数
-
-### 8.2 缓存策略
-
-合理使用缓存提高性能:
-
-1. **用户团队缓存**:缓存用户的团队结构和达人信息
-2. **分成规则缓存**:缓存分成规则和比例
-3. **统计数据缓存**:缓存团队规模等统计数据
-
-### 8.3 异步处理
-
-耗时操作采用异步处理:
-
-1. **队列处理**:收益分成等操作通过队列异步处理
-2. **批量处理**:定期批量处理团队统计和达人升级
-3. **任务调度**:使用任务调度系统管理异步任务
-
-## 9. 与其他模块的交互
-
-### 9.1 与User模块的交互
-
-- **用户注册**:接收用户注册事件,处理推荐关系
-- **用户信息**:获取用户基本信息,如昵称、头像等
-- **用户状态**:监听用户状态变更,如封禁、注销等
-
-### 9.2 与Farm模块的交互
-
-- **收获事件**:监听作物收获事件,计算农场收益分成
-- **达人权益**:提供达人等级信息,影响农场产出
-- **团队任务**:支持团队协作完成农场任务
-
-### 9.3 与GameItems模块的交互
-
-- **物品操作**:调用物品模块接口,添加收益物品
-- **物品记录**:记录收益物品的来源和分成信息
-- **物品消耗**:支持使用物品激活团队特权
-
-### 9.4 与Task模块的交互
-
-- **任务完成**:触发团队相关任务的完成
-- **任务奖励**:计算团队任务奖励的分成
-- **团队目标**:支持设置和完成团队目标
-
-## 10. 总结
-
-团队模块作为开心农场系统的核心模块之一,通过建立用户间的推荐关系、团队结构、达人等级和收益分成机制,鼓励用户发展团队,形成良性的社交生态。模块设计注重灵活性、可扩展性和性能,采用分层架构和事件驱动通信,与其他模块保持松耦合关系。通过合理的数据结构设计和优化策略,确保系统在大规模用户场景下的稳定运行。

+ 0 - 27
app/Module/Promotion/Enums/PROFIT_RECORD_STATUS.php

@@ -1,27 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Enums;
-
-/**
- * 收益记录状态枚举
- * 定义了团队收益记录的状态
- */
-enum PROFIT_RECORD_STATUS: int {
-    /**
-     * 待处理
-     * 收益记录已创建但尚未处理
-     */
-    case PENDING = 0;
-
-    /**
-     * 成功
-     * 收益已成功分配到用户账户
-     */
-    case SUCCESS = 1;
-
-    /**
-     * 失败
-     * 收益分配失败,需要重试或人工处理
-     */
-    case FAILED = 2;
-}

+ 0 - 27
app/Module/Promotion/Enums/PROFIT_SOURCE_TYPE.php

@@ -1,27 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Enums;
-
-/**
- * 收益来源类型枚举
- * 定义了团队收益的来源
- */
-enum PROFIT_SOURCE_TYPE: string {
-    /**
-     * 农场收获
-     * 来自Farm模块的作物收获
-     */
-    case FARM_HARVEST = 'farm_harvest';
-
-    /**
-     * 任务完成
-     * 来自Task模块的任务奖励
-     */
-    case TASK_COMPLETE = 'task_complete';
-
-    /**
-     * 物品出售
-     * 来自GameItems模块的物品出售
-     */
-    case ITEM_SELL = 'item_sell';
-}

+ 0 - 27
app/Module/Promotion/Enums/REFERRAL_CODE_STATUS.php

@@ -1,27 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Enums;
-
-/**
- * 推荐码状态枚举
- * 定义了推荐码的状态
- */
-enum REFERRAL_CODE_STATUS: int {
-    /**
-     * 未激活
-     * 推荐码已生成但尚未激活
-     */
-    case INACTIVE = 0;
-
-    /**
-     * 有效
-     * 推荐码有效,可以使用
-     */
-    case ACTIVE = 1;
-
-    /**
-     * 已禁用
-     * 推荐码已被禁用,无法使用
-     */
-    case DISABLED = 2;
-}

+ 0 - 21
app/Module/Promotion/Enums/REFERRAL_LEVEL.php

@@ -1,21 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Enums;
-
-/**
- * 推荐层级枚举
- * 定义了用户之间的推荐关系类型
- */
-enum REFERRAL_LEVEL: int {
-    /**
-     * 直推关系
-     * 用户A直接推荐用户B
-     */
-    case DIRECT = 1;
-
-    /**
-     * 间推关系
-     * 用户A通过中间用户间接推荐用户C
-     */
-    case INDIRECT = 2;
-}

+ 0 - 45
app/Module/Promotion/Enums/TALENT_LEVEL.php

@@ -1,45 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Enums;
-
-/**
- * 达人等级枚举
- * 定义了用户的达人等级
- */
-enum TALENT_LEVEL: int {
-    /**
-     * 非达人
-     * 默认等级
-     */
-    case NONE = 0;
-
-    /**
-     * 初级达人
-     * 直推5人且团队总人数≥10
-     */
-    case JUNIOR = 1;
-
-    /**
-     * 中级达人
-     * 直推10人且团队总人数≥30
-     */
-    case INTERMEDIATE = 2;
-
-    /**
-     * 高级达人
-     * 直推20人且团队总人数≥50
-     */
-    case SENIOR = 3;
-
-    /**
-     * 资深达人
-     * 直推30人且团队总人数≥100
-     */
-    case EXPERT = 4;
-
-    /**
-     * 顶级达人
-     * 直推50人且团队总人数≥200
-     */
-    case MASTER = 5;
-}

+ 0 - 33
app/Module/Promotion/Enums/TEAM_TASK_STATUS.php

@@ -1,33 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Enums;
-
-/**
- * 团队任务状态枚举
- * 定义了团队任务的状态
- */
-enum TEAM_TASK_STATUS: int {
-    /**
-     * 进行中
-     * 任务正在进行中
-     */
-    case ACTIVE = 1;
-
-    /**
-     * 已完成
-     * 任务已完成并发放奖励
-     */
-    case COMPLETED = 2;
-
-    /**
-     * 已过期
-     * 任务未完成但已过期
-     */
-    case EXPIRED = 3;
-
-    /**
-     * 已取消
-     * 任务被创建者或管理员取消
-     */
-    case CANCELLED = 4;
-}

+ 0 - 33
app/Module/Promotion/Enums/TEAM_TASK_TYPE.php

@@ -1,33 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Enums;
-
-/**
- * 团队任务类型枚举
- * 定义了团队可以执行的任务类型
- */
-enum TEAM_TASK_TYPE: string {
-    /**
-     * 种植任务
-     * 团队成员种植特定作物
-     */
-    case PLANTING = 'planting';
-
-    /**
-     * 收获任务
-     * 团队成员收获特定作物
-     */
-    case HARVESTING = 'harvesting';
-
-    /**
-     * 推荐任务
-     * 团队成员发展新成员
-     */
-    case REFERRAL = 'referral';
-
-    /**
-     * 活跃度任务
-     * 团队成员保持活跃
-     */
-    case ACTIVITY = 'activity';
-}

+ 0 - 40
app/Module/Promotion/Events/PromotionProfitCreatedEvent.php

@@ -1,40 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Events;
-
-use App\Module\Promotion\Models\PromotionProfit;
-use Illuminate\Broadcasting\InteractsWithSockets;
-use Illuminate\Foundation\Events\Dispatchable;
-use Illuminate\Queue\SerializesModels;
-
-/**
- * 团队收益创建事件
- *
- * 当团队收益记录被创建时触发此事件。
- * 监听此事件可以执行如下操作:
- * 1. 发送通知
- * 2. 记录收益日志
- * 3. 更新用户的收益统计
- */
-class PromotionProfitCreatedEvent
-{
-    use Dispatchable, InteractsWithSockets, SerializesModels;
-
-    /**
-     * 团队收益模型
-     *
-     * @var PromotionProfit
-     */
-    public $profit;
-
-    /**
-     * 创建一个新的事件实例
-     *
-     * @param PromotionProfit $profit 团队收益模型
-     * @return void
-     */
-    public function __construct(PromotionProfit $profit)
-    {
-        $this->profit = $profit;
-    }
-}

+ 0 - 40
app/Module/Promotion/Events/ReferralCreatedEvent.php

@@ -1,40 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Events;
-
-use App\Module\Promotion\Models\PromotionUserReferral;
-use Illuminate\Broadcasting\InteractsWithSockets;
-use Illuminate\Foundation\Events\Dispatchable;
-use Illuminate\Queue\SerializesModels;
-
-/**
- * 推荐关系创建事件
- *
- * 当用户的推荐关系被创建时触发此事件。
- * 监听此事件可以执行如下操作:
- * 1. 更新用户的团队统计数据
- * 2. 更新用户的达人等级
- * 3. 发放邀请奖励
- */
-class ReferralCreatedEvent
-{
-    use Dispatchable, InteractsWithSockets, SerializesModels;
-
-    /**
-     * 推荐关系模型
-     *
-     * @var PromotionUserReferral
-     */
-    public $referral;
-
-    /**
-     * 创建一个新的事件实例
-     *
-     * @param PromotionUserReferral $referral 推荐关系模型
-     * @return void
-     */
-    public function __construct(PromotionUserReferral $referral)
-    {
-        $this->referral = $referral;
-    }
-}

+ 0 - 50
app/Module/Promotion/Events/ReferralUpdatedEvent.php

@@ -1,50 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Events;
-
-use App\Module\Promotion\Models\PromotionReferralChange;
-use App\Module\Promotion\Models\PromotionUserReferral;
-use Illuminate\Broadcasting\InteractsWithSockets;
-use Illuminate\Foundation\Events\Dispatchable;
-use Illuminate\Queue\SerializesModels;
-
-/**
- * 推荐关系更新事件
- *
- * 当用户的推荐关系被更新时触发此事件。
- * 监听此事件可以执行如下操作:
- * 1. 更新用户的团队统计数据
- * 2. 更新用户的达人等级
- * 3. 更新用户的关系缓存
- */
-class ReferralUpdatedEvent
-{
-    use Dispatchable, InteractsWithSockets, SerializesModels;
-
-    /**
-     * 推荐关系模型
-     *
-     * @var PromotionUserReferral
-     */
-    public $referral;
-
-    /**
-     * 推荐关系修改记录
-     *
-     * @var PromotionReferralChange
-     */
-    public $change;
-
-    /**
-     * 创建一个新的事件实例
-     *
-     * @param PromotionUserReferral $referral 推荐关系模型
-     * @param PromotionReferralChange $change 推荐关系修改记录
-     * @return void
-     */
-    public function __construct(PromotionUserReferral $referral, PromotionReferralChange $change)
-    {
-        $this->referral = $referral;
-        $this->change = $change;
-    }
-}

+ 0 - 58
app/Module/Promotion/Events/TalentLevelChangedEvent.php

@@ -1,58 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Events;
-
-use App\Module\Promotion\Models\PromotionUserTalent;
-use Illuminate\Broadcasting\InteractsWithSockets;
-use Illuminate\Foundation\Events\Dispatchable;
-use Illuminate\Queue\SerializesModels;
-
-/**
- * 达人等级变更事件
- *
- * 当用户的达人等级发生变化时触发此事件。
- * 监听此事件可以执行如下操作:
- * 1. 更新用户的权益
- * 2. 发送通知
- * 3. 记录等级变更日志
- */
-class TalentLevelChangedEvent
-{
-    use Dispatchable, InteractsWithSockets, SerializesModels;
-
-    /**
-     * 达人等级模型
-     *
-     * @var PromotionUserTalent
-     */
-    public $talent;
-
-    /**
-     * 旧的达人等级
-     *
-     * @var int
-     */
-    public $oldLevel;
-
-    /**
-     * 新的达人等级
-     *
-     * @var int
-     */
-    public $newLevel;
-
-    /**
-     * 创建一个新的事件实例
-     *
-     * @param PromotionUserTalent $talent 达人等级模型
-     * @param int $oldLevel 旧的达人等级
-     * @param int $newLevel 新的达人等级
-     * @return void
-     */
-    public function __construct(PromotionUserTalent $talent, int $oldLevel, int $newLevel)
-    {
-        $this->talent = $talent;
-        $this->oldLevel = $oldLevel;
-        $this->newLevel = $newLevel;
-    }
-}

+ 0 - 101
app/Module/Promotion/Listeners/DistributePromotionProfitListener.php

@@ -1,101 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Listeners;
-
-use App\Module\Promotion\Events\PromotionProfitCreatedEvent;
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Logics\TalentLogic;
-use App\Module\Promotion\Logics\PromotionProfitLogic;
-
-
-use Illuminate\Support\Facades\Log;
-
-/**
- * 分配团队收益监听器
- *
- * 监听团队收益创建事件,分配团队收益。
- * 根据用户的推荐关系和达人等级,计算并分配团队收益。
- */
-class DistributePromotionProfitListener
-{
-
-
-    /**
-     * 推荐关系逻辑类
-     *
-     * @var ReferralLogic
-     */
-    protected $referralLogic;
-
-    /**
-     * 达人等级逻辑类
-     *
-     * @var TalentLogic
-     */
-    protected $talentLogic;
-
-    /**
-     * 团队收益逻辑类
-     *
-     * @var PromotionProfitLogic
-     */
-    protected $promotionProfitLogic;
-
-    /**
-     * 创建监听器实例
-     *
-     * @param ReferralLogic $referralLogic 推荐关系逻辑类
-     * @param TalentLogic $talentLogic 达人等级逻辑类
-     * @param PromotionProfitLogic $promotionProfitLogic 团队收益逻辑类
-     * @return void
-     */
-    public function __construct(
-        ReferralLogic $referralLogic,
-        TalentLogic $talentLogic,
-        PromotionProfitLogic $promotionProfitLogic
-    ) {
-        $this->referralLogic = $referralLogic;
-        $this->talentLogic = $talentLogic;
-        $this->promotionProfitLogic = $promotionProfitLogic;
-    }
-
-    /**
-     * 处理团队收益创建事件
-     *
-     * @param PromotionProfitCreatedEvent $event 团队收益创建事件
-     * @return void
-     */
-    public function handle(PromotionProfitCreatedEvent $event)
-    {
-        try {
-            $profit = $event->profit;
-            $userId = $profit->from_user_id;
-            $sourceType = $profit->source_type;
-            $sourceId = $profit->source_id;
-            $itemId = $profit->item_id;
-            $amount = $profit->amount;
-
-            // 分配团队收益
-            $this->promotionProfitLogic->distributePromotionProfit(
-                $userId,
-                $sourceType,
-                $sourceId,
-                $itemId,
-                $amount
-            );
-
-            Log::info("团队收益分配成功", [
-                'user_id' => $userId,
-                'source_type' => $sourceType,
-                'source_id' => $sourceId,
-                'item_id' => $itemId,
-                'amount' => $amount
-            ]);
-        } catch (\Exception $e) {
-            Log::error("团队收益分配失败", [
-                'error' => $e->getMessage(),
-                'event' => 'PromotionProfitCreated'
-            ]);
-        }
-    }
-}

+ 0 - 155
app/Module/Promotion/Listeners/UpdatePromotionCountsListener.php

@@ -1,155 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Listeners;
-
-use App\Module\Promotion\Events\ReferralCreatedEvent;
-use App\Module\Promotion\Events\ReferralUpdatedEvent;
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Logics\RelationCacheLogic;
-
-
-use Illuminate\Support\Facades\Log;
-
-/**
- * 更新团队统计数据监听器
- *
- * 监听推荐关系创建和更新事件,更新团队统计数据。
- * 包括更新直推人数和团队总人数。
- */
-class UpdatePromotionCountsListener
-{
-
-
-    /**
-     * 推荐关系逻辑类
-     *
-     * @var ReferralLogic
-     */
-    protected $referralLogic;
-
-    /**
-     * 关系缓存逻辑类
-     *
-     * @var RelationCacheLogic
-     */
-    protected $relationCacheLogic;
-
-    /**
-     * 创建监听器实例
-     *
-     * @param ReferralLogic $referralLogic 推荐关系逻辑类
-     * @param RelationCacheLogic $relationCacheLogic 关系缓存逻辑类
-     * @return void
-     */
-    public function __construct(ReferralLogic $referralLogic, RelationCacheLogic $relationCacheLogic)
-    {
-        $this->referralLogic = $referralLogic;
-        $this->relationCacheLogic = $relationCacheLogic;
-    }
-
-    /**
-     * 处理推荐关系创建事件
-     *
-     * @param ReferralCreatedEvent $event 推荐关系创建事件
-     * @return void
-     */
-    public function handleReferralCreated(ReferralCreatedEvent $event)
-    {
-        try {
-            $referral = $event->referral;
-            $userId = $referral->user_id;
-            $referrerId = $referral->referrer_id;
-
-            // 更新直推人数
-            $this->referralLogic->incrementDirectCount($referrerId);
-
-            // 更新关系缓存
-            $this->relationCacheLogic->buildUserRelationCache($userId);
-
-            // 更新团队总人数
-            $this->referralLogic->updatePromotionCounts($referrerId);
-
-            Log::info("团队统计数据更新成功", [
-                'user_id' => $userId,
-                'referrer_id' => $referrerId,
-                'event' => 'ReferralCreated'
-            ]);
-        } catch (\Exception $e) {
-            Log::error("团队统计数据更新失败", [
-                'error' => $e->getMessage(),
-                'event' => 'ReferralCreated'
-            ]);
-        }
-    }
-
-    /**
-     * 处理推荐关系更新事件
-     *
-     * @param ReferralUpdatedEvent $event 推荐关系更新事件
-     * @return void
-     */
-    public function handleReferralUpdated(ReferralUpdatedEvent $event)
-    {
-        try {
-            $referral = $event->referral;
-            $change = $event->change;
-            $userId = $referral->user_id;
-            $oldReferrerId = $change->old_referrer_id;
-            $newReferrerId = $change->new_referrer_id;
-
-            // 减少旧推荐人的直推人数
-            if ($oldReferrerId) {
-                $this->referralLogic->decrementDirectCount($oldReferrerId);
-            }
-
-            // 增加新推荐人的直推人数
-            if ($newReferrerId) {
-                $this->referralLogic->incrementDirectCount($newReferrerId);
-            }
-
-            // 更新关系缓存
-            $this->relationCacheLogic->rebuildUserRelationCache($userId);
-
-            // 更新旧推荐人的团队总人数
-            if ($oldReferrerId) {
-                $this->referralLogic->updatePromotionCounts($oldReferrerId);
-            }
-
-            // 更新新推荐人的团队总人数
-            if ($newReferrerId) {
-                $this->referralLogic->updatePromotionCounts($newReferrerId);
-            }
-
-            Log::info("团队统计数据更新成功", [
-                'user_id' => $userId,
-                'old_referrer_id' => $oldReferrerId,
-                'new_referrer_id' => $newReferrerId,
-                'event' => 'ReferralUpdated'
-            ]);
-        } catch (\Exception $e) {
-            Log::error("团队统计数据更新失败", [
-                'error' => $e->getMessage(),
-                'event' => 'ReferralUpdated'
-            ]);
-        }
-    }
-
-    /**
-     * 注册监听器的订阅者
-     *
-     * @param \Illuminate\Events\Dispatcher $events
-     * @return void
-     */
-    public function subscribe($events)
-    {
-        $events->listen(
-            ReferralCreatedEvent::class,
-            [UpdatePromotionCountsListener::class, 'handleReferralCreated']
-        );
-
-        $events->listen(
-            ReferralUpdatedEvent::class,
-            [UpdatePromotionCountsListener::class, 'handleReferralUpdated']
-        );
-    }
-}

+ 0 - 131
app/Module/Promotion/Listeners/UpdateTalentLevelListener.php

@@ -1,131 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Listeners;
-
-use App\Module\Promotion\Events\ReferralCreatedEvent;
-use App\Module\Promotion\Events\ReferralUpdatedEvent;
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Logics\TalentLogic;
-
-
-use Illuminate\Support\Facades\Log;
-
-/**
- * 更新达人等级监听器
- *
- * 监听推荐关系创建和更新事件,更新用户的达人等级。
- * 根据用户的直推人数和团队总人数,计算用户的达人等级。
- */
-class UpdateTalentLevelListener
-{
-
-
-    /**
-     * 推荐关系逻辑类
-     *
-     * @var ReferralLogic
-     */
-    protected $referralLogic;
-
-    /**
-     * 达人等级逻辑类
-     *
-     * @var TalentLogic
-     */
-    protected $talentLogic;
-
-    /**
-     * 创建监听器实例
-     *
-     * @param ReferralLogic $referralLogic 推荐关系逻辑类
-     * @param TalentLogic $talentLogic 达人等级逻辑类
-     * @return void
-     */
-    public function __construct(ReferralLogic $referralLogic, TalentLogic $talentLogic)
-    {
-        $this->referralLogic = $referralLogic;
-        $this->talentLogic = $talentLogic;
-    }
-
-    /**
-     * 处理推荐关系创建事件
-     *
-     * @param ReferralCreatedEvent $event 推荐关系创建事件
-     * @return void
-     */
-    public function handleReferralCreated(ReferralCreatedEvent $event)
-    {
-        try {
-            $referral = $event->referral;
-            $referrerId = $referral->referrer_id;
-
-            // 更新推荐人的达人等级
-            $this->talentLogic->checkAndUpdateTalentLevel($referrerId);
-
-            Log::info("达人等级更新成功", [
-                'referrer_id' => $referrerId,
-                'event' => 'ReferralCreated'
-            ]);
-        } catch (\Exception $e) {
-            Log::error("达人等级更新失败", [
-                'error' => $e->getMessage(),
-                'event' => 'ReferralCreated'
-            ]);
-        }
-    }
-
-    /**
-     * 处理推荐关系更新事件
-     *
-     * @param ReferralUpdatedEvent $event 推荐关系更新事件
-     * @return void
-     */
-    public function handleReferralUpdated(ReferralUpdatedEvent $event)
-    {
-        try {
-            $change = $event->change;
-            $oldReferrerId = $change->old_referrer_id;
-            $newReferrerId = $change->new_referrer_id;
-
-            // 更新旧推荐人的达人等级
-            if ($oldReferrerId) {
-                $this->talentLogic->checkAndUpdateTalentLevel($oldReferrerId);
-            }
-
-            // 更新新推荐人的达人等级
-            if ($newReferrerId) {
-                $this->talentLogic->checkAndUpdateTalentLevel($newReferrerId);
-            }
-
-            Log::info("达人等级更新成功", [
-                'old_referrer_id' => $oldReferrerId,
-                'new_referrer_id' => $newReferrerId,
-                'event' => 'ReferralUpdated'
-            ]);
-        } catch (\Exception $e) {
-            Log::error("达人等级更新失败", [
-                'error' => $e->getMessage(),
-                'event' => 'ReferralUpdated'
-            ]);
-        }
-    }
-
-    /**
-     * 注册监听器的订阅者
-     *
-     * @param \Illuminate\Events\Dispatcher $events
-     * @return void
-     */
-    public function subscribe($events)
-    {
-        $events->listen(
-            ReferralCreatedEvent::class,
-            [UpdateTalentLevelListener::class, 'handleReferralCreated']
-        );
-
-        $events->listen(
-            ReferralUpdatedEvent::class,
-            [UpdateTalentLevelListener::class, 'handleReferralUpdated']
-        );
-    }
-}

+ 0 - 256
app/Module/Promotion/Logics/PromotionProfitLogic.php

@@ -1,256 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Logics;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use App\Module\Promotion\Enums\REFERRAL_LEVEL;
-use App\Module\Promotion\Models\PromotionProfit;
-use App\Module\Promotion\Models\PromotionProfitRule;
-use Illuminate\Support\Facades\Log;
-
-/**
- * 团队收益逻辑类
- *
- * 处理团队收益的核心业务逻辑,包括计算收益分成、记录收益、
- * 获取收益规则等功能。该类仅供内部使用,不对外提供服务。
- */
-class PromotionProfitLogic
-{
-    /**
-     * @var ReferralLogic
-     */
-    protected $referralLogic;
-
-    /**
-     * @var TalentLogic
-     */
-    protected $talentLogic;
-
-    /**
-     * 构造函数
-     *
-     * @param ReferralLogic $referralLogic
-     * @param TalentLogic $talentLogic
-     */
-    public function __construct(ReferralLogic $referralLogic, TalentLogic $talentLogic)
-    {
-        $this->referralLogic = $referralLogic;
-        $this->talentLogic = $talentLogic;
-    }
-
-    /**
-     * 计算并记录团队收益分成
-     *
-     * @param int $userId 产生收益的用户ID
-     * @param string $sourceType 收益来源类型
-     * @param int $sourceId 收益来源ID
-     * @param int $itemId 物品ID
-     * @param int $amount 收益数量
-     * @return bool
-     */
-    public function calculateAndRecordProfit(int $userId, string $sourceType, int $sourceId, int $itemId, int $amount): bool
-    {
-        try {
-            // 获取收益分成规则
-            $rule = $this->getProfitRule($sourceType);
-
-            if (!$rule || !$rule->isActive()) {
-                Log::info("收益分成规则不存在或未激活: {$sourceType}");
-                return false;
-            }
-
-            // 检查收益是否满足最小数量要求
-            $minAmount = $rule->getRuleAttribute('min_amount', 0);
-            if ($amount < $minAmount) {
-                Log::info("收益数量不满足最小要求: {$amount} < {$minAmount}");
-                return false;
-            }
-
-            // 检查收益是否超过最大数量限制
-            $maxAmount = $rule->getRuleAttribute('max_amount', PHP_INT_MAX);
-            if ($amount > $maxAmount) {
-                $amount = $maxAmount;
-                Log::info("收益数量超过最大限制,已调整为: {$maxAmount}");
-            }
-
-            // 检查物品是否在排除列表中
-            $excludedItems = $rule->getRuleAttribute('excluded_items', []);
-            if (in_array($itemId, $excludedItems)) {
-                Log::info("物品在排除列表中: {$itemId}");
-                return false;
-            }
-
-            // 获取用户的所有上级
-            $referrers = $this->referralLogic->getAllReferrers($userId, $rule->max_indirect_level);
-
-            if (empty($referrers)) {
-                Log::info("用户没有上级: {$userId}");
-                return true;
-            }
-
-            // 检查事务是否已开启
-            \UCore\Db\Helper::check_tr();
-
-            // 记录收益分成
-            $success = true;
-
-            foreach ($referrers as $referrer) {
-                $referrerId = $referrer['user_id'];
-                $level = $referrer['level'];
-                $depth = $referrer['depth'];
-
-                // 计算分成比例
-                $profitRate = $this->calculateProfitRate($level, $depth, $rule);
-
-                // 计算分成数量
-                $profitAmount = (int)($amount * $profitRate);
-
-                if ($profitAmount <= 0) {
-                    continue;
-                }
-
-                // 记录收益
-                $profit = new PromotionProfit();
-                $profit->user_id = $referrerId;
-                $profit->promotion_member_id = $userId;
-                $profit->source_id = $sourceId;
-                $profit->source_type = $sourceType;
-                $profit->item_id = $itemId;
-                $profit->profit_amount = $profitAmount;
-                $profit->profit_rate = $profitRate;
-                $profit->relation_type = $level;
-
-                if (!$profit->save()) {
-                    $success = false;
-                    Log::error("记录收益分成失败: 用户 {$referrerId}, 来源 {$sourceType}, 数量 {$profitAmount}");
-                }
-            }
-
-            return $success;
-        } catch (\Exception $e) {
-            Log::error("计算并记录团队收益分成失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 计算分成比例
-     *
-     * @param int $level 关系层级
-     * @param int $depth 层级深度
-     * @param PromotionProfitRule $rule 分成规则
-     * @return float
-     */
-    private function calculateProfitRate(int $level, int $depth, PromotionProfitRule $rule): float
-    {
-        // 直推关系
-        if ($level == REFERRAL_LEVEL::DIRECT) {
-            return $rule->direct_profit_rate;
-        }
-
-        // 间推关系
-        if ($level == REFERRAL_LEVEL::INDIRECT) {
-            // 获取用户的达人等级
-            $talent = $this->talentLogic->getUserTalent($depth);
-
-            if (!$talent || $talent->talent_level == 0) {
-                return 0.0;
-            }
-
-            // 获取达人等级对应的分成比例
-            $profitRate = $this->talentLogic->getTalentProfitRate($talent->talent_level);
-
-            // 应用特殊规则
-            $specialRates = $rule->getRuleAttribute('special_rates', []);
-            foreach ($specialRates as $specialRate) {
-                if (isset($specialRate['talent_level']) && $specialRate['talent_level'] == $talent->talent_level) {
-                    if (isset($specialRate['bonus_rate'])) {
-                        $profitRate += $specialRate['bonus_rate'];
-                    }
-                }
-            }
-
-            return $profitRate;
-        }
-
-        return 0.0;
-    }
-
-    /**
-     * 获取收益分成规则
-     *
-     * @param string $sourceType 收益来源类型
-     * @return PromotionProfitRule|null
-     */
-    public function getProfitRule(string $sourceType): ?PromotionProfitRule
-    {
-        return PromotionProfitRule::where('source_type', $sourceType)
-            ->where('status', 1)
-            ->first();
-    }
-
-    /**
-     * 获取用户的团队收益记录
-     *
-     * @param int $userId 用户ID
-     * @param string|null $sourceType 收益来源类型
-     * @param int $page 页码
-     * @param int $pageSize 每页数量
-     * @return array
-     */
-    public function getUserProfits(int $userId, ?string $sourceType = null, int $page = 1, int $pageSize = 20): array
-    {
-        $query = PromotionProfit::where('user_id', $userId);
-
-        if ($sourceType) {
-            $query->where('source_type', $sourceType);
-        }
-
-        $total = $query->count();
-
-        $profits = $query->orderBy('created_at', 'desc')
-            ->offset(($page - 1) * $pageSize)
-            ->limit($pageSize)
-            ->with(['promotionMember', 'item'])
-            ->get();
-
-        return [
-            'total' => $total,
-            'page' => $page,
-            'page_size' => $pageSize,
-            'total_pages' => ceil($total / $pageSize),
-            'profits' => $profits
-        ];
-    }
-
-    /**
-     * 统计用户的团队收益
-     *
-     * @param int $userId 用户ID
-     * @param string|null $sourceType 收益来源类型
-     * @param int|null $itemId 物品ID
-     * @return array
-     */
-    public function sumUserProfits(int $userId, ?string $sourceType = null, ?int $itemId = null): array
-    {
-        $query = PromotionProfit::where('user_id', $userId);
-
-        if ($sourceType) {
-            $query->where('source_type', $sourceType);
-        }
-
-        if ($itemId) {
-            $query->where('item_id', $itemId);
-        }
-
-        $directSum = (clone $query)->where('relation_type', REFERRAL_LEVEL::DIRECT)->sum('profit_amount');
-        $indirectSum = (clone $query)->where('relation_type', REFERRAL_LEVEL::INDIRECT)->sum('profit_amount');
-        $totalSum = $directSum + $indirectSum;
-
-        return [
-            'direct_profit' => $directSum,
-            'indirect_profit' => $indirectSum,
-            'total_profit' => $totalSum
-        ];
-    }
-}

+ 0 - 309
app/Module/Promotion/Logics/ReferralCodeLogic.php

@@ -1,309 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Logics;
-
-use App\Module\Promotion\Enums\REFERRAL_CODE_STATUS;
-use App\Module\Promotion\Models\PromotionReferralCode;
-use App\Module\Promotion\Models\PromotionReferralCodeUsage;
-use Illuminate\Support\Facades\Log;
-use Illuminate\Support\Str;
-
-/**
- * 推荐码逻辑类
- *
- * 处理推荐码的核心业务逻辑,包括生成推荐码、验证推荐码、
- * 使用推荐码等功能。该类仅供内部使用,不对外提供服务。
- */
-class ReferralCodeLogic
-{
-    /**
-     * @var ReferralLogic
-     */
-    protected $referralLogic;
-
-    /**
-     * 构造函数
-     *
-     * @param ReferralLogic $referralLogic
-     */
-    public function __construct(ReferralLogic $referralLogic)
-    {
-        $this->referralLogic = $referralLogic;
-    }
-
-    /**
-     * 生成推荐码
-     *
-     * @param int $userId 用户ID
-     * @param \DateTime|null $expireTime 过期时间
-     * @return string|null
-     */
-    public function generateReferralCode(int $userId, ?\DateTime $expireTime = null): ?string
-    {
-        try {
-            // 检查用户是否已有有效的推荐码
-            $existingCode = $this->getUserActiveCode($userId);
-
-            if ($existingCode) {
-                return $existingCode->code;
-            }
-
-            // 生成唯一的推荐码
-            $code = $this->generateUniqueCode();
-
-            // 创建推荐码记录
-            $referralCode = new PromotionReferralCode();
-            $referralCode->user_id = $userId;
-            $referralCode->code = $code;
-            $referralCode->usage_count = 0;
-            $referralCode->status = REFERRAL_CODE_STATUS::ACTIVE;
-            $referralCode->expire_time = $expireTime;
-
-            if ($referralCode->save()) {
-                return $code;
-            }
-
-            return null;
-        } catch (\Exception $e) {
-            Log::error("生成推荐码失败: " . $e->getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * 生成唯一的推荐码
-     *
-     * @param int $length 推荐码长度
-     * @return string
-     */
-    private function generateUniqueCode(int $length = 8): string
-    {
-        $attempts = 0;
-        $maxAttempts = 10;
-
-        do {
-            // 生成随机字符串
-            $code = strtoupper(Str::random($length));
-
-            // 检查是否已存在
-            $exists = PromotionReferralCode::where('code', $code)->exists();
-
-            $attempts++;
-        } while ($exists && $attempts < $maxAttempts);
-
-        // 如果多次尝试后仍然存在冲突,添加时间戳确保唯一性
-        if ($exists) {
-            $code = strtoupper(substr(Str::random($length - 4), 0, $length - 4) . substr(time(), -4));
-        }
-
-        return $code;
-    }
-
-    /**
-     * 获取用户的有效推荐码
-     *
-     * @param int $userId 用户ID
-     * @return PromotionReferralCode|null
-     */
-    public function getUserActiveCode(int $userId): ?PromotionReferralCode
-    {
-        $code = PromotionReferralCode::where('user_id', $userId)
-            ->where('status', REFERRAL_CODE_STATUS::ACTIVE)
-            ->where(function ($query) {
-                $query->whereNull('expire_time')
-                    ->orWhere('expire_time', '>', now());
-            })
-            ->first();
-
-        return $code;
-    }
-
-    /**
-     * 验证推荐码
-     *
-     * @param string $code 推荐码
-     * @return array 包含验证结果和推荐码信息
-     */
-    public function validateReferralCode(string $code): array
-    {
-        try {
-            // 查找推荐码
-            $referralCode = PromotionReferralCode::where('code', $code)->first();
-
-            if (!$referralCode) {
-                return [
-                    'valid' => false,
-                    'message' => '推荐码不存在',
-                    'code' => null
-                ];
-            }
-
-            // 检查状态
-            if ($referralCode->status != REFERRAL_CODE_STATUS::ACTIVE) {
-                return [
-                    'valid' => false,
-                    'message' => '推荐码已禁用',
-                    'code' => $referralCode
-                ];
-            }
-
-            // 检查过期时间
-            if ($referralCode->expire_time && $referralCode->expire_time->isPast()) {
-                return [
-                    'valid' => false,
-                    'message' => '推荐码已过期',
-                    'code' => $referralCode
-                ];
-            }
-
-            return [
-                'valid' => true,
-                'message' => '推荐码有效',
-                'code' => $referralCode
-            ];
-        } catch (\Exception $e) {
-            Log::error("验证推荐码失败: " . $e->getMessage());
-            return [
-                'valid' => false,
-                'message' => '验证推荐码时发生错误',
-                'code' => null
-            ];
-        }
-    }
-
-    /**
-     * 使用推荐码
-     *
-     * @param string $code 推荐码
-     * @param int $userId 使用者ID
-     * @param string $ipAddress IP地址
-     * @param string $userAgent 用户代理
-     * @return array 包含使用结果和信息
-     */
-    public function useReferralCode(string $code, int $userId, string $ipAddress, string $userAgent): array
-    {
-        try {
-            // 验证推荐码
-            $validation = $this->validateReferralCode($code);
-
-            if (!$validation['valid']) {
-                return [
-                    'success' => false,
-                    'message' => $validation['message']
-                ];
-            }
-
-            $referralCode = $validation['code'];
-
-            // 检查用户是否使用自己的推荐码
-            if ($referralCode->user_id == $userId) {
-                return [
-                    'success' => false,
-                    'message' => '不能使用自己的推荐码'
-                ];
-            }
-
-            // 检查用户是否已有推荐人
-            if ($this->referralLogic->hasReferrer($userId)) {
-                return [
-                    'success' => false,
-                    'message' => '用户已有推荐人,不能使用推荐码'
-                ];
-            }
-
-            // 检查是否形成循环推荐
-            if ($this->referralLogic->checkCircularReferral($userId, $referralCode->user_id)) {
-                return [
-                    'success' => false,
-                    'message' => '使用此推荐码会形成循环推荐关系'
-                ];
-            }
-
-            // 检查事务是否已开启
-            \UCore\Db\Helper::check_tr();
-
-            // 记录使用记录
-            $usage = new PromotionReferralCodeUsage();
-            $usage->code = $code;
-            $usage->code_owner_id = $referralCode->user_id;
-            $usage->user_id = $userId;
-            $usage->ip_address = $ipAddress;
-            $usage->user_agent = $userAgent;
-            $usage->status = PromotionReferralCodeUsage::STATUS_SUCCESS;
-            $usage->result = '成功使用推荐码';
-            $usage->save();
-
-            // 更新推荐码使用次数
-            $referralCode->usage_count += 1;
-            $referralCode->save();
-
-            // 建立推荐关系
-            $result = $this->referralLogic->createReferralRelation($userId, $referralCode->user_id);
-
-            if (!$result) {
-                // 如果建立推荐关系失败,更新使用记录状态
-                $usage->status = PromotionReferralCodeUsage::STATUS_FAILED;
-                $usage->result = '建立推荐关系失败';
-                $usage->save();
-
-                return [
-                    'success' => false,
-                    'message' => '建立推荐关系失败'
-                ];
-            }
-
-            return [
-                'success' => true,
-                'message' => '成功使用推荐码并建立推荐关系',
-                'referrer_id' => $referralCode->user_id
-            ];
-        } catch (\Exception $e) {
-            Log::error("使用推荐码失败: " . $e->getMessage());
-            return [
-                'success' => false,
-                'message' => '使用推荐码时发生错误'
-            ];
-        }
-    }
-
-    /**
-     * 禁用推荐码
-     *
-     * @param string $code 推荐码
-     * @return bool
-     */
-    public function disableReferralCode(string $code): bool
-    {
-        try {
-            $referralCode = PromotionReferralCode::where('code', $code)->first();
-
-            if (!$referralCode) {
-                return false;
-            }
-
-            $referralCode->status = REFERRAL_CODE_STATUS::DISABLED;
-            return $referralCode->save();
-        } catch (\Exception $e) {
-            Log::error("禁用推荐码失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 清理过期的推荐码
-     *
-     * @return int 清理的数量
-     */
-    public function cleanExpiredReferralCodes(): int
-    {
-        try {
-            return PromotionReferralCode::where('status', REFERRAL_CODE_STATUS::ACTIVE)
-                ->whereNotNull('expire_time')
-                ->where('expire_time', '<', now())
-                ->update(['status' => REFERRAL_CODE_STATUS::DISABLED]);
-        } catch (\Exception $e) {
-            Log::error("清理过期推荐码失败: " . $e->getMessage());
-            return 0;
-        }
-    }
-}

+ 0 - 397
app/Module/Promotion/Logics/ReferralLogic.php

@@ -1,397 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Logics;
-
-use App\Module\Promotion\Enums\REFERRAL_LEVEL;
-use App\Module\Promotion\Models\PromotionReferralChange;
-use App\Module\Promotion\Models\PromotionUserReferral;
-use App\Module\Promotion\Models\PromotionUserRelationCache;
-use Illuminate\Support\Facades\Log;
-use Illuminate\Support\Facades\Redis;
-
-/**
- * 推荐关系逻辑类
- *
- * 处理用户推荐关系的核心业务逻辑,包括建立推荐关系、修改推荐关系、
- * 查询推荐关系、检查循环推荐等功能。该类仅供内部使用,不对外提供服务。
- */
-class ReferralLogic
-{
-    /**
-     * 建立推荐关系
-     *
-     * @param int $userId 用户ID
-     * @param int $referrerId 推荐人ID
-     * @return bool
-     */
-    public function createReferralRelation(int $userId, int $referrerId): bool
-    {
-        // 验证是否已存在推荐关系
-        if ($this->hasReferrer($userId)) {
-            Log::warning("用户 {$userId} 已有推荐人,不能重复设置");
-            return false;
-        }
-
-        // 验证是否形成循环推荐
-        if ($this->checkCircularReferral($userId, $referrerId)) {
-            Log::warning("用户 {$userId} 和推荐人 {$referrerId} 形成循环推荐关系");
-            return false;
-        }
-
-        try {
-            // 创建直推关系
-            $referral = new PromotionUserReferral();
-            $referral->user_id = $userId;
-            $referral->referrer_id = $referrerId;
-            $result = $referral->save();
-
-            if ($result) {
-                // 更新关系缓存
-                $this->updateRelationCache($userId, null, $referrerId);
-            }
-
-            return $result;
-        } catch (\Exception $e) {
-            Log::error("创建推荐关系失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 更新推荐关系
-     *
-     * @param int $userId 用户ID
-     * @param int $newReferrerId 新推荐人ID
-     * @param string $reason 修改原因
-     * @param int $operatorId 操作人ID
-     * @return bool
-     */
-    public function updateReferralRelation(int $userId, int $newReferrerId, string $reason, int $operatorId): bool
-    {
-        // 获取旧的推荐人
-        $oldReferrerId = $this->getDirectReferrerId($userId);
-
-        // 如果新旧推荐人相同,无需更新
-        if ($oldReferrerId == $newReferrerId) {
-            return true;
-        }
-
-        // 验证是否形成循环推荐
-        if ($this->checkCircularReferral($userId, $newReferrerId)) {
-            Log::warning("用户 {$userId} 和新推荐人 {$newReferrerId} 形成循环推荐关系");
-            return false;
-        }
-
-        // 检查事务是否已开启
-        \UCore\Db\Helper::check_tr();
-
-        try {
-            // 删除旧的推荐关系
-            if ($oldReferrerId) {
-                PromotionUserReferral::where('user_id', $userId)->delete();
-            }
-
-            // 创建新的推荐关系
-            $referral = new PromotionUserReferral();
-            $referral->user_id = $userId;
-            $referral->referrer_id = $newReferrerId;
-            $result = $referral->save();
-
-            if ($result) {
-                // 记录修改历史
-                $change = new PromotionReferralChange();
-                $change->user_id = $userId;
-                $change->old_referrer_id = $oldReferrerId;
-                $change->new_referrer_id = $newReferrerId;
-                $change->change_time = now();
-                $change->change_reason = $reason;
-                $change->changed_by = $operatorId;
-                $change->save();
-
-                // 更新关系缓存
-                $this->updateRelationCache($userId, $oldReferrerId, $newReferrerId);
-            }
-
-            return $result;
-        } catch (\Exception $e) {
-            Log::error("更新推荐关系失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 获取用户的直接推荐人ID
-     *
-     * @param int $userId 用户ID
-     * @return int|null
-     */
-    public function getDirectReferrerId(int $userId): ?int
-    {
-        $referral = PromotionUserReferral::where('user_id', $userId)->first();
-        return $referral ? $referral->referrer_id : null;
-    }
-
-    /**
-     * 检查用户是否已有推荐人
-     *
-     * @param int $userId 用户ID
-     * @return bool
-     */
-    public function hasReferrer(int $userId): bool
-    {
-        return PromotionUserReferral::where('user_id', $userId)->exists();
-    }
-
-    /**
-     * 获取用户的直接下级
-     *
-     * @param int $userId 用户ID
-     * @return array
-     */
-    public function getDirectMembers(int $userId): array
-    {
-        return PromotionUserReferral::where('referrer_id', $userId)
-            ->with('user')
-            ->get()
-            ->toArray();
-    }
-
-    /**
-     * 获取用户的所有上级(包括直接和间接)
-     *
-     * @param int $userId 用户ID
-     * @param int $maxLevel 最大层级
-     * @return array
-     */
-    public function getAllReferrers(int $userId, int $maxLevel = 20): array
-    {
-        // 尝试从缓存获取
-        $cacheKey = "promotion:user:{$userId}:all_referrers";
-        $cachedData = Redis::get($cacheKey);
-
-        if ($cachedData !== null) {
-            return json_decode($cachedData, true);
-        }
-
-        // 从关系缓存表获取
-        $relations = PromotionUserRelationCache::where('user_id', $userId)
-            ->where('depth', '<=', $maxLevel)
-            ->orderBy('depth')
-            ->get();
-
-        $referrers = [];
-        foreach ($relations as $relation) {
-            $referrers[] = [
-                'user_id' => $relation->related_user_id,
-                'level' => $relation->level,
-                'depth' => $relation->depth,
-                'path' => $relation->path,
-            ];
-        }
-
-        // 缓存结果
-        Redis::setex($cacheKey, 86400, json_encode($referrers)); // 缓存1天
-
-        return $referrers;
-    }
-
-    /**
-     * 获取用户的所有团队成员(包括直接和间接)
-     *
-     * @param int $userId 用户ID
-     * @param int $maxLevel 最大层级
-     * @param int $page 页码
-     * @param int $pageSize 每页数量
-     * @return array
-     */
-    public function getAllPromotionMembers(int $userId, int $maxLevel = 20, int $page = 1, int $pageSize = 20): array
-    {
-        // 从关系缓存表获取
-        $query = PromotionUserRelationCache::where('related_user_id', $userId)
-            ->where('depth', '<=', $maxLevel);
-
-        $total = $query->count();
-
-        $relations = $query->orderBy('depth')
-            ->offset(($page - 1) * $pageSize)
-            ->limit($pageSize)
-            ->with('user')
-            ->get();
-
-        $members = [];
-        foreach ($relations as $relation) {
-            if ($relation->user) {
-                $members[] = [
-                    'user_id' => $relation->user_id,
-                    'username' => $relation->user->username ?? '',
-                    'level' => $relation->level,
-                    'depth' => $relation->depth,
-                    'path' => $relation->path,
-                    'created_at' => $relation->created_at,
-                ];
-            }
-        }
-
-        return [
-            'total' => $total,
-            'page' => $page,
-            'page_size' => $pageSize,
-            'total_pages' => ceil($total / $pageSize),
-            'members' => $members
-        ];
-    }
-
-    /**
-     * 检查是否形成循环推荐
-     *
-     * @param int $userId 用户ID
-     * @param int $referrerId 推荐人ID
-     * @return bool
-     */
-    public function checkCircularReferral(int $userId, int $referrerId): bool
-    {
-        // 如果用户ID和推荐人ID相同,直接形成循环
-        if ($userId == $referrerId) {
-            return true;
-        }
-
-        // 获取推荐人的所有上级
-        $referrerReferrers = $this->getAllReferrers($referrerId);
-
-        // 检查用户是否在推荐人的上级中
-        foreach ($referrerReferrers as $referrer) {
-            if ($referrer['user_id'] == $userId) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * 更新关系缓存
-     *
-     * @param int $userId 用户ID
-     * @param int|null $oldReferrerId 旧推荐人ID
-     * @param int $newReferrerId 新推荐人ID
-     * @return void
-     */
-    private function updateRelationCache(int $userId, ?int $oldReferrerId, int $newReferrerId): void
-    {
-        // 检查事务是否已开启
-        \UCore\Db\Helper::check_tr();
-
-        try {
-                // 1. 删除用户及其所有下级与旧上级及其所有上级的关系缓存
-                if ($oldReferrerId) {
-                    // 获取用户的所有下级ID
-                    $downlineIds = PromotionUserRelationCache::where('related_user_id', $userId)
-                        ->pluck('user_id')
-                        ->toArray();
-                    $downlineIds[] = $userId; // 包括用户自身
-
-                    // 获取旧上级的所有上级ID
-                    $upperReferrerIds = PromotionUserRelationCache::where('user_id', $oldReferrerId)
-                        ->pluck('related_user_id')
-                        ->toArray();
-                    $upperReferrerIds[] = $oldReferrerId; // 包括直接上级
-
-                    // 删除关系缓存
-                    PromotionUserRelationCache::whereIn('user_id', $downlineIds)
-                        ->whereIn('related_user_id', $upperReferrerIds)
-                        ->delete();
-
-                    // 清除Redis缓存
-                    foreach ($downlineIds as $downlineId) {
-                        Redis::del("promotion:user:{$downlineId}:all_referrers");
-                    }
-
-                    foreach ($upperReferrerIds as $upperReferrerId) {
-                        Redis::del("promotion:user:{$upperReferrerId}:all_members");
-                    }
-                }
-
-                // 2. 为用户创建与新上级的直接关系缓存
-                $directRelation = new PromotionUserRelationCache();
-                $directRelation->user_id = $userId;
-                $directRelation->related_user_id = $newReferrerId;
-                $directRelation->level = REFERRAL_LEVEL::DIRECT;
-                $directRelation->path = (string)$newReferrerId;
-                $directRelation->depth = 1;
-                $directRelation->save();
-
-                // 3. 获取新上级的所有上级
-                $upperRelations = PromotionUserRelationCache::where('user_id', $newReferrerId)->get();
-
-                // 4. 为用户创建与新上级的所有上级的间接关系缓存
-                foreach ($upperRelations as $upperRelation) {
-                    $indirectRelation = new PromotionUserRelationCache();
-                    $indirectRelation->user_id = $userId;
-                    $indirectRelation->related_user_id = $upperRelation->related_user_id;
-                    $indirectRelation->level = REFERRAL_LEVEL::INDIRECT;
-                    $indirectRelation->path = $newReferrerId . ',' . $upperRelation->path;
-                    $indirectRelation->depth = $upperRelation->depth + 1;
-                    $indirectRelation->save();
-                }
-
-                // 5. 获取用户的所有下级
-                $downlineRelations = PromotionUserRelationCache::where('related_user_id', $userId)->get();
-
-                // 6. 为用户的所有下级创建与新上级及其所有上级的关系缓存
-                foreach ($downlineRelations as $downlineRelation) {
-                    // 创建下级与新上级的关系
-                    $downlineToReferrer = new PromotionUserRelationCache();
-                    $downlineToReferrer->user_id = $downlineRelation->user_id;
-                    $downlineToReferrer->related_user_id = $newReferrerId;
-                    $downlineToReferrer->level = REFERRAL_LEVEL::INDIRECT;
-                    $downlineToReferrer->path = $downlineRelation->path . ',' . $newReferrerId;
-                    $downlineToReferrer->depth = $downlineRelation->depth + 1;
-                    $downlineToReferrer->save();
-
-                    // 创建下级与新上级的所有上级的关系
-                    foreach ($upperRelations as $upperRelation) {
-                        $downlineToUpper = new PromotionUserRelationCache();
-                        $downlineToUpper->user_id = $downlineRelation->user_id;
-                        $downlineToUpper->related_user_id = $upperRelation->related_user_id;
-                        $downlineToUpper->level = REFERRAL_LEVEL::INDIRECT;
-                        $downlineToUpper->path = $downlineRelation->path . ',' . $newReferrerId . ',' . $upperRelation->path;
-                        $downlineToUpper->depth = $downlineRelation->depth + $upperRelation->depth + 1;
-                        $downlineToUpper->save();
-                    }
-
-                    // 清除下级的Redis缓存
-                    Redis::del("promotion:user:{$downlineRelation->user_id}:all_referrers");
-                }
-
-                // 7. 清除新上级及其所有上级的Redis缓存
-                Redis::del("promotion:user:{$newReferrerId}:all_members");
-                foreach ($upperRelations as $upperRelation) {
-                    Redis::del("promotion:user:{$upperRelation->related_user_id}:all_members");
-                }
-        } catch (\Exception $e) {
-            Log::error("更新关系缓存失败: " . $e->getMessage());
-        }
-    }
-
-    /**
-     * 统计用户的直推人数
-     *
-     * @param int $userId 用户ID
-     * @return int
-     */
-    public function countDirectReferrals(int $userId): int
-    {
-        return PromotionUserReferral::where('referrer_id', $userId)->count();
-    }
-
-    /**
-     * 统计用户的团队总人数
-     *
-     * @param int $userId 用户ID
-     * @return int
-     */
-    public function countPromotionMembers(int $userId): int
-    {
-        return PromotionUserRelationCache::where('related_user_id', $userId)->count();
-    }
-}

+ 0 - 247
app/Module/Promotion/Logics/RelationCacheLogic.php

@@ -1,247 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Logics;
-
-use App\Module\Promotion\Enums\REFERRAL_LEVEL;
-use App\Module\Promotion\Models\PromotionUserReferral;
-use App\Module\Promotion\Models\PromotionUserRelationCache;
-use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Facades\Log;
-use Illuminate\Support\Facades\Redis;
-
-/**
- * 关系缓存逻辑类
- *
- * 处理用户关系缓存的核心业务逻辑,包括生成关系缓存、清理关系缓存、
- * 重建关系缓存等功能。该类仅供内部使用,不对外提供服务。
- */
-class RelationCacheLogic
-{
-    /**
-     * 生成用户的关系缓存
-     *
-     * @param int $userId 用户ID
-     * @return bool
-     */
-    public function generateUserRelationCache(int $userId): bool
-    {
-        try {
-            // 清除用户的现有关系缓存
-            $this->clearUserRelationCache($userId);
-
-            // 获取用户的直接推荐人
-            $referral = PromotionUserReferral::where('user_id', $userId)->first();
-
-            if (!$referral) {
-                Log::info("用户 {$userId} 没有推荐人,无需生成关系缓存");
-                return true;
-            }
-
-            $referrerId = $referral->referrer_id;
-
-            // 创建直接关系缓存
-            $directRelation = new PromotionUserRelationCache();
-            $directRelation->user_id = $userId;
-            $directRelation->related_user_id = $referrerId;
-            $directRelation->level = REFERRAL_LEVEL::DIRECT;
-            $directRelation->path = (string)$referrerId;
-            $directRelation->depth = 1;
-            $directRelation->save();
-
-            // 获取推荐人的所有上级
-            $upperRelations = PromotionUserRelationCache::where('user_id', $referrerId)->get();
-
-            // 创建间接关系缓存
-            foreach ($upperRelations as $upperRelation) {
-                $indirectRelation = new PromotionUserRelationCache();
-                $indirectRelation->user_id = $userId;
-                $indirectRelation->related_user_id = $upperRelation->related_user_id;
-                $indirectRelation->level = REFERRAL_LEVEL::INDIRECT;
-                $indirectRelation->path = $referrerId . ',' . $upperRelation->path;
-                $indirectRelation->depth = $upperRelation->depth + 1;
-                $indirectRelation->save();
-            }
-
-            // 清除Redis缓存
-            Redis::del("promotion:user:{$userId}:all_referrers");
-
-            return true;
-        } catch (\Exception $e) {
-            Log::error("生成用户关系缓存失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 清除用户的关系缓存
-     *
-     * @param int $userId 用户ID
-     * @return bool
-     */
-    public function clearUserRelationCache(int $userId): bool
-    {
-        try {
-            // 删除数据库中的关系缓存
-            PromotionUserRelationCache::where('user_id', $userId)->delete();
-
-            // 清除Redis缓存
-            Redis::del("promotion:user:{$userId}:all_referrers");
-
-            return true;
-        } catch (\Exception $e) {
-            Log::error("清除用户关系缓存失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 重建所有用户的关系缓存
-     *
-     * @param int $batchSize 批处理大小
-     * @return array 包含成功和失败的数量
-     */
-    public function rebuildAllRelationCache(int $batchSize = 100): array
-    {
-        try {
-            // 清空关系缓存表
-            PromotionUserRelationCache::truncate();
-
-            // 清除所有Redis缓存
-            $keys = Redis::keys("promotion:user:*:all_referrers");
-            if (!empty($keys)) {
-                Redis::del($keys);
-            }
-
-            // 获取所有用户ID
-            $userIds = PromotionUserReferral::pluck('user_id')->toArray();
-
-            $successCount = 0;
-            $failCount = 0;
-
-            // 分批处理
-            $chunks = array_chunk($userIds, $batchSize);
-
-            foreach ($chunks as $chunk) {
-                foreach ($chunk as $userId) {
-                    if ($this->generateUserRelationCache($userId)) {
-                        $successCount++;
-                    } else {
-                        $failCount++;
-                    }
-                }
-            }
-
-            return [
-                'success' => $successCount,
-                'fail' => $failCount,
-                'total' => count($userIds)
-            ];
-        } catch (\Exception $e) {
-            Log::error("重建所有关系缓存失败: " . $e->getMessage());
-            return [
-                'success' => 0,
-                'fail' => 0,
-                'total' => 0,
-                'error' => $e->getMessage()
-            ];
-        }
-    }
-
-    /**
-     * 检查关系缓存的完整性
-     *
-     * @return array 包含检查结果
-     */
-    public function checkRelationCacheIntegrity(): array
-    {
-        try {
-            $totalUsers = PromotionUserReferral::count();
-            $usersWithCache = PromotionUserRelationCache::distinct('user_id')->count('user_id');
-            $missingUsers = $totalUsers - $usersWithCache;
-
-            $circularRelations = DB::select("
-                SELECT r1.user_id, r1.referrer_id
-                FROM promotion_user_referrals r1
-                JOIN promotion_user_referrals r2 ON r1.referrer_id = r2.user_id
-                WHERE r2.referrer_id = r1.user_id
-            ");
-
-            $orphanedCaches = DB::select("
-                SELECT c.user_id
-                FROM promotion_user_relation_cache c
-                LEFT JOIN promotion_user_referrals r ON c.user_id = r.user_id
-                WHERE r.user_id IS NULL
-            ");
-
-            return [
-                'total_users' => $totalUsers,
-                'users_with_cache' => $usersWithCache,
-                'missing_users' => $missingUsers,
-                'circular_relations' => count($circularRelations),
-                'orphaned_caches' => count($orphanedCaches)
-            ];
-        } catch (\Exception $e) {
-            Log::error("检查关系缓存完整性失败: " . $e->getMessage());
-            return [
-                'error' => $e->getMessage()
-            ];
-        }
-    }
-
-    /**
-     * 修复关系缓存问题
-     *
-     * @return array 包含修复结果
-     */
-    public function fixRelationCacheIssues(): array
-    {
-        try {
-            // 检查完整性
-            $integrity = $this->checkRelationCacheIntegrity();
-
-            $fixed = [
-                'missing_users' => 0,
-                'orphaned_caches' => 0
-            ];
-
-            // 修复缺失的用户缓存
-            if ($integrity['missing_users'] > 0) {
-                $usersWithCache = PromotionUserRelationCache::distinct('user_id')->pluck('user_id')->toArray();
-                $allUsers = PromotionUserReferral::pluck('user_id')->toArray();
-                $missingUsers = array_diff($allUsers, $usersWithCache);
-
-                foreach ($missingUsers as $userId) {
-                    if ($this->generateUserRelationCache($userId)) {
-                        $fixed['missing_users']++;
-                    }
-                }
-            }
-
-            // 清理孤立的缓存
-            if ($integrity['orphaned_caches'] > 0) {
-                $orphanedCaches = DB::select("
-                    SELECT c.user_id
-                    FROM promotion_user_relation_cache c
-                    LEFT JOIN promotion_user_referrals r ON c.user_id = r.user_id
-                    WHERE r.user_id IS NULL
-                ");
-
-                foreach ($orphanedCaches as $cache) {
-                    if ($this->clearUserRelationCache($cache->user_id)) {
-                        $fixed['orphaned_caches']++;
-                    }
-                }
-            }
-
-            return [
-                'integrity' => $integrity,
-                'fixed' => $fixed
-            ];
-        } catch (\Exception $e) {
-            Log::error("修复关系缓存问题失败: " . $e->getMessage());
-            return [
-                'error' => $e->getMessage()
-            ];
-        }
-    }
-}

+ 0 - 326
app/Module/Promotion/Logics/TalentLogic.php

@@ -1,326 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Logics;
-
-use App\Module\Promotion\Enums\TALENT_LEVEL;
-use App\Module\Promotion\Models\PromotionTalentConfig;
-use App\Module\Promotion\Models\PromotionUserTalent;
-use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Facades\Log;
-use Illuminate\Support\Facades\Redis;
-
-/**
- * 达人等级逻辑类
- *
- * 处理用户达人等级的核心业务逻辑,包括计算达人等级、更新达人等级、
- * 获取达人等级配置等功能。该类仅供内部使用,不对外提供服务。
- */
-class TalentLogic
-{
-    /**
-     * @var ReferralLogic
-     */
-    protected $referralLogic;
-
-    /**
-     * 构造函数
-     *
-     * @param ReferralLogic $referralLogic
-     */
-    public function __construct(ReferralLogic $referralLogic)
-    {
-        $this->referralLogic = $referralLogic;
-    }
-
-    /**
-     * 获取用户的达人等级信息
-     *
-     * @param int $userId 用户ID
-     * @return PromotionUserTalent|null
-     */
-    public function getUserTalent(int $userId): ?PromotionUserTalent
-    {
-        // 尝试从缓存获取
-        $cacheKey = "promotion:user:{$userId}:talent";
-        $cachedData = Redis::get($cacheKey);
-
-        if ($cachedData !== null) {
-            $talentData = json_decode($cachedData, true);
-            $talent = new PromotionUserTalent();
-            $talent->fill($talentData);
-            return $talent;
-        }
-
-        // 从数据库获取
-        $talent = PromotionUserTalent::where('user_id', $userId)->first();
-
-        // 如果不存在,创建一个默认的达人等级记录
-        if (!$talent) {
-            $talent = $this->createDefaultTalent($userId);
-        }
-
-        // 缓存结果
-        if ($talent) {
-            Redis::setex($cacheKey, 86400, json_encode($talent->toArray())); // 缓存1天
-        }
-
-        return $talent;
-    }
-
-    /**
-     * 创建默认的达人等级记录
-     *
-     * @param int $userId 用户ID
-     * @return PromotionUserTalent|null
-     */
-    public function createDefaultTalent(int $userId): ?PromotionUserTalent
-    {
-        try {
-            $talent = new PromotionUserTalent();
-            $talent->user_id = $userId;
-            $talent->talent_level = TALENT_LEVEL::NONE;
-            $talent->direct_count = 0;
-            $talent->promotion_count = 0;
-            $talent->save();
-
-            return $talent;
-        } catch (\Exception $e) {
-            Log::error("创建默认达人等级记录失败: " . $e->getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * 更新用户的达人等级
-     *
-     * @param int $userId 用户ID
-     * @param int $talentLevel 达人等级
-     * @return bool
-     */
-    public function updateTalentLevel(int $userId, int $talentLevel): bool
-    {
-        try {
-            $talent = $this->getUserTalent($userId);
-
-            if (!$talent) {
-                return false;
-            }
-
-            // 如果等级没有变化,无需更新
-            if ($talent->talent_level == $talentLevel) {
-                return true;
-            }
-
-            $talent->talent_level = $talentLevel;
-            $result = $talent->save();
-
-            if ($result) {
-                // 清除缓存
-                Redis::del("promotion:user:{$userId}:talent");
-            }
-
-            return $result;
-        } catch (\Exception $e) {
-            Log::error("更新达人等级失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 更新用户的团队统计数据
-     *
-     * @param int $userId 用户ID
-     * @return bool
-     */
-    public function updatePromotionCounts(int $userId): bool
-    {
-        try {
-            $talent = $this->getUserTalent($userId);
-
-            if (!$talent) {
-                return false;
-            }
-
-            // 计算直推人数
-            $directCount = $this->referralLogic->countDirectReferrals($userId);
-
-            // 计算团队总人数
-            $promotionCount = $this->referralLogic->countPromotionMembers($userId);
-
-            // 更新数据
-            $talent->direct_count = $directCount;
-            $talent->promotion_count = $promotionCount;
-            $result = $talent->save();
-
-            if ($result) {
-                // 清除缓存
-                Redis::del("promotion:user:{$userId}:talent");
-            }
-
-            return $result;
-        } catch (\Exception $e) {
-            Log::error("更新团队统计数据失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 检查并更新用户的达人等级
-     *
-     * @param int $userId 用户ID
-     * @return bool
-     */
-    public function checkAndUpdateTalentLevel(int $userId): bool
-    {
-        try {
-            // 更新团队统计数据
-            $this->updatePromotionCounts($userId);
-
-            // 获取用户的达人信息
-            $talent = $this->getUserTalent($userId);
-
-            if (!$talent) {
-                return false;
-            }
-
-            // 获取所有达人等级配置
-            $configs = $this->getAllTalentConfigs();
-
-            // 计算应该的达人等级
-            $newLevel = TALENT_LEVEL::NONE;
-
-            foreach ($configs as $config) {
-                if ($talent->direct_count >= $config->direct_count_required &&
-                    $talent->promotion_count >= $config->promotion_count_required) {
-                    $newLevel = $config->level;
-                }
-            }
-
-            // 如果等级有变化,更新达人等级
-            if ($talent->talent_level != $newLevel) {
-                return $this->updateTalentLevel($userId, $newLevel);
-            }
-
-            return true;
-        } catch (\Exception $e) {
-            Log::error("检查并更新达人等级失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 获取达人等级配置
-     *
-     * @param int $level 等级
-     * @return PromotionTalentConfig|null
-     */
-    public function getTalentConfig(int $level): ?PromotionTalentConfig
-    {
-        // 尝试从缓存获取
-        $cacheKey = "promotion:talent_config:{$level}";
-        $cachedData = Redis::get($cacheKey);
-
-        if ($cachedData !== null) {
-            $configData = json_decode($cachedData, true);
-            $config = new PromotionTalentConfig();
-            $config->fill($configData);
-            return $config;
-        }
-
-        // 从数据库获取
-        $config = PromotionTalentConfig::where('level', $level)->first();
-
-        // 缓存结果
-        if ($config) {
-            Redis::setex($cacheKey, 86400 * 7, json_encode($config->toArray())); // 缓存7天
-        }
-
-        return $config;
-    }
-
-    /**
-     * 获取所有达人等级配置
-     *
-     * @return array
-     */
-    public function getAllTalentConfigs(): array
-    {
-        // 尝试从缓存获取
-        $cacheKey = "promotion:talent_configs";
-        $cachedData = Redis::get($cacheKey);
-
-        if ($cachedData !== null) {
-            $configsData = json_decode($cachedData, true);
-            $configs = [];
-
-            foreach ($configsData as $configData) {
-                $config = new PromotionTalentConfig();
-                $config->fill($configData);
-                $configs[] = $config;
-            }
-
-            return $configs;
-        }
-
-        // 从数据库获取
-        $configs = PromotionTalentConfig::orderBy('level')->get()->toArray();
-
-        // 缓存结果
-        Redis::setex($cacheKey, 86400 * 7, json_encode($configs)); // 缓存7天
-
-        return $configs;
-    }
-
-    /**
-     * 获取达人等级分成比例
-     *
-     * @param int $level 等级
-     * @return float
-     */
-    public function getTalentProfitRate(int $level): float
-    {
-        $config = $this->getTalentConfig($level);
-
-        if (!$config) {
-            return 0.0;
-        }
-
-        return $config->profit_rate;
-    }
-
-    /**
-     * 获取达人等级权益
-     *
-     * @param int $level 等级
-     * @return array
-     */
-    public function getTalentBenefits(int $level): array
-    {
-        $config = $this->getTalentConfig($level);
-
-        if (!$config || empty($config->benefits)) {
-            return [];
-        }
-
-        return is_array($config->benefits) ? $config->benefits : json_decode($config->benefits, true);
-    }
-
-    /**
-     * 批量更新用户的达人等级
-     *
-     * @param array $userIds 用户ID数组
-     * @return int 成功更新的数量
-     */
-    public function batchUpdateTalentLevels(array $userIds): int
-    {
-        $successCount = 0;
-
-        foreach ($userIds as $userId) {
-            if ($this->checkAndUpdateTalentLevel($userId)) {
-                $successCount++;
-            }
-        }
-
-        return $successCount;
-    }
-}

+ 0 - 104
app/Module/Promotion/Models/PromotionInviteReward.php

@@ -1,104 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use UCore\ModelCore;
-
-/**
- * 邀请奖励记录
- *
- * field start 
- * field end
- */
-class PromotionInviteReward extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_invite_rewards';
-
-
-
-    /**
-     * 奖励类型常量
-     */
-    const REWARD_TYPE_ITEM = 'item';
-    const REWARD_TYPE_COIN = 'coin';
-    const REWARD_TYPE_EXP = 'exp';
-
-    /**
-     * 奖励来源常量
-     */
-    const REWARD_SOURCE_REGISTER = 'register';
-    const REWARD_SOURCE_UPGRADE = 'upgrade';
-    const REWARD_SOURCE_TASK = 'task';
-
-    /**
-     * 状态常量
-     */
-    const STATUS_PENDING = 0;
-    const STATUS_ISSUED = 1;
-    const STATUS_EXPIRED = 2;
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 获取用户信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 获取被邀请用户信息
-     *
-     * @return BelongsTo
-     */
-    public function invitedUser()
-    {
-        return $this->belongsTo('App\Models\User', 'invited_user_id');
-    }
-
-    /**
-     * 获取物品信息(如果奖励类型为物品)
-     *
-     * @return BelongsTo|null
-     */
-    public function item()
-    {
-        if ($this->reward_type != self::REWARD_TYPE_ITEM) {
-            return null;
-        }
-
-        return $this->belongsTo('App\Module\GameItems\Models\Item', 'reward_id');
-    }
-
-    /**
-     * 判断奖励是否已发放
-     *
-     * @return bool
-     */
-    public function isIssued(): bool
-    {
-        return $this->status == self::STATUS_ISSUED;
-    }
-
-    /**
-     * 判断奖励是否已过期
-     *
-     * @return bool
-     */
-    public function isExpired(): bool
-    {
-        return $this->status == self::STATUS_EXPIRED;
-    }
-}

+ 0 - 79
app/Module/Promotion/Models/PromotionProfit.php

@@ -1,79 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use App\Module\Promotion\Enums\REFERRAL_LEVEL;
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use UCore\ModelCore;
-
-/**
- * 团队收益记录
- *
- * field start 
- * field end
- */
-class PromotionProfit extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_profits';
-
-
-
-    /**
-     * 指示模型是否应该被打上时间戳
-     *
-     * @var bool
-     */
-    public $timestamps = false;
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 应该被转换为原生类型的属性
-     *
-     * @var array
-     */
-    protected $casts = [
-        'profit_rate' => 'float',
-        'source_type' => PROFIT_SOURCE_TYPE::class,
-        'relation_type' => REFERRAL_LEVEL::class,
-    ];
-
-    /**
-     * 获取收益用户信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 获取团队成员信息
-     *
-     * @return BelongsTo
-     */
-    public function promotionMember()
-    {
-        return $this->belongsTo('App\Models\User', 'promotion_member_id');
-    }
-
-    /**
-     * 获取物品信息
-     *
-     * @return BelongsTo
-     */
-    public function item()
-    {
-        return $this->belongsTo('App\Module\GameItems\Models\Item', 'item_id');
-    }
-}

+ 0 - 69
app/Module/Promotion/Models/PromotionProfitRule.php

@@ -1,69 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use UCore\ModelCore;
-
-/**
- * 收益分成规则
- *
- * field start 
- * field end
- */
-class PromotionProfitRule extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_profit_rules';
-
-
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 应该被转换为原生类型的属性
-     *
-     * @var array
-     */
-    protected $casts = [
-        'source_type' => PROFIT_SOURCE_TYPE::class,
-        'direct_profit_rate' => 'float',
-        'status' => 'boolean',
-        'rules' => 'json',
-    ];
-
-    /**
-     * 获取规则的特定属性
-     *
-     * @param string $key
-     * @param mixed $default
-     * @return mixed
-     */
-    public function getRuleAttribute(string $key, $default = null)
-    {
-        if (empty($this->rules)) {
-            return $default;
-        }
-
-        $rules = is_array($this->rules) ? $this->rules : json_decode($this->rules, true);
-
-        return $rules[$key] ?? $default;
-    }
-
-    /**
-     * 判断规则是否有效
-     *
-     * @return bool
-     */
-    public function isActive(): bool
-    {
-        return (bool)$this->status;
-    }
-}

+ 0 - 86
app/Module/Promotion/Models/PromotionReferralChange.php

@@ -1,86 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use UCore\ModelCore;
-
-/**
- * 推荐关系修改记录
- *
- * field start 
- * field end
- */
-class PromotionReferralChange extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_referral_changes';
-
-
-
-    /**
-     * 指示模型是否应该被打上时间戳
-     *
-     * @var bool
-     */
-    public $timestamps = false;
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 应该被转换为日期的属性
-     *
-     * @var array
-     */
-    protected $dates = [
-        'change_time',
-        'created_at',
-    ];
-
-    /**
-     * 获取用户信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 获取旧推荐人信息
-     *
-     * @return BelongsTo
-     */
-    public function oldReferrer()
-    {
-        return $this->belongsTo('App\Models\User', 'old_referrer_id');
-    }
-
-    /**
-     * 获取新推荐人信息
-     *
-     * @return BelongsTo
-     */
-    public function newReferrer()
-    {
-        return $this->belongsTo('App\Models\User', 'new_referrer_id');
-    }
-
-    /**
-     * 获取操作人信息
-     *
-     * @return BelongsTo
-     */
-    public function operator()
-    {
-        return $this->belongsTo('App\Models\User', 'changed_by');
-    }
-}

+ 0 - 89
app/Module/Promotion/Models/PromotionReferralCode.php

@@ -1,89 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use App\Module\Promotion\Enums\REFERRAL_CODE_STATUS;
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Database\Eloquent\Relations\HasMany;
-use UCore\ModelCore;
-
-/**
- * 推荐码
- *
- * field start 
- * field end
- */
-class PromotionReferralCode extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_referral_codes';
-
-
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 应该被转换为日期的属性
-     *
-     * @var array
-     */
-    protected $dates = [
-        'expire_time',
-        'created_at',
-        'updated_at',
-    ];
-
-    /**
-     * 应该被转换为原生类型的属性
-     *
-     * @var array
-     */
-    protected $casts = [
-        'status' => REFERRAL_CODE_STATUS::class,
-    ];
-
-    /**
-     * 获取用户信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 获取推荐码使用记录
-     *
-     * @return HasMany
-     */
-    public function usages()
-    {
-        return $this->hasMany(PromotionReferralCodeUsage::class, 'code', 'code');
-    }
-
-    /**
-     * 判断推荐码是否有效
-     *
-     * @return bool
-     */
-    public function isValid(): bool
-    {
-        if ($this->status != REFERRAL_CODE_STATUS::ACTIVE) {
-            return false;
-        }
-
-        if ($this->expire_time && $this->expire_time->isPast()) {
-            return false;
-        }
-
-        return true;
-    }
-}

+ 0 - 86
app/Module/Promotion/Models/PromotionReferralCodeUsage.php

@@ -1,86 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use UCore\ModelCore;
-
-/**
- * 邀请码使用记录
- *
- * field start 
- * field end
- */
-class PromotionReferralCodeUsage extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_referral_code_usages';
-
-
-
-    /**
-     * 状态常量
-     */
-    const STATUS_FAILED = 0;
-    const STATUS_SUCCESS = 1;
-    const STATUS_REVOKED = 2;
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 获取邀请码信息
-     *
-     * @return BelongsTo
-     */
-    public function referralCode()
-    {
-        return $this->belongsTo(PromotionReferralCode::class, 'code', 'code');
-    }
-
-    /**
-     * 获取邀请码所有者信息
-     *
-     * @return BelongsTo
-     */
-    public function codeOwner()
-    {
-        return $this->belongsTo('App\Models\User', 'code_owner_id');
-    }
-
-    /**
-     * 获取使用者信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 判断使用是否成功
-     *
-     * @return bool
-     */
-    public function isSuccess(): bool
-    {
-        return $this->status == self::STATUS_SUCCESS;
-    }
-
-    /**
-     * 判断使用是否已撤销
-     *
-     * @return bool
-     */
-    public function isRevoked(): bool
-    {
-        return $this->status == self::STATUS_REVOKED;
-    }
-}

+ 0 - 65
app/Module/Promotion/Models/PromotionTalentConfig.php

@@ -1,65 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use App\Module\Promotion\Enums\TALENT_LEVEL;
-use Illuminate\Database\Eloquent\Relations\HasMany;
-use UCore\ModelCore;
-
-/**
- * 达人等级配置
- *
- * field start 
- * field end
- */
-class PromotionTalentConfig extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_talent_configs';
-
-
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 应该被转换为原生类型的属性
-     *
-     * @var array
-     */
-    protected $casts = [
-        'level' => TALENT_LEVEL::class,
-        'profit_rate' => 'float',
-        'benefits' => 'json',
-    ];
-
-    /**
-     * 获取拥有此等级的用户
-     *
-     * @return HasMany
-     */
-    public function users()
-    {
-        return $this->hasMany(PromotionUserTalent::class, 'talent_level', 'level');
-    }
-
-    /**
-     * 获取等级图标的完整URL
-     *
-     * @return string|null
-     */
-    public function getIconUrlAttribute()
-    {
-        if (empty($this->icon)) {
-            return null;
-        }
-
-        return asset($this->icon);
-    }
-}

+ 0 - 49
app/Module/Promotion/Models/PromotionUserReferral.php

@@ -1,49 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use UCore\ModelCore;
-
-/**
- * 用户推荐关系
- *
- * field start 
- * field end
- */
-class PromotionUserReferral extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_user_referrals';
-
-
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 获取被推荐用户信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 获取推荐人信息
-     *
-     * @return BelongsTo
-     */
-    public function referrer()
-    {
-        return $this->belongsTo('App\Models\User', 'referrer_id');
-    }
-}

+ 0 - 84
app/Module/Promotion/Models/PromotionUserRelationCache.php

@@ -1,84 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use App\Module\Promotion\Enums\REFERRAL_LEVEL;
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use UCore\ModelCore;
-
-/**
- * 用户关系缓存
- *
- * field start 
- * field end
- */
-class PromotionUserRelationCache extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_user_relation_cache';
-
-
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 应该被转换为原生类型的属性
-     *
-     * @var array
-     */
-    protected $casts = [
-        'level' => REFERRAL_LEVEL::class,
-        'depth' => 'integer',
-    ];
-
-    /**
-     * 获取用户信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 获取关联用户信息
-     *
-     * @return BelongsTo
-     */
-    public function relatedUser()
-    {
-        return $this->belongsTo('App\Models\User', 'related_user_id');
-    }
-
-    /**
-     * 获取关系路径数组
-     *
-     * @return array
-     */
-    public function getPathArrayAttribute(): array
-    {
-        if (empty($this->path)) {
-            return [];
-        }
-
-        return explode(',', $this->path);
-    }
-
-    /**
-     * 判断是否为直接关系
-     *
-     * @return bool
-     */
-    public function isDirectRelation(): bool
-    {
-        return $this->level == REFERRAL_LEVEL::DIRECT;
-    }
-}

+ 0 - 58
app/Module/Promotion/Models/PromotionUserTalent.php

@@ -1,58 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Models;
-
-use App\Module\Promotion\Enums\TALENT_LEVEL;
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use UCore\ModelCore;
-
-/**
- * 达人等级
- *
- * field start 
- * field end
- */
-class PromotionUserTalent extends ModelCore
-{
-    /**
-     * 与模型关联的表名
-     *
-     * @var string
-     */
-    protected $table = 'promotion_user_talents';
-
-
-    // attrlist start 
-    protected $fillable = [
-    ];
-    // attrlist end
-
-    /**
-     * 应该被转换为原生类型的属性
-     *
-     * @var array
-     */
-    protected $casts = [
-        'talent_level' => TALENT_LEVEL::class,
-    ];
-
-    /**
-     * 获取用户信息
-     *
-     * @return BelongsTo
-     */
-    public function user()
-    {
-        return $this->belongsTo('App\Models\User', 'user_id');
-    }
-
-    /**
-     * 获取达人等级配置
-     *
-     * @return BelongsTo
-     */
-    public function config()
-    {
-        return $this->belongsTo(PromotionTalentConfig::class, 'talent_level', 'level');
-    }
-}

+ 0 - 84
app/Module/Promotion/Providers/PromotionServiceProvider.php

@@ -1,84 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Providers;
-
-use App\Module\Promotion\Commands\CleanExpiredReferralCodesCommand;
-use App\Module\Promotion\Commands\RebuildRelationCacheCommand;
-use App\Module\Promotion\Commands\UpdateTalentLevelsCommand;
-use App\Module\Promotion\Events\ReferralCreatedEvent;
-use App\Module\Promotion\Events\ReferralUpdatedEvent;
-use App\Module\Promotion\Events\PromotionProfitCreatedEvent;
-use App\Module\Promotion\Listeners\DistributePromotionProfitListener;
-use App\Module\Promotion\Listeners\UpdateTalentLevelListener;
-use App\Module\Promotion\Listeners\UpdatePromotionCountsListener;
-use App\Module\Promotion\Logics\ReferralCodeLogic;
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Logics\RelationCacheLogic;
-use App\Module\Promotion\Logics\TalentLogic;
-use App\Module\Promotion\Logics\PromotionProfitLogic;
-use Illuminate\Support\Facades\Event;
-use Illuminate\Support\ServiceProvider;
-
-/**
- * 团队模块服务提供者
- *
- * 注册团队模块的服务、事件、命令等。
- */
-class PromotionServiceProvider extends ServiceProvider
-{
-    /**
-     * 注册服务
-     *
-     * @return void
-     */
-    public function register()
-    {
-        // 注册逻辑层类
-        $this->app->singleton(ReferralLogic::class, function ($app) {
-            return new ReferralLogic();
-        });
-
-        $this->app->singleton(RelationCacheLogic::class, function ($app) {
-            return new RelationCacheLogic();
-        });
-
-        $this->app->singleton(TalentLogic::class, function ($app) {
-            return new TalentLogic($app->make(ReferralLogic::class));
-        });
-
-        $this->app->singleton(PromotionProfitLogic::class, function ($app) {
-            return new PromotionProfitLogic(
-                $app->make(ReferralLogic::class),
-                $app->make(TalentLogic::class)
-            );
-        });
-
-        $this->app->singleton(ReferralCodeLogic::class, function ($app) {
-            return new ReferralCodeLogic($app->make(ReferralLogic::class));
-        });
-    }
-
-    /**
-     * 启动服务
-     *
-     * @return void
-     */
-    public function boot()
-    {
-        // 注册事件和监听器
-        Event::listen(ReferralCreatedEvent::class, UpdatePromotionCountsListener::class);
-        Event::listen(ReferralCreatedEvent::class, UpdateTalentLevelListener::class);
-        Event::listen(ReferralUpdatedEvent::class, UpdatePromotionCountsListener::class);
-        Event::listen(ReferralUpdatedEvent::class, UpdateTalentLevelListener::class);
-        Event::listen(PromotionProfitCreatedEvent::class, DistributePromotionProfitListener::class);
-
-        // 注册命令
-        if ($this->app->runningInConsole()) {
-            $this->commands([
-                CleanExpiredReferralCodesCommand::class,
-                RebuildRelationCacheCommand::class,
-                UpdateTalentLevelsCommand::class,
-            ]);
-        }
-    }
-}

+ 0 - 156
app/Module/Promotion/README.md

@@ -1,156 +0,0 @@
-# 团队模块
-
-## 概述
-
-团队模块是开心农场系统的核心模块之一,负责管理用户之间的推荐关系、团队结构、达人等级和收益分成机制。该模块通过建立用户间的直推和间推关系,形成团队结构,并在团队成员产生收益时进行分成,鼓励用户发展团队,形成良性的社交生态。
-
-## 主要功能
-
-1. **推荐关系管理**:建立和维护用户间的直推和间推关系
-2. **达人等级系统**:根据团队规模和活跃度评定用户的达人等级
-3. **团队收益分成**:计算和分配团队成员产生的收益分成
-4. **团队数据统计**:统计和展示团队规模、收益等数据
-5. **推荐码生成**:生成用户专属推荐码和推荐链接
-
-## 目录结构
-
-```
-app/Module/Promotion/
-├── AdminControllers/        # 后台管理控制器
-├── Commands/                # 命令行工具
-├── Databases/               # 数据库相关文件
-│   └── createsql/          # 数据库创建SQL
-├── Docs/                    # 详细文档目录
-│   ├── README.md            # 文档索引
-│   ├── 设计概述.md           # 模块整体设计
-│   ├── 数据库设计.md         # 数据库表结构设计
-│   ├── 模块接口.md           # 模块对外接口
-│   └── 推荐关系系统.md        # 推荐关系系统设计
-├── Enums/                   # 枚举类型定义
-├── Events/                  # 事件类
-├── Logics/                  # 业务逻辑类
-├── Models/                  # 数据模型
-├── Providers/               # 服务提供者
-├── Repositorys/             # 数据仓库
-└── Services/                # 开放服务类
-```
-
-## 核心概念
-
-### 1. 推荐关系
-
-- **直推关系**:用户A直接推荐用户B注册,则用户A是用户B的直推上级
-- **间推关系**:用户A推荐用户B,用户B推荐用户C,则用户A是用户C的间推上级
-- **团队成员**:用户的所有直推和间推下级构成该用户的团队
-
-### 2. 达人等级
-
-团队系统设有达人等级,根据团队规模和活跃度评定:
-
-| 达人等级 | 名称 | 升级条件 | 奖励权益 |
-|---------|------|---------|---------|
-| 1 | 初级达人 | 直推5人且团队总人数≥10 | 团队收益1%分成 |
-| 2 | 中级达人 | 直推10人且团队总人数≥30 | 团队收益1.5%分成 |
-| 3 | 高级达人 | 直推20人且团队总人数≥50 | 团队收益2%分成 |
-| 4 | 资深达人 | 直推30人且团队总人数≥100 | 团队收益2.5%分成 |
-| 5 | 顶级达人 | 直推50人且团队总人数≥200 | 团队收益3%分成 |
-
-### 3. 收益分成
-
-- **直推分成**:直推上级获得下级收益的5%
-- **间推分成**:间推上级根据达人等级获得下级收益的1%-3%
-- **分成范围**:间推分成仅对20代以内的团队成员有效
-- **收益来源**:主要来自团队成员播种收获的农作物收益
-
-## 核心数据表
-
-### 1. 用户推荐关系表 (promotion_user_referrals)
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 用户ID |
-| referrer_id | bigint | 推荐人ID |
-| level | tinyint | 推荐层级(1=直推,2=间推) |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-### 2. 达人等级表 (promotion_user_talents)
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 用户ID |
-| talent_level | tinyint | 达人等级(0-5) |
-| direct_count | int | 直推人数 |
-| promotion_count | int | 团队总人数 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-### 3. 团队收益记录表 (promotion_profits)
-| 字段名 | 类型 | 说明 |
-|--------|------|------|
-| id | bigint | 主键ID |
-| user_id | bigint | 获得收益的用户ID |
-| promotion_member_id | bigint | 团队成员ID |
-| source_id | bigint | 收益来源ID |
-| source_type | varchar | 收益来源类型 |
-| profit_amount | int | 分成收益数量 |
-| profit_rate | decimal | 分成比例 |
-| created_at | timestamp | 创建时间 |
-
-## 核心服务
-
-### 1. 推荐关系服务 (ReferralService)
-- 建立推荐关系
-- 获取用户的推荐人
-- 获取用户的团队成员
-- 验证推荐关系
-
-### 2. 达人等级服务 (TalentService)
-- 计算和更新达人等级
-- 获取用户的达人信息
-- 获取达人等级权益
-
-### 3. 团队收益服务 (PromotionProfitService)
-- 计算团队收益分成
-- 记录收益分成
-- 统计团队收益
-
-### 4. 推荐码服务 (ReferralCodeService)
-- 生成推荐码
-- 验证推荐码
-- 生成推荐链接
-
-## 与其他模块的交互
-
-### 1. 与User模块的交互
-- 用户注册时接收推荐人ID
-- 验证推荐人ID的有效性
-- 建立推荐关系
-
-### 2. 与Farm模块的交互
-- 监听作物收获事件,计算农场收益分成
-- 提供达人等级信息,影响农场产出
-
-### 3. 与GameItems模块的交互
-- 将团队分成收益添加到用户物品库
-- 记录收益来源和分成比例
-
-### 4. 与Task模块的交互
-- 达人升级可触发任务完成
-- 发展团队成员可完成特定任务
-
-## 开发注意事项
-
-1. **数据一致性**:所有涉及多个操作的功能都应使用数据库事务
-2. **性能优化**:推荐关系查询和团队成员统计应考虑性能优化
-3. **扩展性考虑**:预留达人等级和分成比例的扩展空间
-4. **安全验证**:所有操作前验证用户权限和数据有效性
-5. **日志记录**:记录关键操作,便于问题排查和数据分析
-
-## 开发文档
-
-详细的开发文档请参考以下资源:
-- [设计概述](Docs/设计概述.md) - 模块的整体设计思路和架构
-- [数据库设计](Docs/数据库设计.md) - 详细的数据库表结构和关系设计
-- [模块接口](Docs/模块接口.md) - 模块对外提供的服务接口
-- [推荐关系系统](Docs/推荐关系系统.md) - 推荐关系系统的设计与实现

+ 0 - 189
app/Module/Promotion/Repositorys/BaseRepository.php

@@ -1,189 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use Illuminate\Database\Eloquent\Model;
-use Illuminate\Support\Facades\DB;
-
-/**
- * 基础仓库类
- *
- * 提供基本的数据访问和操作功能,所有具体的仓库类都继承自此类。
- * 该类主要用于后台管理控制器,提供数据的CRUD操作。
- */
-class BaseRepository
-{
-    /**
-     * 模型实例
-     *
-     * @var Model
-     */
-    protected $model;
-
-    /**
-     * 构造函数
-     *
-     * @param Model $model
-     */
-    public function __construct(Model $model)
-    {
-        $this->model = $model;
-    }
-
-    /**
-     * 获取所有记录
-     *
-     * @param array $columns 要获取的字段
-     * @return \Illuminate\Database\Eloquent\Collection
-     */
-    public function all(array $columns = ['*'])
-    {
-        return $this->model->all($columns);
-    }
-
-    /**
-     * 分页获取记录
-     *
-     * @param int $perPage 每页数量
-     * @param array $columns 要获取的字段
-     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
-     */
-    public function paginate(int $perPage = 15, array $columns = ['*'])
-    {
-        return $this->model->paginate($perPage, $columns);
-    }
-
-    /**
-     * 根据ID获取记录
-     *
-     * @param int $id 记录ID
-     * @param array $columns 要获取的字段
-     * @return Model|null
-     */
-    public function find(int $id, array $columns = ['*'])
-    {
-        return $this->model->find($id, $columns);
-    }
-
-    /**
-     * 根据条件获取第一条记录
-     *
-     * @param array $conditions 查询条件
-     * @param array $columns 要获取的字段
-     * @return Model|null
-     */
-    public function findBy(array $conditions, array $columns = ['*'])
-    {
-        $query = $this->model->query();
-
-        foreach ($conditions as $field => $value) {
-            $query->where($field, $value);
-        }
-
-        return $query->first($columns);
-    }
-
-    /**
-     * 根据条件获取多条记录
-     *
-     * @param array $conditions 查询条件
-     * @param array $columns 要获取的字段
-     * @return \Illuminate\Database\Eloquent\Collection
-     */
-    public function findAllBy(array $conditions, array $columns = ['*'])
-    {
-        $query = $this->model->query();
-
-        foreach ($conditions as $field => $value) {
-            $query->where($field, $value);
-        }
-
-        return $query->get($columns);
-    }
-
-    /**
-     * 创建记录
-     *
-     * @param array $data 记录数据
-     * @return Model
-     */
-    public function create(array $data)
-    {
-        return $this->model->create($data);
-    }
-
-    /**
-     * 更新记录
-     *
-     * @param int $id 记录ID
-     * @param array $data 记录数据
-     * @return bool
-     */
-    public function update(int $id, array $data)
-    {
-        $record = $this->find($id);
-
-        if (!$record) {
-            return false;
-        }
-
-        return $record->update($data);
-    }
-
-    /**
-     * 删除记录
-     *
-     * @param int $id 记录ID
-     * @return bool
-     */
-    public function delete(int $id)
-    {
-        $record = $this->find($id);
-
-        if (!$record) {
-            return false;
-        }
-
-        return $record->delete();
-    }
-
-    /**
-     * 批量删除记录
-     *
-     * @param array $ids 记录ID数组
-     * @return int 删除的记录数
-     */
-    public function deleteMultiple(array $ids)
-    {
-        return $this->model->whereIn('id', $ids)->delete();
-    }
-
-    /**
-     * 获取记录总数
-     *
-     * @param array $conditions 查询条件
-     * @return int
-     */
-    public function count(array $conditions = [])
-    {
-        $query = $this->model->query();
-
-        foreach ($conditions as $field => $value) {
-            $query->where($field, $value);
-        }
-
-        return $query->count();
-    }
-
-    /**
-     * 执行原生SQL查询
-     *
-     * @param string $query SQL查询语句
-     * @param array $bindings 绑定参数
-     * @return array
-     */
-    public function rawQuery(string $query, array $bindings = [])
-    {
-        return DB::select($query, $bindings);
-    }
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionInviteRewardRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionInviteReward;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 邀请奖励记录数据仓库类
- *
- * 提供邀请奖励记录数据的访问和操作功能。
- * 该类是邀请奖励记录模块与后台管理系统的桥梁,用于处理邀请奖励记录数据的CRUD操作。
- * 邀请奖励记录了用户邀请新用户获得的奖励,包括奖励类型、奖励数量、奖励状态等信息。
- */
-class PromotionInviteRewardRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionInviteReward::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionProfitRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionProfit;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 团队收益记录数据仓库类
- *
- * 提供团队收益记录数据的访问和操作功能。
- * 该类是团队收益记录模块与后台管理系统的桥梁,用于处理团队收益记录数据的CRUD操作。
- * 团队收益记录了用户获得的团队收益,包括收益来源、收益数量、分成比例等信息。
- */
-class PromotionProfitRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionProfit::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionProfitRuleRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionProfitRule;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 收益分成规则数据仓库类
- *
- * 提供收益分成规则数据的访问和操作功能。
- * 该类是收益分成规则模块与后台管理系统的桥梁,用于处理收益分成规则数据的CRUD操作。
- * 收益分成规则定义了不同来源类型的收益分成比例和规则。
- */
-class PromotionProfitRuleRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionProfitRule::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionReferralChangeRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionReferralChange;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 推荐关系修改记录数据仓库类
- *
- * 提供推荐关系修改记录数据的访问和操作功能。
- * 该类是推荐关系修改记录模块与后台管理系统的桥梁,用于处理推荐关系修改记录数据的CRUD操作。
- * 推荐关系修改记录了用户推荐关系的变更历史,包括旧推荐人、新推荐人、修改原因等信息。
- */
-class PromotionReferralChangeRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionReferralChange::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionReferralCodeRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionReferralCode;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 推荐码数据仓库类
- *
- * 提供推荐码数据的访问和操作功能。
- * 该类是推荐码模块与后台管理系统的桥梁,用于处理推荐码数据的CRUD操作。
- * 推荐码用于用户邀请新用户加入,建立推荐关系。
- */
-class PromotionReferralCodeRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionReferralCode::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionReferralCodeUsageRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionReferralCodeUsage;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 邀请码使用记录数据仓库类
- *
- * 提供邀请码使用记录数据的访问和操作功能。
- * 该类是邀请码使用记录模块与后台管理系统的桥梁,用于处理邀请码使用记录数据的CRUD操作。
- * 邀请码使用记录了用户使用邀请码的详细信息,包括使用时间、使用结果、IP地址等。
- */
-class PromotionReferralCodeUsageRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionReferralCodeUsage::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionTalentConfigRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionTalentConfig;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 达人等级配置数据仓库类
- *
- * 提供达人等级配置数据的访问和操作功能。
- * 该类是达人等级配置模块与后台管理系统的桥梁,用于处理达人等级配置数据的CRUD操作。
- * 达人等级配置定义了不同达人等级的要求和权益。
- */
-class PromotionTalentConfigRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionTalentConfig::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionUserReferralRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionUserReferral;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 用户推荐关系数据仓库类
- *
- * 提供用户推荐关系数据的访问和操作功能。
- * 该类是用户推荐关系模块与后台管理系统的桥梁,用于处理用户推荐关系数据的CRUD操作。
- * 用户推荐关系记录了用户之间的直接推荐关系,是构建团队结构的基础。
- */
-class PromotionUserReferralRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionUserReferral::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionUserRelationCacheRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionUserRelationCache;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 用户关系缓存数据仓库类
- *
- * 提供用户关系缓存数据的访问和操作功能。
- * 该类是用户关系缓存模块与后台管理系统的桥梁,用于处理用户关系缓存数据的CRUD操作。
- * 用户关系缓存记录了用户之间的间接推荐关系,用于快速查询用户的团队结构。
- */
-class PromotionUserRelationCacheRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionUserRelationCache::class;
-}

+ 0 - 18
app/Module/Promotion/Repositorys/PromotionUserTalentRepository.php

@@ -1,18 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Repositorys;
-
-use App\Module\Promotion\Models\PromotionUserTalent;
-use Dcat\Admin\Repositories\EloquentRepository;
-
-/**
- * 用户达人等级数据仓库类
- *
- * 提供用户达人等级数据的访问和操作功能。
- * 该类是用户达人等级模块与后台管理系统的桥梁,用于处理用户达人等级数据的CRUD操作。
- * 用户达人等级记录了用户的达人等级、直推人数和团队总人数等信息。
- */
-class PromotionUserTalentRepository extends EloquentRepository
-{
-    protected $eloquentClass = PromotionUserTalent::class;
-}

+ 0 - 219
app/Module/Promotion/Services/PromotionProfitService.php

@@ -1,219 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Services;
-
-use App\Module\Promotion\Enums\PROFIT_SOURCE_TYPE;
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Logics\TalentLogic;
-use App\Module\Promotion\Logics\PromotionProfitLogic;
-use Illuminate\Support\Facades\Log;
-
-/**
- * 团队收益服务类
- *
- * 对外提供团队收益相关的服务,包括记录收益、获取收益记录、
- * 统计收益等功能。该类对外提供服务,内部调用逻辑层实现。
- */
-class PromotionProfitService
-{
-
-    /**
-     * 记录农场收获收益
-     *
-     * @param int $userId 产生收益的用户ID
-     * @param int $sourceId 收益来源ID(如收获记录ID)
-     * @param int $itemId 物品ID
-     * @param int $amount 收益数量
-     * @return bool
-     */
-    public static function recordFarmHarvestProfit(int $userId, int $sourceId, int $itemId, int $amount): bool
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $promotionProfitLogic = new PromotionProfitLogic($referralLogic, $talentLogic);
-
-            return $promotionProfitLogic->calculateAndRecordProfit(
-                $userId,
-                PROFIT_SOURCE_TYPE::FARM_HARVEST,
-                $sourceId,
-                $itemId,
-                $amount
-            );
-        } catch (\Exception $e) {
-            Log::error("记录农场收获收益失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 记录任务完成收益
-     *
-     * @param int $userId 产生收益的用户ID
-     * @param int $sourceId 收益来源ID(如任务记录ID)
-     * @param int $itemId 物品ID
-     * @param int $amount 收益数量
-     * @return bool
-     */
-    public static function recordTaskCompleteProfit(int $userId, int $sourceId, int $itemId, int $amount): bool
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $promotionProfitLogic = new PromotionProfitLogic($referralLogic, $talentLogic);
-
-            return $promotionProfitLogic->calculateAndRecordProfit(
-                $userId,
-                PROFIT_SOURCE_TYPE::TASK_COMPLETE,
-                $sourceId,
-                $itemId,
-                $amount
-            );
-        } catch (\Exception $e) {
-            Log::error("记录任务完成收益失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 记录物品出售收益
-     *
-     * @param int $userId 产生收益的用户ID
-     * @param int $sourceId 收益来源ID(如出售记录ID)
-     * @param int $itemId 物品ID
-     * @param int $amount 收益数量
-     * @return bool
-     */
-    public static function recordItemSellProfit(int $userId, int $sourceId, int $itemId, int $amount): bool
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $promotionProfitLogic = new PromotionProfitLogic($referralLogic, $talentLogic);
-
-            return $promotionProfitLogic->calculateAndRecordProfit(
-                $userId,
-                PROFIT_SOURCE_TYPE::ITEM_SELL,
-                $sourceId,
-                $itemId,
-                $amount
-            );
-        } catch (\Exception $e) {
-            Log::error("记录物品出售收益失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 获取用户的收益记录
-     *
-     * @param int $userId 用户ID
-     * @param string|null $sourceType 收益来源类型
-     * @param int $page 页码
-     * @param int $pageSize 每页数量
-     * @return array
-     */
-    public static function getUserProfits(int $userId, ?string $sourceType = null, int $page = 1, int $pageSize = 20): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $promotionProfitLogic = new PromotionProfitLogic($referralLogic, $talentLogic);
-
-            return $promotionProfitLogic->getUserProfits($userId, $sourceType, $page, $pageSize);
-        } catch (\Exception $e) {
-            Log::error("获取用户收益记录失败: " . $e->getMessage());
-            return [
-                'total' => 0,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => 0,
-                'profits' => []
-            ];
-        }
-    }
-
-    /**
-     * 统计用户的收益
-     *
-     * @param int $userId 用户ID
-     * @param string|null $sourceType 收益来源类型
-     * @param int|null $itemId 物品ID
-     * @return array
-     */
-    public static function sumUserProfits(int $userId, ?string $sourceType = null, ?int $itemId = null): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $promotionProfitLogic = new PromotionProfitLogic($referralLogic, $talentLogic);
-
-            return $promotionProfitLogic->sumUserProfits($userId, $sourceType, $itemId);
-        } catch (\Exception $e) {
-            Log::error("统计用户收益失败: " . $e->getMessage());
-            return [
-                'direct_profit' => 0,
-                'indirect_profit' => 0,
-                'total_profit' => 0
-            ];
-        }
-    }
-
-    /**
-     * 获取收益分成规则
-     *
-     * @param string $sourceType 收益来源类型
-     * @return array|null
-     */
-    public static function getProfitRule(string $sourceType): ?array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $promotionProfitLogic = new PromotionProfitLogic($referralLogic, $talentLogic);
-
-            $rule = $promotionProfitLogic->getProfitRule($sourceType);
-
-            if (!$rule) {
-                return null;
-            }
-
-            return [
-                'source_type' => $rule->source_type,
-                'direct_profit_rate' => $rule->direct_profit_rate,
-                'max_indirect_level' => $rule->max_indirect_level,
-                'status' => $rule->status,
-                'rules' => is_array($rule->rules) ? $rule->rules : json_decode($rule->rules, true)
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取收益分成规则失败: " . $e->getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * 获取所有收益来源类型
-     *
-     * @return array
-     */
-    public static function getAllProfitSourceTypes(): array
-    {
-        return [
-            [
-                'type' => PROFIT_SOURCE_TYPE::FARM_HARVEST,
-                'name' => '农场收获',
-                'description' => '来自Farm模块的作物收获'
-            ],
-            [
-                'type' => PROFIT_SOURCE_TYPE::TASK_COMPLETE,
-                'name' => '任务完成',
-                'description' => '来自Task模块的任务奖励'
-            ],
-            [
-                'type' => PROFIT_SOURCE_TYPE::ITEM_SELL,
-                'name' => '物品出售',
-                'description' => '来自GameItems模块的物品出售'
-            ]
-        ];
-    }
-}

+ 0 - 258
app/Module/Promotion/Services/ReferralCodeService.php

@@ -1,258 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Services;
-
-use App\Module\Promotion\Logics\ReferralCodeLogic;
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Models\PromotionReferralCode;
-use App\Module\Promotion\Models\PromotionReferralCodeUsage;
-use Illuminate\Support\Facades\Log;
-
-/**
- * 推荐码服务类
- *
- * 对外提供推荐码相关的服务,包括生成推荐码、验证推荐码、
- * 使用推荐码等功能。该类对外提供服务,内部调用逻辑层实现。
- */
-class ReferralCodeService
-{
-
-    /**
-     * 获取或生成用户的推荐码
-     *
-     * @param int $userId 用户ID
-     * @param \DateTime|null $expireTime 过期时间
-     * @return array|null
-     */
-    public static function getUserReferralCode(int $userId, ?\DateTime $expireTime = null): ?array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $referralCodeLogic = new ReferralCodeLogic($referralLogic);
-
-            // 先尝试获取现有的推荐码
-            $code = $referralCodeLogic->getUserActiveCode($userId);
-
-            // 如果没有有效的推荐码,则生成一个新的
-            if (!$code) {
-                $codeStr = $referralCodeLogic->generateReferralCode($userId, $expireTime);
-
-                if (!$codeStr) {
-                    return null;
-                }
-
-                $code = $referralCodeLogic->getUserActiveCode($userId);
-            }
-
-            if (!$code) {
-                return null;
-            }
-
-            return [
-                'code' => $code->code,
-                'usage_count' => $code->usage_count,
-                'status' => $code->status,
-                'expire_time' => $code->expire_time,
-                'created_at' => $code->created_at,
-                'is_valid' => $code->isValid()
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取或生成用户推荐码失败: " . $e->getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * 验证推荐码
-     *
-     * @param string $code 推荐码
-     * @return array
-     */
-    public static function validateReferralCode(string $code): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $referralCodeLogic = new ReferralCodeLogic($referralLogic);
-
-            return $referralCodeLogic->validateReferralCode($code);
-        } catch (\Exception $e) {
-            Log::error("验证推荐码失败: " . $e->getMessage());
-            return [
-                'valid' => false,
-                'message' => '验证推荐码时发生错误',
-                'code' => null
-            ];
-        }
-    }
-
-    /**
-     * 使用推荐码
-     *
-     * @param string $code 推荐码
-     * @param int $userId 使用者ID
-     * @param string $ipAddress IP地址
-     * @param string $userAgent 用户代理
-     * @return array
-     */
-    public static function useReferralCode(string $code, int $userId, string $ipAddress, string $userAgent): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $referralCodeLogic = new ReferralCodeLogic($referralLogic);
-
-            return $referralCodeLogic->useReferralCode($code, $userId, $ipAddress, $userAgent);
-        } catch (\Exception $e) {
-            Log::error("使用推荐码失败: " . $e->getMessage());
-            return [
-                'success' => false,
-                'message' => '使用推荐码时发生错误'
-            ];
-        }
-    }
-
-    /**
-     * 禁用推荐码
-     *
-     * @param string $code 推荐码
-     * @return bool
-     */
-    public static function disableReferralCode(string $code): bool
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $referralCodeLogic = new ReferralCodeLogic($referralLogic);
-
-            return $referralCodeLogic->disableReferralCode($code);
-        } catch (\Exception $e) {
-            Log::error("禁用推荐码失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 获取推荐码使用记录
-     *
-     * @param string $code 推荐码
-     * @param int $page 页码
-     * @param int $pageSize 每页数量
-     * @return array
-     */
-    public static function getReferralCodeUsages(string $code, int $page = 1, int $pageSize = 20): array
-    {
-        try {
-            $query = PromotionReferralCodeUsage::where('code', $code);
-
-            $total = $query->count();
-
-            $usages = $query->orderBy('created_at', 'desc')
-                ->offset(($page - 1) * $pageSize)
-                ->limit($pageSize)
-                ->with(['user', 'codeOwner'])
-                ->get();
-
-            $result = [];
-            foreach ($usages as $usage) {
-                $result[] = [
-                    'id' => $usage->id,
-                    'code' => $usage->code,
-                    'code_owner_id' => $usage->code_owner_id,
-                    'code_owner_name' => $usage->codeOwner ? ($usage->codeOwner->username ?? '') : '',
-                    'user_id' => $usage->user_id,
-                    'user_name' => $usage->user ? ($usage->user->username ?? '') : '',
-                    'ip_address' => $usage->ip_address,
-                    'user_agent' => $usage->user_agent,
-                    'status' => $usage->status,
-                    'result' => $usage->result,
-                    'remark' => $usage->remark,
-                    'created_at' => $usage->created_at
-                ];
-            }
-
-            return [
-                'total' => $total,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => ceil($total / $pageSize),
-                'usages' => $result
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取推荐码使用记录失败: " . $e->getMessage());
-            return [
-                'total' => 0,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => 0,
-                'usages' => []
-            ];
-        }
-    }
-
-    /**
-     * 获取用户的所有推荐码
-     *
-     * @param int $userId 用户ID
-     * @param int $page 页码
-     * @param int $pageSize 每页数量
-     * @return array
-     */
-    public static function getUserAllReferralCodes(int $userId, int $page = 1, int $pageSize = 20): array
-    {
-        try {
-            $query = PromotionReferralCode::where('user_id', $userId);
-
-            $total = $query->count();
-
-            $codes = $query->orderBy('created_at', 'desc')
-                ->offset(($page - 1) * $pageSize)
-                ->limit($pageSize)
-                ->get();
-
-            $result = [];
-            foreach ($codes as $code) {
-                $result[] = [
-                    'code' => $code->code,
-                    'usage_count' => $code->usage_count,
-                    'status' => $code->status,
-                    'expire_time' => $code->expire_time,
-                    'created_at' => $code->created_at,
-                    'is_valid' => $code->isValid()
-                ];
-            }
-
-            return [
-                'total' => $total,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => ceil($total / $pageSize),
-                'codes' => $result
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取用户所有推荐码失败: " . $e->getMessage());
-            return [
-                'total' => 0,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => 0,
-                'codes' => []
-            ];
-        }
-    }
-
-    /**
-     * 清理过期的推荐码
-     *
-     * @return int 清理的数量
-     */
-    public static function cleanExpiredReferralCodes(): int
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $referralCodeLogic = new ReferralCodeLogic($referralLogic);
-
-            return $referralCodeLogic->cleanExpiredReferralCodes();
-        } catch (\Exception $e) {
-            Log::error("清理过期推荐码失败: " . $e->getMessage());
-            return 0;
-        }
-    }
-}

+ 0 - 263
app/Module/Promotion/Services/ReferralService.php

@@ -1,263 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Services;
-
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Logics\RelationCacheLogic;
-use App\Module\Promotion\Logics\TalentLogic;
-use App\Module\Promotion\Models\PromotionUserReferral;
-use Illuminate\Support\Facades\Log;
-
-/**
- * 推荐关系服务类
- *
- * 对外提供推荐关系相关的服务,包括获取推荐关系、设置推荐关系、
- * 查询团队成员等功能。该类对外提供服务,内部调用逻辑层实现。
- */
-class ReferralService
-{
-
-    /**
-     * 获取用户的直接推荐人
-     *
-     * @param int $userId 用户ID
-     * @return array|null 推荐人信息
-     */
-    public static function getUserReferrer(int $userId): ?array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $referrerId = $referralLogic->getDirectReferrerId($userId);
-
-            if (!$referrerId) {
-                return null;
-            }
-
-            // 获取推荐人信息
-            $user = app('db')->table('users')->where('id', $referrerId)->first();
-
-            if (!$user) {
-                return null;
-            }
-
-            return [
-                'user_id' => $user->id,
-                'username' => $user->username ?? '',
-                'nickname' => $user->nickname ?? '',
-                'avatar' => $user->avatar ?? '',
-                'created_at' => $user->created_at
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取用户推荐人失败: " . $e->getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * 获取用户的直接推荐列表
-     *
-     * @param int $userId 用户ID
-     * @param int $page 页码
-     * @param int $pageSize 每页数量
-     * @return array
-     */
-    public static function getUserDirectReferrals(int $userId, int $page = 1, int $pageSize = 20): array
-    {
-        try {
-            $query = PromotionUserReferral::where('referrer_id', $userId)
-                ->with('user');
-
-            $total = $query->count();
-
-            $referrals = $query->orderBy('created_at', 'desc')
-                ->offset(($page - 1) * $pageSize)
-                ->limit($pageSize)
-                ->get();
-
-            $result = [];
-            foreach ($referrals as $referral) {
-                if ($referral->user) {
-                    $result[] = [
-                        'user_id' => $referral->user->id,
-                        'username' => $referral->user->username ?? '',
-                        'nickname' => $referral->user->nickname ?? '',
-                        'avatar' => $referral->user->avatar ?? '',
-                        'created_at' => $referral->created_at
-                    ];
-                }
-            }
-
-            return [
-                'total' => $total,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => ceil($total / $pageSize),
-                'referrals' => $result
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取用户直接推荐列表失败: " . $e->getMessage());
-            return [
-                'total' => 0,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => 0,
-                'referrals' => []
-            ];
-        }
-    }
-
-    /**
-     * 获取用户的团队成员列表
-     *
-     * @param int $userId 用户ID
-     * @param int $page 页码
-     * @param int $pageSize 每页数量
-     * @param int $maxLevel 最大层级
-     * @return array
-     */
-    public static function getUserPromotionMembers(int $userId, int $page = 1, int $pageSize = 20, int $maxLevel = 20): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            return $referralLogic->getAllPromotionMembers($userId, $maxLevel, $page, $pageSize);
-        } catch (\Exception $e) {
-            Log::error("获取用户团队成员列表失败: " . $e->getMessage());
-            return [
-                'total' => 0,
-                'page' => $page,
-                'page_size' => $pageSize,
-                'total_pages' => 0,
-                'members' => []
-            ];
-        }
-    }
-
-    /**
-     * 设置用户的推荐人
-     *
-     * @param int $userId 用户ID
-     * @param int $referrerId 推荐人ID
-     * @param string $reason 设置原因
-     * @param int $operatorId 操作人ID
-     * @return array 包含设置结果和消息
-     */
-    public static function setUserReferrer(int $userId, int $referrerId, string $reason, int $operatorId): array
-    {
-        try {
-            // 验证用户和推荐人是否存在
-            $user = app('db')->table('users')->where('id', $userId)->first();
-            $referrer = app('db')->table('users')->where('id', $referrerId)->first();
-
-            if (!$user) {
-                return [
-                    'success' => false,
-                    'message' => '用户不存在'
-                ];
-            }
-
-            if (!$referrer) {
-                return [
-                    'success' => false,
-                    'message' => '推荐人不存在'
-                ];
-            }
-
-            // 检查是否自己推荐自己
-            if ($userId == $referrerId) {
-                return [
-                    'success' => false,
-                    'message' => '不能设置自己为推荐人'
-                ];
-            }
-
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-
-            // 检查是否形成循环推荐
-            if ($referralLogic->checkCircularReferral($userId, $referrerId)) {
-                return [
-                    'success' => false,
-                    'message' => '设置此推荐人会形成循环推荐关系'
-                ];
-            }
-
-            // 设置推荐关系
-            $result = $referralLogic->updateReferralRelation($userId, $referrerId, $reason, $operatorId);
-
-            if (!$result) {
-                return [
-                    'success' => false,
-                    'message' => '设置推荐人失败'
-                ];
-            }
-
-            // 更新团队统计和达人等级
-            $talentLogic->updatePromotionCounts($referrerId);
-            $talentLogic->checkAndUpdateTalentLevel($referrerId);
-
-            return [
-                'success' => true,
-                'message' => '设置推荐人成功'
-            ];
-        } catch (\Exception $e) {
-            Log::error("设置用户推荐人失败: " . $e->getMessage());
-            return [
-                'success' => false,
-                'message' => '设置推荐人时发生错误: ' . $e->getMessage()
-            ];
-        }
-    }
-
-    /**
-     * 获取用户的团队统计数据
-     *
-     * @param int $userId 用户ID
-     * @return array
-     */
-    public static function getUserPromotionStats(int $userId): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $talent = $talentLogic->getUserTalent($userId);
-
-            if (!$talent) {
-                return [
-                    'direct_count' => 0,
-                    'promotion_count' => 0,
-                    'talent_level' => 0
-                ];
-            }
-
-            return [
-                'direct_count' => $talent->direct_count,
-                'promotion_count' => $talent->promotion_count,
-                'talent_level' => $talent->talent_level
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取用户团队统计数据失败: " . $e->getMessage());
-            return [
-                'direct_count' => 0,
-                'promotion_count' => 0,
-                'talent_level' => 0
-            ];
-        }
-    }
-
-    /**
-     * 重建用户的关系缓存
-     *
-     * @param int $userId 用户ID
-     * @return bool
-     */
-    public static function rebuildUserRelationCache(int $userId): bool
-    {
-        try {
-            $relationCacheLogic = new RelationCacheLogic();
-            return $relationCacheLogic->generateUserRelationCache($userId);
-        } catch (\Exception $e) {
-            Log::error("重建用户关系缓存失败: " . $e->getMessage());
-            return false;
-        }
-    }
-}

+ 0 - 264
app/Module/Promotion/Services/TalentService.php

@@ -1,264 +0,0 @@
-<?php
-
-namespace App\Module\Promotion\Services;
-
-use App\Module\Promotion\Logics\ReferralLogic;
-use App\Module\Promotion\Logics\TalentLogic;
-use App\Module\Promotion\Models\PromotionUserTalent;
-use Illuminate\Support\Facades\Log;
-
-/**
- * 达人等级服务类
- *
- * 对外提供达人等级相关的服务,包括获取达人等级、获取达人权益、
- * 获取达人等级配置等功能。该类对外提供服务,内部调用逻辑层实现。
- */
-class TalentService
-{
-
-    /**
-     * 获取用户的达人等级信息
-     *
-     * @param int $userId 用户ID
-     * @return array|null
-     */
-    public static function getUserTalentInfo(int $userId): ?array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-
-            $talent = $talentLogic->getUserTalent($userId);
-
-            if (!$talent) {
-                return null;
-            }
-
-            $config = $talentLogic->getTalentConfig($talent->talent_level);
-
-            return [
-                'user_id' => $talent->user_id,
-                'talent_level' => $talent->talent_level,
-                'talent_name' => $config ? $config->name : '',
-                'direct_count' => $talent->direct_count,
-                'promotion_count' => $talent->promotion_count,
-                'icon' => $config ? $config->icon : '',
-                'icon_url' => $config ? $config->icon_url : '',
-                'benefits' => $config ? (is_array($config->benefits) ? $config->benefits : json_decode($config->benefits, true)) : [],
-                'profit_rate' => $config ? $config->profit_rate : 0.0,
-                'created_at' => $talent->created_at,
-                'updated_at' => $talent->updated_at
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取用户达人等级信息失败: " . $e->getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * 获取所有达人等级配置
-     *
-     * @return array
-     */
-    public static function getAllTalentConfigs(): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            $configs = $talentLogic->getAllTalentConfigs();
-
-            $result = [];
-            foreach ($configs as $config) {
-                $result[] = [
-                    'level' => $config->level,
-                    'name' => $config->name,
-                    'direct_count_required' => $config->direct_count_required,
-                    'promotion_count_required' => $config->promotion_count_required,
-                    'profit_rate' => $config->profit_rate,
-                    'benefits' => is_array($config->benefits) ? $config->benefits : json_decode($config->benefits, true),
-                    'icon' => $config->icon,
-                    'icon_url' => $config->icon_url
-                ];
-            }
-
-            return $result;
-        } catch (\Exception $e) {
-            Log::error("获取所有达人等级配置失败: " . $e->getMessage());
-            return [];
-        }
-    }
-
-    /**
-     * 获取达人等级权益
-     *
-     * @param int $level 等级
-     * @return array
-     */
-    public static function getTalentBenefits(int $level): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            return $talentLogic->getTalentBenefits($level);
-        } catch (\Exception $e) {
-            Log::error("获取达人等级权益失败: " . $e->getMessage());
-            return [];
-        }
-    }
-
-    /**
-     * 检查并更新用户的达人等级
-     *
-     * @param int $userId 用户ID
-     * @return bool
-     */
-    public static function checkAndUpdateUserTalentLevel(int $userId): bool
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-            return $talentLogic->checkAndUpdateTalentLevel($userId);
-        } catch (\Exception $e) {
-            Log::error("检查并更新用户达人等级失败: " . $e->getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 获取达人等级排行榜
-     *
-     * @param int $limit 限制数量
-     * @return array
-     */
-    public static function getTalentRanking(int $limit = 10): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-
-            $talents = PromotionUserTalent::where('talent_level', '>', 0)
-                ->orderBy('talent_level', 'desc')
-                ->orderBy('promotion_count', 'desc')
-                ->orderBy('direct_count', 'desc')
-                ->limit($limit)
-                ->with('user')
-                ->get();
-
-            $result = [];
-            foreach ($talents as $talent) {
-                if ($talent->user) {
-                    $config = $talentLogic->getTalentConfig($talent->talent_level);
-
-                    $result[] = [
-                        'user_id' => $talent->user_id,
-                        'username' => $talent->user->username ?? '',
-                        'nickname' => $talent->user->nickname ?? '',
-                        'avatar' => $talent->user->avatar ?? '',
-                        'talent_level' => $talent->talent_level,
-                        'talent_name' => $config ? $config->name : '',
-                        'direct_count' => $talent->direct_count,
-                        'promotion_count' => $talent->promotion_count,
-                        'icon' => $config ? $config->icon : '',
-                        'icon_url' => $config ? $config->icon_url : ''
-                    ];
-                }
-            }
-
-            return $result;
-        } catch (\Exception $e) {
-            Log::error("获取达人等级排行榜失败: " . $e->getMessage());
-            return [];
-        }
-    }
-
-    /**
-     * 获取用户的达人等级进度
-     *
-     * @param int $userId 用户ID
-     * @return array
-     */
-    public static function getUserTalentProgress(int $userId): array
-    {
-        try {
-            $referralLogic = new ReferralLogic();
-            $talentLogic = new TalentLogic($referralLogic);
-
-            $talent = $talentLogic->getUserTalent($userId);
-
-            if (!$talent) {
-                return [
-                    'current_level' => 0,
-                    'next_level' => 1,
-                    'direct_count' => 0,
-                    'direct_count_required' => 5,
-                    'direct_count_progress' => 0,
-                    'promotion_count' => 0,
-                    'promotion_count_required' => 10,
-                    'promotion_count_progress' => 0
-                ];
-            }
-
-            $configs = $talentLogic->getAllTalentConfigs();
-
-            // 找到下一个等级
-            $nextLevel = null;
-            $nextLevelConfig = null;
-
-            foreach ($configs as $config) {
-                if ($config->level > $talent->talent_level) {
-                    $nextLevel = $config->level;
-                    $nextLevelConfig = $config;
-                    break;
-                }
-            }
-
-            if (!$nextLevel) {
-                // 已经是最高等级
-                $currentConfig = $talentLogic->getTalentConfig($talent->talent_level);
-
-                return [
-                    'current_level' => $talent->talent_level,
-                    'next_level' => null,
-                    'direct_count' => $talent->direct_count,
-                    'direct_count_required' => $currentConfig ? $currentConfig->direct_count_required : 0,
-                    'direct_count_progress' => 100,
-                    'promotion_count' => $talent->promotion_count,
-                    'promotion_count_required' => $currentConfig ? $currentConfig->promotion_count_required : 0,
-                    'promotion_count_progress' => 100
-                ];
-            }
-
-            // 计算进度
-            $directCountProgress = $nextLevelConfig->direct_count_required > 0
-                ? min(100, ($talent->direct_count / $nextLevelConfig->direct_count_required) * 100)
-                : 0;
-
-            $promotionCountProgress = $nextLevelConfig->promotion_count_required > 0
-                ? min(100, ($talent->promotion_count / $nextLevelConfig->promotion_count_required) * 100)
-                : 0;
-
-            return [
-                'current_level' => $talent->talent_level,
-                'next_level' => $nextLevel,
-                'direct_count' => $talent->direct_count,
-                'direct_count_required' => $nextLevelConfig->direct_count_required,
-                'direct_count_progress' => $directCountProgress,
-                'promotion_count' => $talent->promotion_count,
-                'promotion_count_required' => $nextLevelConfig->promotion_count_required,
-                'promotion_count_progress' => $promotionCountProgress
-            ];
-        } catch (\Exception $e) {
-            Log::error("获取用户达人等级进度失败: " . $e->getMessage());
-            return [
-                'current_level' => 0,
-                'next_level' => 1,
-                'direct_count' => 0,
-                'direct_count_required' => 5,
-                'direct_count_progress' => 0,
-                'promotion_count' => 0,
-                'promotion_count_required' => 10,
-                'promotion_count_progress' => 0
-            ];
-        }
-    }
-}