ShopPromotion.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace App\Module\Shop\Models;
  3. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  4. use Illuminate\Database\Eloquent\Relations\HasMany;
  5. use UCore\ModelCore;
  6. /**
  7. * 商店促销活动模型
  8. *
  9. * field start
  10. * field end
  11. */
  12. class ShopPromotion extends ModelCore
  13. {
  14. /**
  15. * 与模型关联的表名
  16. *
  17. * @var string
  18. */
  19. protected $table = 'shop_promotions';
  20. /**
  21. * 可批量赋值的属性
  22. *
  23. * @var array
  24. */
  25. protected $fillable = [
  26. 'name',
  27. 'description',
  28. 'banner',
  29. 'discount_type',
  30. 'discount_value',
  31. 'is_active',
  32. 'sort_order',
  33. 'start_time',
  34. 'end_time',
  35. ];
  36. /**
  37. * 应该被转换为日期的属性
  38. *
  39. * @var array
  40. */
  41. protected $dates = [
  42. 'start_time',
  43. 'end_time',
  44. 'created_at',
  45. 'updated_at',
  46. ];
  47. /**
  48. * 应该被转换为原生类型的属性
  49. *
  50. * @var array
  51. */
  52. protected $casts = [
  53. 'is_active' => 'boolean',
  54. ];
  55. /**
  56. * 折扣类型:固定折扣
  57. */
  58. const DISCOUNT_TYPE_FIXED = 1;
  59. /**
  60. * 折扣类型:百分比折扣
  61. */
  62. const DISCOUNT_TYPE_PERCENTAGE = 2;
  63. /**
  64. * 获取折扣类型文本
  65. *
  66. * @return string
  67. */
  68. public function getDiscountTypeTextAttribute(): string
  69. {
  70. return match ($this->discount_type) {
  71. self::DISCOUNT_TYPE_FIXED => '固定折扣',
  72. self::DISCOUNT_TYPE_PERCENTAGE => '百分比折扣',
  73. default => '未知',
  74. };
  75. }
  76. /**
  77. * 获取该促销活动关联的商品
  78. *
  79. * @return BelongsToMany
  80. */
  81. public function items(): BelongsToMany
  82. {
  83. return $this->belongsToMany(
  84. ShopItem::class,
  85. 'shop_promotion_items',
  86. 'promotion_id',
  87. 'shop_item_id'
  88. )->withPivot('custom_discount_value')
  89. ->withTimestamps();
  90. }
  91. /**
  92. * 获取促销活动的商品关联记录
  93. *
  94. * @return HasMany
  95. */
  96. public function promotionItems(): HasMany
  97. {
  98. return $this->hasMany(ShopPromotionItem::class, 'promotion_id');
  99. }
  100. /**
  101. * 检查促销活动是否有效
  102. *
  103. * @return bool
  104. */
  105. public function isValid(): bool
  106. {
  107. if (!$this->is_active) {
  108. return false;
  109. }
  110. $now = now();
  111. if ($this->start_time && $now < $this->start_time) {
  112. return false;
  113. }
  114. if ($this->end_time && $now > $this->end_time) {
  115. return false;
  116. }
  117. return true;
  118. }
  119. /**
  120. * 计算折扣后的价格
  121. *
  122. * @param int $originalPrice 原价
  123. * @param int|null $customDiscountValue 自定义折扣值
  124. * @return int 折扣后的价格
  125. */
  126. public function calculateDiscountedPrice(int $originalPrice, ?int $customDiscountValue = null): int
  127. {
  128. $discountValue = $customDiscountValue ?? $this->discount_value;
  129. if ($this->discount_type === self::DISCOUNT_TYPE_FIXED) {
  130. return max(0, $originalPrice - $discountValue);
  131. } elseif ($this->discount_type === self::DISCOUNT_TYPE_PERCENTAGE) {
  132. return (int)($originalPrice * (100 - $discountValue) / 100);
  133. }
  134. return $originalPrice;
  135. }
  136. }