Browse Source

update: add coupon per user limit

tokumeikoi 3 years ago
parent
commit
5a3b897c57

+ 6 - 19
app/Http/Controllers/User/CouponController.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers\User;
 
 use App\Http\Controllers\Controller;
+use App\Services\CouponService;
 use Illuminate\Http\Request;
 use App\Models\Coupon;
 
@@ -13,26 +14,12 @@ class CouponController extends Controller
         if (empty($request->input('code'))) {
             abort(500, __('Coupon cannot be empty'));
         }
-        $coupon = Coupon::where('code', $request->input('code'))->first();
-        if (!$coupon) {
-            abort(500, __('Invalid coupon'));
-        }
-        if ($coupon->limit_use <= 0 && $coupon->limit_use !== NULL) {
-            abort(500, __('This coupon is no longer available'));
-        }
-        if (time() < $coupon->started_at) {
-            abort(500, __('This coupon has not yet started'));
-        }
-        if (time() > $coupon->ended_at) {
-            abort(500, __('This coupon has expired'));
-        }
-        if ($coupon->limit_plan_ids) {
-            if (!in_array($request->input('plan_id'), $coupon->limit_plan_ids)) {
-                abort(500, __('The coupon code cannot be used for this subscription'));
-            }
-        }
+        $couponService = new CouponService($request->input('code'));
+        $couponService->setPlanId($request->input('plan_id'));
+        $couponService->setUserId($request->session()->get('id'));
+        $couponService->check();
         return response([
-            'data' => $coupon
+            'data' => $couponService->getCoupon()
         ]);
     }
 }

+ 1 - 0
app/Http/Requests/Admin/CouponSave.php

@@ -20,6 +20,7 @@ class CouponSave extends FormRequest
             'started_at' => 'required|integer',
             'ended_at' => 'required|integer',
             'limit_use' => 'nullable|integer',
+            'limit_use_with_user' => 'nullable|integer',
             'limit_plan_ids' => 'nullable|array',
             'code' => ''
         ];

+ 59 - 18
app/Services/CouponService.php

@@ -8,27 +8,20 @@ use Illuminate\Support\Facades\DB;
 
 class CouponService
 {
-    public $order;
+    public $coupon;
+    public $planId;
+    public $userId;
 
     public function __construct($code)
     {
         $this->coupon = Coupon::where('code', $code)->first();
-        if (!$this->coupon) {
-            abort(500, '优惠券无效');
-        }
-        if ($this->coupon->limit_use <= 0 && $this->coupon->limit_use !== NULL) {
-            abort(500, '优惠券已无可用次数');
-        }
-        if (time() < $this->coupon->started_at) {
-            abort(500, '优惠券还未到可用时间');
-        }
-        if (time() > $this->coupon->ended_at) {
-            abort(500, '优惠券已过期');
-        }
     }
 
     public function use(Order $order)
     {
+        $this->setPlanId($order->plan_id);
+        $this->setUserId($order->user_id);
+        $this->check();
         switch ($this->coupon->type) {
             case 1:
                 $order->discount_amount = $this->coupon->value;
@@ -43,11 +36,6 @@ class CouponService
                 return false;
             }
         }
-        if ($this->coupon->limit_plan_ids) {
-            if (!in_array($order->plan_id, $this->coupon->limit_plan_ids)) {
-                return false;
-            }
-        }
         return true;
     }
 
@@ -55,4 +43,57 @@ class CouponService
     {
         return $this->coupon->id;
     }
+
+    public function getCoupon()
+    {
+        return $this->coupon;
+    }
+
+    public function setPlanId($planId)
+    {
+        $this->planId = $planId;
+    }
+
+    public function setUserId($userId)
+    {
+        $this->userId = $userId;
+    }
+
+    public function checkLimitUseWithUser()
+    {
+        $usedCount = Order::where('coupon_id', $this->coupon->id)
+            ->where('user_id', $this->userId)
+            ->whereNotIn('status', [0, 2])
+            ->count();
+        if ($usedCount >= $this->coupon->limit_use_with_user) return false;
+        return true;
+    }
+
+    public function check()
+    {
+        if (!$this->coupon) {
+            abort(500, __('Invalid coupon'));
+        }
+        if ($this->coupon->limit_use <= 0 && $this->coupon->limit_use !== NULL) {
+            abort(500, __('This coupon is no longer available'));
+        }
+        if (time() < $this->coupon->started_at) {
+            abort(500, __('This coupon has not yet started'));
+        }
+        if (time() > $this->coupon->ended_at) {
+            abort(500, __('This coupon has expired'));
+        }
+        if ($this->coupon->limit_plan_ids && $this->planId) {
+            if (!in_array($this->planId, $this->coupon->limit_plan_ids)) {
+                abort(500, __('The coupon code cannot be used for this subscription'));
+            }
+        }
+        if ($this->coupon->limit_use_with_user !== NULL && $this->userId) {
+            if (!$this->checkLimitUseWithUser()) {
+                abort(500, __('The coupon can only be used :limit_use_with_user per person', [
+                    'limit_use_with_user' => $this->coupon->limit_use_with_user
+                ]));
+            }
+        }
+    }
 }

+ 2 - 1
database/install.sql

@@ -27,6 +27,7 @@ CREATE TABLE `v2_coupon` (
                              `type` tinyint(1) NOT NULL,
                              `value` int(11) NOT NULL,
                              `limit_use` int(11) DEFAULT NULL,
+                             `limit_use_with_user` int(11) DEFAULT NULL,
                              `limit_plan_ids` varchar(255) DEFAULT NULL,
                              `started_at` int(11) NOT NULL,
                              `ended_at` int(11) NOT NULL,
@@ -351,4 +352,4 @@ CREATE TABLE `v2_user` (
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
--- 2021-08-18 12:22:48
+-- 2021-08-28 06:53:57

+ 3 - 0
database/update.sql

@@ -435,3 +435,6 @@ ADD INDEX `server_id` (`server_id`);
 
 ALTER TABLE `v2_ticket_message`
     CHANGE `message` `message` text COLLATE 'utf8mb4_general_ci' NOT NULL AFTER `ticket_id`;
+
+ALTER TABLE `v2_coupon`
+    ADD `limit_use_with_user` int(11) NULL AFTER `limit_use`;

File diff suppressed because it is too large
+ 0 - 0
public/assets/admin/umi.js


+ 2 - 1
resources/lang/en-US.json

@@ -84,5 +84,6 @@
     "Email format is incorrect": "Email format is incorrect",
     "Password can not be empty": "Password can not be empty",
     "The traffic usage in :app_name has reached 80%": "The traffic usage in :app_name has reached 80%",
-    "The service in :app_name is about to expire": "The service in :app_name is about to expire"
+    "The service in :app_name is about to expire": "The service in :app_name is about to expire",
+    "The coupon can only be used :limit_use_with_user per person": "The coupon can only be used :limit_use_with_user per person"
 }

+ 2 - 1
resources/lang/zh-CN.json

@@ -84,5 +84,6 @@
     "Email format is incorrect": "邮箱格式不正确",
     "Password can not be empty": "密码不能为空",
     "The traffic usage in :app_name has reached 80%": "在:app_name的流量使用已达到80%",
-    "The service in :app_name is about to expire": "在:app_name的服务即将到期"
+    "The service in :app_name is about to expire": "在:app_name的服务即将到期",
+    "The coupon can only be used :limit_use_with_user per person": "该优惠券每人只能用:limit_use_with_user次"
 }

Some files were not shown because too many files changed in this diff