bianjunhui 6 дней назад
Родитель
Сommit
6e4edbe85e

+ 13 - 35
packages/Longyi/RewardPoints/src/Listeners/OrderEvents.php

@@ -35,16 +35,25 @@ class OrderEvents
         }
 
         $customer = $order->customer;
+
+        // 1. 检查规则是否适用
         if (!$rule->isApplicableToCustomer($customer)) {
             Log::info('Order rule not applicable', [
                 'order_id' => $order->id,
                 'customer_id' => $order->customer_id,
-                'customer_group_id' => $customer->customer_group_id ?? null
             ]);
             return;
         }
 
-        $points = $this->calculateOrderPoints($order, $rule, $customer);
+        // 2. 使用统一方法获取积分倍率
+        $pointsPerCurrency = $rule->getPointsForCustomer($customer);
+
+        if ($pointsPerCurrency <= 0) {
+            return;
+        }
+
+        // 3. 计算订单积分
+        $points = (int)floor($order->base_grand_total * $pointsPerCurrency);
 
         if ($points > 0) {
             $this->rewardPointRepository->addPoints(
@@ -58,8 +67,8 @@ class OrderEvents
 
             Log::info('Order points added as PENDING', [
                 'order_id' => $order->id,
-                'customer_id' => $order->customer_id,
-                'points' => $points
+                'points' => $points,
+                'rate' => $pointsPerCurrency
             ]);
         }
     }
@@ -109,35 +118,6 @@ class OrderEvents
             ->first();
     }
 
-    /**
-     * 计算订单积分
-     */
-    protected function calculateOrderPoints(Order $order, RewardActiveRule $rule, $customer): int
-    {
-        $pointsPerCurrency = $this->getPointsPerCurrency($rule, $customer);
-
-        if ($pointsPerCurrency <= 0) {
-            return 0;
-        }
-
-        return (int)floor($order->base_grand_total * $pointsPerCurrency);
-    }
-
-    /**
-     * 获取积分倍率
-     */
-    protected function getPointsPerCurrency(RewardActiveRule $rule, $customer): int
-    {
-        if ($rule->enable_different_points_by_group && $customer) {
-            $customerGroupId = $customer->customer_group_id ?? null;
-            if ($customerGroupId !== null) {
-                return $rule->getRewardPointForCustomerGroup($customerGroupId);
-            }
-        }
-
-        return (int)$rule->reward_point;
-    }
-
     /**
      * 处理取消订单的积分记录
      */
@@ -147,7 +127,6 @@ class OrderEvents
             return;
         }
 
-        // 只有 COMPLETED 状态需要扣减余额
         if ($history->status === RewardPointHistory::STATUS_COMPLETED) {
             $this->rewardPointRepository->deductPoints(
                 $order->customer_id,
@@ -157,7 +136,6 @@ class OrderEvents
             );
         }
 
-        // 更新历史记录
         $history->status = RewardPointHistory::STATUS_CANCELLED;
         $history->point_remaining = 0;
         $history->save();

+ 21 - 65
packages/Longyi/RewardPoints/src/Listeners/ReviewEvents.php

@@ -4,7 +4,6 @@ namespace Longyi\RewardPoints\Listeners;
 
 use Longyi\RewardPoints\Repositories\RewardPointRepository;
 use Longyi\RewardPoints\Models\RewardActiveRule;
-use Longyi\RewardPoints\Models\RewardPointHistory;
 use Webkul\Customer\Models\Customer;
 use Illuminate\Support\Facades\Log;
 
@@ -17,9 +16,6 @@ class ReviewEvents
         $this->rewardPointRepository = $rewardPointRepository;
     }
 
-    /**
-     * 处理评价创建事件,赠送评价积分
-     */
     public function handleReviewCreation($review): void
     {
         // 验证基础条件
@@ -43,38 +39,37 @@ class ReviewEvents
             return;
         }
 
