RewardActiveRule.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace Longyi\RewardPoints\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Webkul\Customer\Models\Customer;
  5. class RewardActiveRule extends Model
  6. {
  7. // 定义交易类型常量
  8. const TYPE_SIGN_IN = 1;
  9. const TYPE_REGISTRATION = 2;
  10. const TYPE_ORDER = 3;
  11. const TYPE_REVIEW = 4;
  12. const TYPE_REFERRAL = 5;
  13. const TYPE_BIRTHDAY = 6;
  14. const TYPE_SHARE = 7;
  15. const TYPE_SUBSCRIBE = 8;
  16. const TYPE_LOGIN = 9;
  17. protected $table = 'mw_reward_active_rules';
  18. protected $primaryKey = 'rule_id';
  19. public $timestamps = false;
  20. protected $fillable = [
  21. 'rule_name', 'type_of_transaction', 'store_view', 'customer_group_ids',
  22. 'enable_different_points_by_group', 'default_expired', 'expired_day',
  23. 'date_event', 'comment', 'coupon_code', 'reward_point', 'status',
  24. 'group_points' // 添加群组积分配置字段
  25. ];
  26. protected $casts = [
  27. 'type_of_transaction' => 'integer',
  28. 'status' => 'boolean',
  29. 'expired_day' => 'integer',
  30. 'enable_different_points_by_group' => 'boolean',
  31. 'group_points' => 'array', // 自动 JSON 转换
  32. ];
  33. /**
  34. * 获取客户群组积分配置
  35. * 假设数据库中 group_points 字段存储 JSON,格式:{"1": 100, "2": 150}
  36. */
  37. public function getCustomerGroupPointsAttribute(): array
  38. {
  39. // 如果使用 group_points 字段(推荐)
  40. if (isset($this->attributes['group_points'])) {
  41. $value = $this->attributes['group_points'];
  42. if (is_string($value)) {
  43. return json_decode($value, true) ?: [];
  44. }
  45. return is_array($value) ? $value : [];
  46. }
  47. // 兼容其他可能的字段名
  48. if (isset($this->attributes['customer_group_points'])) {
  49. $value = $this->attributes['customer_group_points'];
  50. if (is_string($value)) {
  51. return json_decode($value, true) ?: [];
  52. }
  53. return is_array($value) ? $value : [];
  54. }
  55. return [];
  56. }
  57. /**
  58. * 【核心方法】统一获取客户应得的积分值
  59. * 整合了所有积分获取逻辑,避免重复代码
  60. */
  61. public function getPointsForCustomer($customer): int
  62. {
  63. // 获取客户群组ID
  64. $customerGroupId = $this->extractCustomerGroupId($customer);
  65. // 如果无法获取群组ID,返回0(注册、订阅等场景应该单独处理)
  66. if ($customerGroupId === null) {
  67. return 0;
  68. }
  69. // 启用群组差异化:从配置中获取该群组的积分
  70. if ($this->enable_different_points_by_group) {
  71. $groupPoints = $this->getCustomerGroupPointsAttribute();
  72. return (int)($groupPoints[$customerGroupId] ?? 0);
  73. }
  74. // 不启用差异化:检查群组是否在允许列表中
  75. if ($this->isGroupAllowed($customerGroupId)) {
  76. return (int)$this->reward_point;
  77. }
  78. return 0;
  79. }
  80. /**
  81. * 获取特定客户群组的积分值(保留向后兼容)
  82. */
  83. public function getRewardPointForCustomerGroup($customerGroupId): int
  84. {
  85. if ($this->enable_different_points_by_group) {
  86. $groupPoints = $this->getCustomerGroupPointsAttribute();
  87. return (int)($groupPoints[$customerGroupId] ?? 0);
  88. }
  89. if ($this->isGroupAllowed($customerGroupId)) {
  90. return (int)$this->reward_point;
  91. }
  92. return 0;
  93. }
  94. /**
  95. * 检查规则是否适用于指定客户
  96. */
  97. public function isApplicableToCustomer($customer): bool
  98. {
  99. // 检查 store_view
  100. if (!$this->isStoreViewMatched()) {
  101. return false;
  102. }
  103. $customerGroupId = $this->extractCustomerGroupId($customer);
  104. if ($customerGroupId === null) {
  105. return false;
  106. }
  107. // 启用群组差异化:检查是否有为该群组配置积分
  108. if ($this->enable_different_points_by_group) {
  109. $groupPoints = $this->getCustomerGroupPointsAttribute();
  110. return !empty($groupPoints) && isset($groupPoints[$customerGroupId]);
  111. }
  112. // 不启用差异化:检查群组是否在允许列表中
  113. return $this->isGroupAllowed($customerGroupId);
  114. }
  115. /**
  116. * 检查 store_view 是否匹配
  117. */
  118. protected function isStoreViewMatched(): bool
  119. {
  120. if (empty($this->store_view) || $this->store_view === '0') {
  121. return true;
  122. }
  123. $storeViews = explode(',', $this->store_view);
  124. $currentChannelCode = core()->getCurrentChannelCode();
  125. return in_array($currentChannelCode, $storeViews);
  126. }
  127. /**
  128. * 检查群组是否允许
  129. */
  130. protected function isGroupAllowed($customerGroupId): bool
  131. {
  132. if (empty($this->customer_group_ids) || trim($this->customer_group_ids) === '') {
  133. return true;
  134. }
  135. $allowedGroups = array_map('trim', explode(',', $this->customer_group_ids));
  136. return in_array((string)$customerGroupId, $allowedGroups);
  137. }
  138. /**
  139. * 提取客户群组ID
  140. */
  141. protected function extractCustomerGroupId($customer): ?string
  142. {
  143. if ($customer instanceof Customer) {
  144. return $customer->customer_group_id;
  145. }
  146. if (is_object($customer) && property_exists($customer, 'customer_group_id')) {
  147. return $customer->customer_group_id;
  148. }
  149. return null;
  150. }
  151. /**
  152. * 获取交易类型文本
  153. */
  154. public function getTransactionTypeTextAttribute(): string
  155. {
  156. $types = [
  157. self::TYPE_ORDER => 'Order',
  158. self::TYPE_REGISTRATION => 'Registration',
  159. self::TYPE_REVIEW => 'Product Review',
  160. self::TYPE_LOGIN => 'Login',
  161. self::TYPE_REFERRAL => 'Referral',
  162. self::TYPE_BIRTHDAY => 'Birthday',
  163. self::TYPE_SHARE => 'Share',
  164. self::TYPE_SUBSCRIBE => 'Subscription',
  165. self::TYPE_SIGN_IN => 'Sign In',
  166. ];
  167. return $types[$this->type_of_transaction] ?? 'Unknown';
  168. }
  169. /**
  170. * 作用域:获取启用的规则
  171. */
  172. public function scopeActive($query)
  173. {
  174. return $query->where('status', 1);
  175. }
  176. /**
  177. * 作用域:按交易类型查询
  178. */
  179. public function scopeOfType($query, $type)
  180. {
  181. return $query->where('type_of_transaction', $type);
  182. }
  183. }