bianjunhui 1 tydzień temu
rodzic
commit
2e9f3e70c7

+ 135 - 0
packages/Longyi/RewardPoints/src/Http/Controllers/RewardPointsController.php

@@ -419,6 +419,141 @@ class RewardPointsController extends Controller
         ]);
     }
 
+    /**
+     * 支持的关注平台
+     */
+    const FOLLOW_PLATFORMS = ['ig' => 'Instagram', 'fb' => 'Facebook', 'ytb' => 'YouTube', 'tt' => 'TikTok'];
+
+    /**
+     * 关注社交平台赠送积分(每位用户每个平台仅一次,永久有效)
+     *
+     * @param Request $request
+     * @return \Illuminate\Http\JsonResponse
+     */
+    public function followPlatform(Request $request)
+    {
+        $customer = auth()->guard('customer')->user();
+
+        if (!$customer) {
+            return ApiResponse::unauthorized();
+        }
+
+        $platform = $request->input('platform');
+
+        if (!$platform || !isset(self::FOLLOW_PLATFORMS[$platform])) {
+            return ApiResponse::validationError('Invalid platform. Supported: ' . implode(', ', array_keys(self::FOLLOW_PLATFORMS)));
+        }
+
+        // Redis Key: follow_platform:{customer_id}:{platform}(永久有效,不设 TTL)
+        $redisKey = "follow_platform:{$customer->id}:{$platform}";
+
+        // 1. Redis 快速判断(主缓存)
+        if (Redis::exists($redisKey)) {
+            return ApiResponse::error('You have already earned points for following ' . self::FOLLOW_PLATFORMS[$platform]);
+        }
+
+        // 2. DB 兜底检查:防止 Redis 被清理后重复发积分
+        $dbExists = RewardPointHistory::where('customer_id', $customer->id)
+            ->where('type_of_transaction', RewardActiveRule::TYPE_FOLLOW)
+            ->where('transaction_detail', 'Followed ' . self::FOLLOW_PLATFORMS[$platform])
+            ->exists();
+
+        if ($dbExists) {
+            // DB 有记录但 Redis 丢失,回补 Redis
+            Redis::set($redisKey, 1);
+            return ApiResponse::error('You have already earned points for following ' . self::FOLLOW_PLATFORMS[$platform]);
+        }
+
+        // 查询有效的关注规则
+        $rule = RewardActiveRule::active()
+            ->ofType(RewardActiveRule::TYPE_FOLLOW)
+            ->first();
+
+        if (!$rule) {
+            return ApiResponse::forbidden('Follow reward is not available');
+        }
+
+        // 检查规则是否适用于当前客户
+        if (!$rule->isApplicableToCustomer($customer)) {
+            return ApiResponse::forbidden('This reward is not applicable to your account');
+        }
+
+        // 获取该客户应得的积分
+        $points = $rule->getPointsForCustomer($customer);
+        if ($points <= 0) {
+            $points = (int) $rule->reward_point;
+        }
+        if ($points <= 0) {
+            return ApiResponse::error('No points configured for follow reward');
+        }
+
+        // 添加积分
+        $this->rewardPointRepository->addPoints(
+            $customer->id,
+            RewardActiveRule::TYPE_FOLLOW,
+            $points,
+            null,
+            'Followed ' . self::FOLLOW_PLATFORMS[$platform],
+            $rule
+        );
+
+        // 写入 Redis(永久有效,无需 TTL)
+        Redis::set($redisKey, 1);
+
+        $totalPoints = $this->rewardPointRepository->getCustomerPoints($customer->id);
+
+        return ApiResponse::success([
+            'platform' => $platform,
+            'platform_name' => self::FOLLOW_PLATFORMS[$platform],
+            'points' => $points,
+            'total_points' => $totalPoints
+        ], 'You earned ' . $points . ' points for following ' . self::FOLLOW_PLATFORMS[$platform] . '!');
+    }
+
+    /**
+     * 获取用户已关注的平台列表及积分状态
+     *
+     * @return \Illuminate\Http\JsonResponse
+     */
+    public function getFollowStatus()
+    {
+        $customer = auth()->guard('customer')->user();
+
+        if (!$customer) {
+            return ApiResponse::unauthorized();
+        }
+
+        $platforms = [];
+        foreach (self::FOLLOW_PLATFORMS as $code => $name) {
+            $redisKey = "follow_platform:{$customer->id}:{$code}";
+            $followed = (bool) Redis::exists($redisKey);
+
+            // Redis 未命中时,从 DB 回补并修复 Redis
+            if (!$followed) {
+                $dbExists = RewardPointHistory::where('customer_id', $customer->id)
+                    ->where('type_of_transaction', RewardActiveRule::TYPE_FOLLOW)
+                    ->where('transaction_detail', 'Followed ' . $name)
+                    ->exists();
+
+                if ($dbExists) {
+                    Redis::set($redisKey, 1);
+                    $followed = true;
+                }
+            }
+
+            $platforms[] = [
+                'code' => $code,
+                'name' => $name,
+                'followed' => $followed
+            ];
+        }
+
+        return ApiResponse::success([
+            'platforms' => $platforms,
+            'followed_count' => count(array_filter($platforms, fn($p) => $p['followed']))
+        ]);
+    }
+
     /**
      * Get points information for cart
      */

+ 3 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/rules/index.blade.php

@@ -117,6 +117,9 @@
                                 'indigo' => 'bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300',
                                 'pink' => 'bg-pink-100 dark:bg-pink-900 text-pink-700 dark:text-pink-300',
                                 'orange' => 'bg-orange-100 dark:bg-orange-900 text-orange-700 dark:text-orange-300',
+                                'red' => 'bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-300',
+                                'cyan' => 'bg-cyan-100 dark:bg-cyan-900 text-cyan-700 dark:text-cyan-300',
+                                'teal' => 'bg-teal-100 dark:bg-teal-900 text-teal-700 dark:text-teal-300',
                                 'gray' => 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400',
                             ];
                         @endphp

+ 10 - 0
packages/Longyi/RewardPoints/src/Routes/routes.php

@@ -109,6 +109,16 @@ Route::group(['middleware' => ['api', ApiCustomerAuthenticate::class], 'prefix'
         'as' => 'api.customer.reward-points.browsed-products',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\RewardPointsController@getBrowsedProducts'
     ]);
+
+    Route::post('reward-points/follow', [
+        'as' => 'api.customer.reward-points.follow',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\RewardPointsController@followPlatform'
+    ]);
+
+    Route::get('reward-points/follow-status', [
+        'as' => 'api.customer.reward-points.follow-status',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\RewardPointsController@getFollowStatus'
+    ]);
 });
 
 // 后台路由