Payback.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Models;
  4. use Illuminate\Database\Query\Builder;
  5. use function time;
  6. /**
  7. * @property int $id 记录ID
  8. * @property float $total 总金额
  9. * @property int $userid 用户ID
  10. * @property int $ref_by 推荐人ID
  11. * @property float $ref_get 推荐人获得金额
  12. * @property int $datetime 创建时间
  13. *
  14. * @mixin Builder
  15. */
  16. final class Payback extends Model
  17. {
  18. protected $connection = 'default';
  19. protected $table = 'payback';
  20. public function user(): \Illuminate\Database\Eloquent\Model|User|null
  21. {
  22. return (new User())->where('id', $this->userid)->first();
  23. }
  24. public function getUserNameAttribute(): string
  25. {
  26. return (new User())->where('id', $this->userid)->first() === null ? '已注销' :
  27. (new User())->where('id', $this->userid)->first()->user_name;
  28. }
  29. public function refUser(): \Illuminate\Database\Eloquent\Model|User|null
  30. {
  31. return (new User())->where('id', $this->ref_by)->first();
  32. }
  33. public function getRefUserNameAttribute(): string
  34. {
  35. return (new User())->where('id', $this->ref_by)->first() === null ? '已注销' :
  36. (new User())->where('id', $this->ref_by)->first()->user_name;
  37. }
  38. public function rebate($user_id, $order_amount): void
  39. {
  40. $configs = Config::getClass('ref');
  41. $user = (new User())->where('id', $user_id)->first();
  42. $gift_user_id = $user->ref_by;
  43. // 判断
  44. $invite_rebate_mode = (string) $configs['invite_rebate_mode'];
  45. if ($invite_rebate_mode === 'continued') {
  46. // 不设限制
  47. $this->execute($user_id, $gift_user_id, $order_amount);
  48. } elseif ($invite_rebate_mode === 'limit_frequency') {
  49. // 限制返利次数
  50. $rebate_frequency = self::where('userid', $user_id)->count();
  51. if ($rebate_frequency < $configs['rebate_frequency_limit']) {
  52. $this->execute($user_id, $gift_user_id, $order_amount);
  53. }
  54. } elseif ($invite_rebate_mode === 'limit_amount') {
  55. // 限制返利金额
  56. $total_rebate_amount = self::where('userid', $user_id)->sum('ref_get');
  57. // 预计返利 (expected_rebate) 是指:订单金额 * 返点比例
  58. $expected_rebate = $order_amount * $configs['rebate_ratio'];
  59. // 调整返利 (adjust_rebate) 是指:若历史返利总额在加上此次预计返利金额超过总返利限制,总返利限制与历史返利总额的差值
  60. if ($total_rebate_amount + $expected_rebate > $configs['rebate_amount_limit']
  61. && $total_rebate_amount <= $configs['rebate_amount_limit']
  62. ) {
  63. $adjust_rebate = $configs['rebate_amount_limit'] - $total_rebate_amount;
  64. if ($adjust_rebate > 0) {
  65. $this->execute($user_id, $gift_user_id, $order_amount, $adjust_rebate);
  66. }
  67. } else {
  68. $this->execute($user_id, $gift_user_id, $order_amount);
  69. }
  70. } elseif ($invite_rebate_mode === 'limit_time_range') {
  71. if (strtotime($user->reg_date) + $configs['rebate_time_range_limit'] * 86400 > time()) {
  72. $this->execute($user_id, $gift_user_id, $order_amount);
  73. }
  74. }
  75. }
  76. public function execute($user_id, $gift_user_id, $order_amount, $adjust_rebate = null): void
  77. {
  78. $gift_user = (new User())->where('id', $gift_user_id)
  79. ->where('is_banned', 0)
  80. ->where('is_shadow_banned', 0)
  81. ->first();
  82. if ($gift_user !== null) {
  83. $rebate_amount = $order_amount * Config::obtain('rebate_ratio');
  84. // 返利
  85. $money_before = $gift_user->money;
  86. $gift_user->money += $adjust_rebate ?? $rebate_amount;
  87. $gift_user->save();
  88. // 余额变动记录
  89. (new UserMoneyLog())->add(
  90. $gift_user->id,
  91. (float) $money_before,
  92. (float) $gift_user->money,
  93. $adjust_rebate ?? $rebate_amount,
  94. '邀请用户 #' . $user_id . ' 返利',
  95. );
  96. // 添加记录
  97. $this->total = $order_amount;
  98. $this->userid = $user_id;
  99. $this->ref_by = $gift_user_id;
  100. $this->ref_get = $adjust_rebate ?? $rebate_amount;
  101. $this->datetime = time();
  102. $this->save();
  103. }
  104. }
  105. }