UrsPartnerDividendCommand.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace App\Module\UrsPromotion\Commands;
  3. use App\Module\UrsPromotion\Services\UrsPartnerDividendService;
  4. use Illuminate\Console\Command;
  5. use Carbon\Carbon;
  6. /**
  7. * URS合伙人分红命令
  8. *
  9. * 用于执行每日合伙人分红任务
  10. * php artisan urs-promotion:partner-dividend
  11. */
  12. class UrsPartnerDividendCommand extends Command
  13. {
  14. /**
  15. * 命令签名
  16. */
  17. protected $signature = 'urs-promotion:partner-dividend
  18. {--date= : 指定分红日期,格式:Y-m-d,默认为昨天}
  19. {--force : 强制执行,即使已经分红过}
  20. {--retry : 重试失败的分红}';
  21. /**
  22. * 命令描述
  23. */
  24. protected $description = 'URS合伙人分红 - 顶级达人享受手续费分红';
  25. /**
  26. * 执行命令
  27. */
  28. public function handle(): int
  29. {
  30. $this->info('=== URS合伙人分红任务开始 ===');
  31. // 获取分红日期,默认为昨天
  32. $date = $this->option('date') ?: Carbon::yesterday()->format('Y-m-d');
  33. $force = $this->option('force');
  34. $retry = $this->option('retry');
  35. $this->info("分红日期: {$date}");
  36. // 验证日期格式
  37. if (!$this->validateDate($date)) {
  38. $this->error('日期格式错误,请使用 Y-m-d 格式,例如:2025-06-25');
  39. return self::FAILURE;
  40. }
  41. // 如果是重试模式
  42. if ($retry) {
  43. $this->info('重试失败的分红...');
  44. $result = UrsPartnerDividendService::retryFailedDividend($date);
  45. if ($result['success']) {
  46. $this->info('✅ 重试执行成功!');
  47. $this->displayRetryResult($result['data']);
  48. } else {
  49. $this->error('❌ 重试执行失败:' . $result['message']);
  50. return self::FAILURE;
  51. }
  52. return self::SUCCESS;
  53. }
  54. // 如果不是强制执行,检查是否已经分红
  55. if (!$force) {
  56. if (\App\Module\UrsPromotion\Models\UrsPartnerDividendRecord::isDividendProcessed($date)) {
  57. $this->warn("日期 {$date} 的分红已经处理过了,如需重新执行请使用 --force 参数");
  58. return self::SUCCESS;
  59. }
  60. }
  61. // 显示合伙人信息
  62. $this->showPartnerInfo();
  63. // 执行分红
  64. $this->info('开始执行分红...');
  65. $result = UrsPartnerDividendService::executeDailyDividend($date);
  66. if ($result['success']) {
  67. $this->info('✅ 分红执行成功!');
  68. $this->displayResult($result['data']);
  69. } else {
  70. $this->error('❌ 分红执行失败:' . $result['message']);
  71. return self::FAILURE;
  72. }
  73. $this->info('=== URS合伙人分红任务完成 ===');
  74. return self::SUCCESS;
  75. }
  76. /**
  77. * 验证日期格式
  78. */
  79. private function validateDate(string $date): bool
  80. {
  81. try {
  82. Carbon::createFromFormat('Y-m-d', $date);
  83. return true;
  84. } catch (\Exception $e) {
  85. return false;
  86. }
  87. }
  88. /**
  89. * 显示合伙人信息
  90. */
  91. private function showPartnerInfo(): void
  92. {
  93. $this->info('获取合伙人信息...');
  94. $partnerResult = UrsPartnerDividendService::getPartnerList();
  95. if ($partnerResult['success']) {
  96. $partners = $partnerResult['data'];
  97. $this->info("当前合伙人数量: {$partnerResult['total']}");
  98. if (!empty($partners)) {
  99. $this->table(
  100. ['用户ID', 'URS用户ID', '用户名', '达人等级', '成为合伙人时间'],
  101. array_map(function ($partner) {
  102. return [
  103. $partner['user_id'],
  104. $partner['urs_user_id'],
  105. $partner['username'],
  106. $partner['talent_level_name'],
  107. $partner['created_at']
  108. ];
  109. }, array_slice($partners, 0, 10)) // 只显示前10个
  110. );
  111. if (count($partners) > 10) {
  112. $this->info("... 还有 " . (count($partners) - 10) . " 个合伙人");
  113. }
  114. }
  115. } else {
  116. $this->warn('获取合伙人信息失败: ' . $partnerResult['message']);
  117. }
  118. }
  119. /**
  120. * 显示分红结果
  121. */
  122. private function displayResult(array $data): void
  123. {
  124. $this->info('');
  125. $this->info('📊 分红结果统计:');
  126. $this->info("分红日期: {$data['date']}");
  127. $this->info("当日总手续费: {$data['total_fee_amount']} 钻石");
  128. $this->info("分红总金额: {$data['dividend_amount']} 钻石 (20%)");
  129. $this->info("合伙人数量: {$data['partner_count']} 人");
  130. $this->info("每人分红: {$data['per_partner_amount']} 钻石");
  131. $this->info("成功转账: {$data['success_count']} 人");
  132. if ($data['failed_count'] > 0) {
  133. $this->warn("失败转账: {$data['failed_count']} 人");
  134. }
  135. // 计算成功率
  136. $successRate = $data['partner_count'] > 0 ?
  137. round($data['success_count'] / $data['partner_count'] * 100, 2) : 0;
  138. $this->info("成功率: {$successRate}%");
  139. }
  140. /**
  141. * 显示重试结果
  142. */
  143. private function displayRetryResult(array $data): void
  144. {
  145. $this->info('');
  146. $this->info('🔄 重试结果统计:');
  147. $this->info("重试数量: {$data['retry_count']} 个");
  148. $this->info("成功转账: {$data['success_count']} 个");
  149. if ($data['failed_count'] > 0) {
  150. $this->warn("仍然失败: {$data['failed_count']} 个");
  151. }
  152. // 计算重试成功率
  153. $retrySuccessRate = $data['retry_count'] > 0 ?
  154. round($data['success_count'] / $data['retry_count'] * 100, 2) : 0;
  155. $this->info("重试成功率: {$retrySuccessRate}%");
  156. }
  157. }