-        // 检查规则是否适用于该客户
+        // 【简化】只需要调用 isApplicableToCustomer,它会内部处理所有适用性检查
         if (!$rule->isApplicableToCustomer($customer)) {
-            Log::info('Review rule not applicable to this customer group', [
+            Log::info('Review rule not applicable', [
                 'review_id' => $review->id,
                 'customer_id' => $customer->id,
-                'customer_group_id' => $customer->customer_group_id ?? null
             ]);
             return;
         }
 
-        // 检查是否已经为该评价发放过积分(防止重复发放)
-        if ($this->hasReceivedReviewPoints($review->id, $customer->id)) {
-            Log::info('Review points already granted, skipping', [
+        // 【简化】使用统一方法获取积分值
+        $points = $rule->getPointsForCustomer($customer);
+
+        if ($points <= 0) {
+            Log::info('Review points is 0, skipping', [
                 'review_id' => $review->id,
-                'customer_id' => $customer->id
+                'points' => $points
             ]);
             return;
         }
 
-        // 获取积分值
-        $points = $this->getReviewPoints($customer, $rule);
-        if ($points <= 0) {
-            Log::info('Review points is 0 or negative, skipping', [
+        // 检查是否已经为该评价发放过积分
+        if ($this->hasReceivedReviewPoints($review->id, $customer->id)) {
+            Log::info('Review points already granted', [
                 'review_id' => $review->id,
-                'customer_id' => $customer->id,
-                'points' => $points
+                'customer_id' => $customer->id
             ]);
             return;
         }
 
         // 添加评价积分
-        $history = $this->rewardPointRepository->addPoints(
+        $this->rewardPointRepository->addPoints(
             $review->customer_id,
             RewardActiveRule::TYPE_REVIEW,
             $points,
@@ -83,11 +78,10 @@ class ReviewEvents
             $rule
         );
 
-        Log::info('Review points added successfully', [
+        Log::info('Review points added', [
             'review_id' => $review->id,
             'customer_id' => $customer->id,
-            'points' => $points,
-            'history_id' => $history->history_id ?? null
+            'points' => $points
         ]);
     }
 
@@ -100,19 +94,13 @@ class ReviewEvents
             return false;
         }
 
-        // 检查是否有客户ID
         if (empty($review->customer_id)) {
-            Log::info('Review has no customer_id, skipping points', [
+            Log::info('Review has no customer_id', [
                 'review_id' => $review->id ?? null
             ]);
             return false;
         }
 
-        // 可选:检查评价状态是否已批准(如果评价系统有审核机制)
-        // if (isset($review->status) && $review->status !== 'approved') {
-        //     return false;
-        // }
-
         return true;
     }
 
@@ -134,33 +122,13 @@ class ReviewEvents
         return Customer::find($customerId);
     }
 
-    /**
-     * 获取评价积分值
-     */
-    protected function getReviewPoints(Customer $customer, RewardActiveRule $rule): int
-    {
-        $customerGroupId = $customer->customer_group_id;
-
-        if ($customerGroupId !== null) {
-            return $rule->getRewardPointForCustomerGroup($customerGroupId);
-        }
-
-        return (int)$rule->reward_point;
-    }
-
     /**
      * 检查是否已经为该评价发放过积分
      */
     protected function hasReceivedReviewPoints(int $reviewId, int $customerId): bool
     {
-        // 方案1:通过订单ID字段关联(如果评价有对应的订单ID)
-        // return RewardPointHistory::where('customer_id', $customerId)
-        //     ->where('type_of_transaction', RewardActiveRule::TYPE_REVIEW)
-        //     ->where('history_order_id', $reviewId)
-        //     ->exists();
-
-        // 方案2:通过备注字段判断(需要存储评价ID)
-        return RewardPointHistory::where('customer_id', $customerId)
+        // 通过备注字段判断(需要存储评价ID)
+        return \Longyi\RewardPoints\Models\RewardPointHistory::where('customer_id', $customerId)
             ->where('type_of_transaction', RewardActiveRule::TYPE_REVIEW)
             ->where('description', 'LIKE', "%Review ID: {$reviewId}%")
             ->exists();
@@ -171,22 +139,10 @@ class ReviewEvents
      */
     protected function getReviewPointsDescription($review): string
     {
-        $productInfo = '';
-
-        if (!empty($review->product_id)) {
-            $productInfo = " for product #{$review->product_id}";
-        }
+        $productInfo = !empty($review->product_id)
+            ? " for product #{$review->product_id}"
+            : '';
 
         return "Points earned for product review{$productInfo} (Review ID: {$review->id})";
     }
-
-    /**
-     * 批量处理多个评价(如果是一次性创建多个评价的场景)
-     */
-    public function handleMultipleReviewsCreation(array $reviews): void
-    {
-        foreach ($reviews as $review) {
-            $this->handleReviewCreation($review);
-        }
-    }
 }

+ 73 - 18
packages/Longyi/RewardPoints/src/Models/RewardActiveRule.php

@@ -26,6 +26,7 @@ class RewardActiveRule extends Model
         'rule_name', 'type_of_transaction', 'store_view', 'customer_group_ids',
         'enable_different_points_by_group', 'default_expired', 'expired_day',
         'date_event', 'comment', 'coupon_code', 'reward_point', 'status',
+        'group_points'  // 添加群组积分配置字段
     ];
 
     protected $casts = [
@@ -33,23 +34,66 @@ class RewardActiveRule extends Model
         'status' => 'boolean',
         'expired_day' => 'integer',
         'enable_different_points_by_group' => 'boolean',
+        'group_points' => 'array',  // 自动 JSON 转换
     ];
 
-    // 交易类型文本映射
-    protected const TRANSACTION_TYPES = [
-        self::TYPE_ORDER => 'Order',
-        self::TYPE_REGISTRATION => 'Registration',
-        self::TYPE_REVIEW => 'Product Review',
-        self::TYPE_LOGIN => 'Login',
-        self::TYPE_REFERRAL => 'Referral',
-        self::TYPE_BIRTHDAY => 'Birthday',
-        self::TYPE_SHARE => 'Share',
-        self::TYPE_SUBSCRIBE => 'Subscription',
-        self::TYPE_SIGN_IN => 'Sign In',
-    ];
+    /**
+     * 获取客户群组积分配置
+     * 假设数据库中 group_points 字段存储 JSON,格式:{"1": 100, "2": 150}
+     */
+    public function getCustomerGroupPointsAttribute(): array
+    {
+        // 如果使用 group_points 字段(推荐)
+        if (isset($this->attributes['group_points'])) {
+            $value = $this->attributes['group_points'];
+            if (is_string($value)) {
+                return json_decode($value, true) ?: [];
+            }
+            return is_array($value) ? $value : [];
+        }
+
+        // 兼容其他可能的字段名
+        if (isset($this->attributes['customer_group_points'])) {
+            $value = $this->attributes['customer_group_points'];
+            if (is_string($value)) {
+                return json_decode($value, true) ?: [];
+            }
+            return is_array($value) ? $value : [];
+        }
+
+        return [];
+    }
+
+    /**
+     * 【核心方法】统一获取客户应得的积分值
+     * 整合了所有积分获取逻辑,避免重复代码
+     */
+    public function getPointsForCustomer($customer): int
+    {
+        // 获取客户群组ID
+        $customerGroupId = $this->extractCustomerGroupId($customer);
+
+        // 如果无法获取群组ID,返回0(注册、订阅等场景应该单独处理)
+        if ($customerGroupId === null) {
+            return 0;
+        }
+
+        // 启用群组差异化:从配置中获取该群组的积分
+        if ($this->enable_different_points_by_group) {
+            $groupPoints = $this->getCustomerGroupPointsAttribute();
+            return (int)($groupPoints[$customerGroupId] ?? 0);
+        }
+
+        // 不启用差异化:检查群组是否在允许列表中
+        if ($this->isGroupAllowed($customerGroupId)) {
+            return (int)$this->reward_point;
+        }
+
+        return 0;
+    }
 
     /**
-     * 获取特定客户群组的积分值
+     * 获取特定客户群组的积分值(保留向后兼容)
      */
     public function getRewardPointForCustomerGroup($customerGroupId): int
     {
@@ -58,7 +102,6 @@ class RewardActiveRule extends Model
             return (int)($groupPoints[$customerGroupId] ?? 0);
         }
 
-        // 不启用群组差异化时,检查群组是否允许
         if ($this->isGroupAllowed($customerGroupId)) {
             return (int)$this->reward_point;
         }
@@ -77,17 +120,18 @@ class RewardActiveRule extends Model
         }
 
         $customerGroupId = $this->extractCustomerGroupId($customer);
+
         if ($customerGroupId === null) {
             return false;
         }
 
-        // 启用群组差异化时,检查是否有积分配置
+        // 启用群组差异化:检查是否有为该群组配置积分
         if ($this->enable_different_points_by_group) {
             $groupPoints = $this->getCustomerGroupPointsAttribute();
             return !empty($groupPoints) && isset($groupPoints[$customerGroupId]);
         }
 
-        // 不启用差异化时,检查群组是否在允许列表中
+        // 不启用差异化检查群组是否在允许列表中
         return $this->isGroupAllowed($customerGroupId);
     }
 
@@ -111,7 +155,6 @@ class RewardActiveRule extends Model
      */
     protected function isGroupAllowed($customerGroupId): bool
     {
-        // 空表示适用于所有群组
         if (empty($this->customer_group_ids) || trim($this->customer_group_ids) === '') {
             return true;
         }
@@ -141,7 +184,19 @@ class RewardActiveRule extends Model
      */
     public function getTransactionTypeTextAttribute(): string
     {
-        return self::TRANSACTION_TYPES[$this->type_of_transaction] ?? 'Unknown';
+        $types = [
+            self::TYPE_ORDER => 'Order',
+            self::TYPE_REGISTRATION => 'Registration',
+            self::TYPE_REVIEW => 'Product Review',
+            self::TYPE_LOGIN => 'Login',
+            self::TYPE_REFERRAL => 'Referral',
+            self::TYPE_BIRTHDAY => 'Birthday',
+            self::TYPE_SHARE => 'Share',
+            self::TYPE_SUBSCRIBE => 'Subscription',
+            self::TYPE_SIGN_IN => 'Sign In',
+        ];
+
+        return $types[$this->type_of_transaction] ?? 'Unknown';
     }
 
     /**