Просмотр исходного кода

优化:商品会员等级折扣价计算

Yahoo 4 лет назад
Родитель
Сommit
d4250e5c7f

+ 23 - 24
app/api/model/Goods.php

@@ -12,12 +12,12 @@ declare (strict_types=1);
 
 namespace app\api\model;
 
-use app\api\service\User as UserService;
 use app\api\model\GoodsSpecRel as GoodsSpecRelModel;
+use app\api\service\user\Grade as UserGradeService;
 use app\common\model\Goods as GoodsModel;
 use app\common\enum\goods\Status as GoodsStatusEnum;
 use app\common\library\helper;
-use app\common\exception\BaseException;
+use cores\exception\BaseException;
 
 /**
  * 商品模型
@@ -48,7 +48,7 @@ class Goods extends GoodsModel
      * @param $value
      * @return string
      */
-    public function getContentAttr($value)
+    public function getContentAttr($value): string
     {
         return htmlspecialchars_decode((string)$value);
     }
@@ -147,32 +147,31 @@ class Goods extends GoodsModel
      */
     private function setGoodsGradeMoney(self $goods)
     {
-        // 获取当前登录的用户信息
-        $userInfo = UserService::getCurrentLoginUser();
-        // 会员等级状态
-        $gradeStatus = (!empty($userInfo) && $userInfo['grade_id'] > 0 && !empty($userInfo['grade']))
-            && (!$userInfo['grade']['is_delete'] && $userInfo['grade']['status']);
+        // 设置当前商品是否使用会员等级折扣价
+        $goods['is_user_grade'] = false;
+        // 获取当前登录用户的会员等级信息
+        $gradeInfo = UserGradeService::getCurrentGradeInfo();
         // 判断商品是否参与会员折扣
-        if (!$gradeStatus || !$goods['is_enable_grade']) {
-            $goods['is_user_grade'] = false;
+        if (empty($gradeInfo) || !$goods['is_enable_grade']) {
             return;
         }
+        // 默认的折扣比例
+        $discountRatio = $gradeInfo['equity']['discount'];
         // 商品单独设置了会员折扣
-        if ($goods['is_alone_grade'] && isset($goods['alone_grade_equity'][$userInfo['grade_id']])) {
-            // 折扣比例
-            $discountRatio = helper::bcdiv($goods['alone_grade_equity'][$userInfo['grade_id']], 10);
-        } else {
-            // 折扣比例
-            $discountRatio = helper::bcdiv($userInfo['grade']['equity']['discount'], 10);
+        if ($goods['is_alone_grade'] && isset($goods['alone_grade_equity'][$gradeInfo['grade_id']])) {
+            $discountRatio = $goods['alone_grade_equity'][$gradeInfo['grade_id']];
         }
-        if ($discountRatio > 0) {
-            // 标记参与会员折扣
-            $goods['is_user_grade'] = true;
-            // 会员折扣价
-            foreach ($goods['skuList'] as &$skuItem) {
-                $skuItem['goods_price'] = helper::number2(helper::bcmul($skuItem['goods_price'], $discountRatio), true);
-            }
+        if (empty($discountRatio)) {
+            return;
+        }
+        // 标记参与会员折扣
+        $goods['is_user_grade'] = true;
+        // 会员折扣价: 商品基础价格
+        $goods['goods_price_min'] = UserGradeService::getDiscountPrice($goods['goods_price_min'], $discountRatio);
+        $goods['goods_price_max'] = UserGradeService::getDiscountPrice($goods['goods_price_max'], $discountRatio);
+        // 会员折扣价: 商品sku
+        foreach ($goods['skuList'] as &$skuItem) {
+            $skuItem['goods_price'] = UserGradeService::getDiscountPrice($skuItem['goods_price'], $discountRatio);
         }
     }
-
 }

+ 20 - 20
app/api/service/order/Checkout.php

@@ -21,6 +21,7 @@ use app\api\model\UserCoupon as UserCouponModel;
 
 use app\api\service\User as UserService;
 use app\api\service\Payment as PaymentService;
+use app\api\service\user\Grade as UserGradeService;
 use app\api\service\coupon\GoodsDeduct as GoodsDeductService;
 use app\api\service\points\GoodsDeduct as PointsDeductService;
 use app\api\service\order\source\checkout\Factory as CheckoutFactory;
@@ -468,6 +469,7 @@ class Checkout extends BaseService
     /**
      * 设置订单商品会员折扣价
      * @return void
+     * @throws BaseException
      */
     private function setOrderGoodsGradeMoney(): void
     {
@@ -487,11 +489,10 @@ class Checkout extends BaseService
         if (!$this->checkoutRule['isUserGrade']) {
             return;
         }
-        // 会员等级状态
-        if (!(
-            $this->user['grade_id'] > 0 && !empty($this->user['grade'])
-            && !$this->user['grade']['is_delete'] && $this->user['grade']['status']
-        )) {
+        // 获取当前登录用户的会员等级信息
+        $gradeInfo = UserGradeService::getCurrentGradeInfo();
+        // 判断商品是否参与会员折扣
+        if (empty($gradeInfo)) {
             return;
         }
         // 计算抵扣金额
@@ -500,25 +501,24 @@ class Checkout extends BaseService
             if (!$goods['is_enable_grade']) {
                 continue;
             }
+            // 折扣比例
+            $discountRatio = $gradeInfo['equity']['discount'];
             // 商品单独设置了会员折扣
             if ($goods['is_alone_grade'] && isset($goods['alone_grade_equity'][$this->user['grade_id']])) {
-                // 折扣比例
-                $discountRatio = helper::bcdiv($goods['alone_grade_equity'][$this->user['grade_id']], 10);
-            } else {
-                // 折扣比例
-                $discountRatio = helper::bcdiv($this->user['grade']['equity']['discount'], 10);
+                $discountRatio = $goods['alone_grade_equity'][$gradeInfo['grade_id']];
             }
-            if ($discountRatio > 0) {
-                // 会员折扣后的商品总金额
-                $gradeTotalPrice = max(0.01, helper::bcmul($goods['total_price'], $discountRatio));
-                helper::setDataAttribute($goods, [
-                    'is_user_grade' => true,
-                    'grade_ratio' => $discountRatio,
-                    'grade_goods_price' => helper::number2(helper::bcmul($goods['goods_price'], $discountRatio), true),
-                    'grade_total_money' => helper::number2(helper::bcsub($goods['total_price'], $gradeTotalPrice)),
-                    'total_price' => $gradeTotalPrice,
-                ], false);
+            if (empty($discountRatio)) {
+                continue;
             }
+            // 会员折扣后的商品总金额
+            $gradeTotalPrice = UserGradeService::getDiscountPrice($goods['total_price'], $discountRatio);
+            helper::setDataAttribute($goods, [
+                'is_user_grade' => true,
+                'grade_ratio' => $discountRatio,
+                'grade_goods_price' =>  UserGradeService::getDiscountPrice($goods['goods_price'], $discountRatio),
+                'grade_total_money' => helper::bcsub($goods['total_price'], $gradeTotalPrice),
+                'total_price' => $gradeTotalPrice,
+            ], false);
         }
     }
 

+ 59 - 0
app/api/service/user/Grade.php

@@ -0,0 +1,59 @@
+<?php
+// +----------------------------------------------------------------------
+// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
+// +----------------------------------------------------------------------
+// | Author: 萤火科技 <admin@yiovo.com>
+// +----------------------------------------------------------------------
+declare (strict_types=1);
+
+namespace app\api\service\user;
+
+use app\common\library\helper;
+use app\common\service\BaseService;
+use app\api\service\User as UserService;
+use app\api\model\user\Grade as UserGradeModel;
+use cores\exception\BaseException;
+
+/**
+ * 服务类: 会员等级
+ * Class Grade
+ * @package app\api\service\user
+ */
+class Grade extends BaseService
+{
+    /**
+     * 获取当前登录用户的会员等级信息
+     * @param bool $isForce 是否强制验证登录, 如果未登录将抛错
+     * @throws BaseException
+     */
+    public static function getCurrentGradeInfo(bool $isForce = false)
+    {
+        // 当前登录的用户信息
+        $userInfo = UserService::getCurrentLoginUser($isForce);
+        if (empty($userInfo) || empty($userInfo['grade_id'])) {
+            return false;
+        }
+        // 获取会员等级信息
+        $gradeInfo = UserGradeModel::detail($userInfo['grade_id']);
+        if (empty($gradeInfo) || $gradeInfo['is_delete'] || empty($gradeInfo['status'])) {
+            return false;
+        }
+        return $gradeInfo;
+    }
+
+    /**
+     * 获取和计算折扣后的价格
+     * @param $originalPrice
+     * @param $discountRatio
+     * @return string
+     */
+    public static function getDiscountPrice($originalPrice, $discountRatio): string
+    {
+        $discountPrice = helper::bcmul($originalPrice, $discountRatio / 10);
+        return helper::number2($discountPrice, true);
+    }
+}

+ 8 - 1
app/common/library/helper.php

@@ -81,7 +81,14 @@ class helper
         return $data;
     }
 
-    public static function number2($number, $isMinimum = false, $minimum = 0.01): string
+    /**
+     * 格式化价格显示
+     * @param mixed $number
+     * @param bool $isMinimum 是否存在最小值
+     * @param float $minimum
+     * @return string
+     */
+    public static function number2($number, bool $isMinimum = false, float $minimum = 0.01): string
     {
         $isMinimum && $number = max($minimum, $number);
         return sprintf('%.2f', $number);