OrderService.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. namespace App\Services;
  3. use App\Components\Helpers;
  4. use App\Models\Order;
  5. use App\Models\ReferralLog;
  6. use App\Models\User;
  7. use Log;
  8. class OrderService
  9. {
  10. public static $order;
  11. public static $user;
  12. public static $goods;
  13. public static $payment;
  14. public function __construct(Order $order)
  15. {
  16. // 获取需要的信息
  17. self::$order = $order;
  18. self::$user = $order->user;
  19. self::$goods = $order->goods;
  20. self::$payment = $order->payment;
  21. }
  22. // 支付成功后处理
  23. public function receivedPayment(): bool
  24. {
  25. if (self::$payment) {// 是否为余额购买套餐
  26. if (self::$payment->status === 1) {// 已处理
  27. return true;
  28. }
  29. self::$payment->update(['status' => 1]);
  30. // 余额充值
  31. if (self::$order->goods_id === 0 || self::$order->goods_id === null) {
  32. return $this->chargeCredit();
  33. }
  34. }
  35. $goods = self::$order->goods;
  36. switch ($goods->type) {// 商品为流量或者套餐
  37. case 1:// 流量包
  38. $this->activatePackage();
  39. break;
  40. case 2:// 套餐
  41. if (Order::userActivePlan(self::$user->id)->where('id', '<>', self::$order->id)->exists()) {// 判断套餐是否直接激活
  42. $this->setPrepaidPlan();
  43. } else {
  44. $this->activatePlan();
  45. }
  46. $this->setCommissionExpense(self::$user); // 返利
  47. break;
  48. default:
  49. Log::warning('【处理订单】出现错误-未知套餐类型');
  50. }
  51. return true;
  52. }
  53. // 余额充值
  54. private function chargeCredit(): bool
  55. {
  56. $credit = self::$user->credit;
  57. $ret = (new UserService(self::$user))->updateCredit(self::$order->origin_amount);
  58. // 余额变动记录日志
  59. if ($ret) {
  60. Helpers::addUserCreditLog(
  61. self::$order->user_id,
  62. self::$order->id,
  63. $credit,
  64. self::$user->credit,
  65. self::$order->amount,
  66. '用户通过'.self::$order->pay_way.'充值余额'
  67. );
  68. }
  69. return $ret;
  70. }
  71. // 激活流量包
  72. private function activatePackage(): bool
  73. {
  74. $ret = (new UserService(self::$user))->incrementData(self::$goods->traffic * MB);
  75. if ($ret) {
  76. return Helpers::addUserTrafficModifyLog(
  77. self::$order->user_id,
  78. self::$order->id,
  79. self::$user->transfer_enable - self::$goods->traffic * MB,
  80. self::$user->transfer_enable,
  81. '['.self::$order->pay_way.']加上用户购买的套餐流量'
  82. );
  83. }
  84. return false;
  85. }
  86. // 设置预支付套餐
  87. private function setPrepaidPlan(): bool
  88. {
  89. self::$order->status = 3; // 3为预支付
  90. // 预支付订单, 刷新账号有效时间用于流量重置判断
  91. return self::$order->save()
  92. && self::$user->update(['expired_at' => date('Y-m-d', strtotime(self::$user->expired_at.' +'.self::$goods->days.' days'))]);
  93. }
  94. // 激活套餐
  95. private function activatePlan(): bool
  96. {
  97. Order::whereId(self::$order->id)->update(['expired_at' => date('Y-m-d H:i:s', strtotime('+'.self::$goods->days.' days'))]);
  98. $oldData = self::$user->transfer_enable;
  99. $updateData = [
  100. 'invite_num' => self::$user->invite_num + (self::$goods->invite_num ?: 0),
  101. 'level' => self::$goods->level,
  102. 'enable' => 1,
  103. ];
  104. // 无端口用户 添加端口
  105. if (self::$user->port === null || self::$user->port === 0) {
  106. $updateData['port'] = Helpers::getPort();
  107. }
  108. $ret = self::$user->update(array_merge($this->resetTimeAndData(), $updateData));
  109. if ($ret) {
  110. return Helpers::addUserTrafficModifyLog(
  111. self::$order->user_id,
  112. self::$order->id,
  113. $oldData,
  114. self::$user->transfer_enable,
  115. '【'.self::$order->pay_way.'】加上用户购买的套餐流量'
  116. );
  117. }
  118. return false;
  119. }
  120. // 计算下次重置与账号过期时间
  121. public function resetTimeAndData($expired_at = null): array
  122. {
  123. $data = ['u' => 0, 'd' => 0];
  124. // 账号有效期
  125. if (! $expired_at) {
  126. $expired_at = date('Y-m-d', strtotime('+'.self::$goods->days.' days'));
  127. foreach (Order::userPrepay(self::$order->user_id)->get() as $paidOrder) {//拿出可能存在的其余套餐, 推算最新的到期时间
  128. //取出对应套餐信息
  129. $expired_at = date('Y-m-d', strtotime("$expired_at +".$paidOrder->goods->days.' days'));
  130. }
  131. $data['expired_at'] = $expired_at;
  132. }
  133. //账号流量重置日期
  134. $nextResetTime = date('Y-m-d', strtotime('+'.self::$goods->period.' days'));
  135. if ($nextResetTime >= $expired_at) {
  136. $nextResetTime = null;
  137. }
  138. return array_merge($data, [
  139. 'transfer_enable' => self::$goods->traffic * MB,
  140. 'reset_time' => $nextResetTime,
  141. ]);
  142. }
  143. // 佣金计算
  144. private function setCommissionExpense(User $user): bool
  145. {
  146. $referralType = sysConfig('referral_type');
  147. if ($referralType && $user->inviter_id) {// 是否需要支付佣金
  148. $inviter = $user->inviter;
  149. // 获取历史返利记录
  150. $referral = ReferralLog::whereInviteeId(self::$order->user_id)->doesntExist();
  151. // 无记录 / 首次返利
  152. if ($referral && sysConfig('is_invite_register')) {
  153. // 邀请注册功能开启时,返还邀请者邀请名额
  154. $inviter->update(['invite_num' => $inviter->invite_num + 1]);
  155. }
  156. // 按照返利模式进行返利判断
  157. if ($referralType == 2 || $referral) {
  158. return $this->addReferralLog(
  159. $user->id,
  160. $inviter->id,
  161. self::$order->id,
  162. self::$order->amount,
  163. self::$order->amount * sysConfig('referral_percent')
  164. );
  165. }
  166. }
  167. return true;
  168. }
  169. /**
  170. * 添加返利日志.
  171. *
  172. * @param int $inviteeId 用户ID
  173. * @param int $inviterId 返利对象ID
  174. * @param int $oid 订单ID
  175. * @param int $amount 发生金额
  176. * @param int $commission 返利金额
  177. *
  178. * @return bool
  179. */
  180. private function addReferralLog(int $inviteeId, int $inviterId, int $oid, int $amount, int $commission): bool
  181. {
  182. $log = new ReferralLog();
  183. $log->invitee_id = $inviteeId;
  184. $log->inviter_id = $inviterId;
  185. $log->order_id = $oid;
  186. $log->amount = $amount;
  187. $log->commission = $commission;
  188. $log->status = 0;
  189. return $log->save();
  190. }
  191. // 激活预支付套餐
  192. public function activatePrepaidPlan(): bool
  193. {
  194. self::$order->update([
  195. 'expired_at' => date('Y-m-d H:i:s', strtotime('+'.self::$goods->days.' days')),
  196. 'status' => 2,
  197. ]);
  198. return $this->activatePlan();
  199. }
  200. }