Order.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. namespace App\Models;
  3. use App\Casts\money;
  4. use App\Observers\OrderObserver;
  5. use App\Utils\Helpers;
  6. use App\Utils\Payments\PaymentManager;
  7. use Auth;
  8. use Illuminate\Database\Eloquent\Attributes\ObservedBy;
  9. use Illuminate\Database\Eloquent\Builder;
  10. use Illuminate\Database\Eloquent\Model;
  11. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  12. use Illuminate\Database\Eloquent\Relations\HasOne;
  13. use Kyslik\ColumnSortable\Sortable;
  14. /**
  15. * 订单.
  16. */
  17. #[ObservedBy([OrderObserver::class])]
  18. class Order extends Model
  19. {
  20. use Sortable;
  21. public array $sortable = ['id', 'sn', 'expired_at', 'created_at'];
  22. protected $table = 'order';
  23. protected $guarded = [];
  24. protected $casts = ['origin_amount' => money::class, 'amount' => money::class, 'expired_at' => 'datetime'];
  25. public function user(): BelongsTo
  26. {
  27. return $this->belongsTo(User::class);
  28. }
  29. public function goods(): BelongsTo
  30. {
  31. return $this->belongsTo(Goods::class)->withTrashed();
  32. }
  33. public function coupon(): BelongsTo
  34. {
  35. return $this->belongsTo(Coupon::class)->withTrashed();
  36. }
  37. public function payment(): HasOne
  38. {
  39. return $this->hasOne(Payment::class);
  40. }
  41. public function scopeUid(Builder $query, ?int $uid = null): Builder
  42. {
  43. return $query->whereUserId($uid ?? Auth::id());
  44. }
  45. public function scopeRecentUnPay(Builder $query): Builder
  46. {
  47. return $query->whereStatus(0)->where('created_at', '<=', date('Y-m-d H:i:s', strtotime(sysConfig('tasks_close.orders'))));
  48. }
  49. public function scopeUserPrepay(Builder $query, ?int $uid = null): Builder
  50. {
  51. return $query->uid($uid)->whereStatus(3)->oldest();
  52. }
  53. public function scopeActive(Builder $query): Builder
  54. {
  55. return $query->whereIsExpire(0)->whereStatus(2);
  56. }
  57. public function scopeActivePlan(Builder $query): Builder
  58. {
  59. return $query->active()->isPlan();
  60. }
  61. public function scopeIsPlan(Builder $query): Builder
  62. {
  63. return $query->with('goods')->whereHas('goods', function ($query) {
  64. $query->whereType(2);
  65. });
  66. }
  67. public function scopeActivePackage(Builder $query): Builder
  68. {
  69. return $query->active()->with('goods')->whereHas('goods', static function ($query) {
  70. $query->whereType(1);
  71. });
  72. }
  73. public function scopeUserActivePlan(Builder $query, ?int $uid = null): Builder
  74. {
  75. return $query->uid($uid)->activePlan();
  76. }
  77. public function scopeUserActivePackage(Builder $query, ?int $uid = null): Builder
  78. {
  79. return $query->uid($uid)->activePackage();
  80. }
  81. public function close(): bool
  82. { // 关闭订单
  83. return $this->update(['status' => -1]);
  84. }
  85. public function paid(): bool
  86. { // 支付需要确认的订单
  87. return $this->update(['status' => 1]);
  88. }
  89. public function complete(): bool
  90. { // 完成订单
  91. return $this->update(['status' => 2]);
  92. }
  93. public function prepay(): bool
  94. { // 预支付订单
  95. return $this->update(['status' => 3]);
  96. }
  97. public function expired(): bool
  98. { // 预支付订单
  99. return $this->update(['is_expire' => 1]);
  100. }
  101. public function getStatusLabelAttribute(): string
  102. { // 订单状态
  103. return $this->statusTags($this->status, $this->is_expire);
  104. }
  105. public function statusTags(int $status, bool $expire, bool $isHtml = true): string
  106. {
  107. switch ($status) {
  108. case -1:
  109. $label = trans('common.order.status.canceled');
  110. break;
  111. case 0:
  112. $tag = 1;
  113. $label = trans('common.status.payment_pending');
  114. break;
  115. case 1:
  116. $tag = 2;
  117. $label = trans('common.order.status.review');
  118. break;
  119. case 2:
  120. if ($this->goods_id === null) {
  121. $label = trans('common.order.status.completed');
  122. } elseif ($expire) {
  123. $label = trans('common.status.expire');
  124. } else {
  125. $tag = 3;
  126. $label = trans('common.order.status.ongoing');
  127. }
  128. break;
  129. case 3:
  130. $tag = 2;
  131. $label = trans('common.order.status.prepaid');
  132. break;
  133. default:
  134. $tag = 4;
  135. $label = trans('common.status.unknown');
  136. }
  137. if ($isHtml) {
  138. $label = '<span class="badge badge-'.['default', 'danger', 'info', 'success', 'warning'][$tag ?? 0].'">'.$label.'</span>';
  139. }
  140. return $label;
  141. }
  142. public function getOriginAmountTagAttribute(): string
  143. {
  144. return Helpers::getPriceTag($this->origin_amount);
  145. }
  146. public function getAmountTagAttribute(): string
  147. {
  148. return Helpers::getPriceTag($this->amount);
  149. }
  150. // 支付渠道
  151. public function getPayTypeLabelAttribute(): string
  152. {
  153. return match ($this->pay_type) {
  154. 0 => trans('common.payment.credit'),
  155. 1 => trans('common.payment.alipay'),
  156. 2 => trans('common.payment.qq'),
  157. 3 => trans('common.payment.wechat'),
  158. 4 => trans('common.payment.crypto'),
  159. 5 => trans('admin.system.payment.channel.paypal'),
  160. 6 => trans('admin.system.payment.channel.stripe'),
  161. 7 => trans('common.payment.manual'),
  162. default => '',
  163. };
  164. }
  165. // 支付图标
  166. public function getPayTypeIconAttribute(): string
  167. {
  168. return '/assets/images/payment/'.config('common.payment.icon')[$this->pay_type] ?? 'coin.png';
  169. }
  170. // 支付方式
  171. public function getPayWayLabelAttribute(): string
  172. {
  173. return PaymentManager::getLabels('true')[$this->pay_way] ?? trans('common.status.unknown');
  174. }
  175. }