Browse Source

砍价下单

lizhen_gitee 3 months ago
parent
commit
9e70b3849b
1 changed files with 209 additions and 0 deletions
  1. 209 0
      addons/shopro/library/activity/provider/Kan.php

+ 209 - 0
addons/shopro/library/activity/provider/Kan.php

@@ -0,0 +1,209 @@
+<?php
+
+namespace addons\shopro\library\activity\provider;
+
+use addons\shopro\service\StockSale;
+use addons\shopro\exception\ShoproException;
+
+/**
+ * 砍价
+ */
+class Kan extends Base
+{
+    protected $rules = [
+        "is_commission" => "require|boolean",
+        "is_free_shipping" => "require|boolean",
+        "sales_show_type" => "require",
+        "limit_num" => "number|egt:0",
+        "order_auto_close" => "float|egt:0",
+        "team_num" => "require|number|egt:0",
+    ];
+
+
+    protected $message  =   [
+        'team_num.require'     => '请填写最多砍价人数',
+    ];
+
+
+    protected $default = [
+        "is_commission" => 0,          // 是否参与分销
+        "is_free_shipping" => 0,          // 是否包邮
+        "sales_show_type" => "real",          // real=真实活动销量|goods=商品总销量(包含虚拟销量)
+        "limit_num" => 0,                     // 每人限购数量 0:不限购
+        "order_auto_close" => 0,               // 订单自动关闭时间,如果为 0 将使用系统级订单自动关闭时间
+        "team_num" => 2,                    // 砍价人数,最少两人
+    ];
+
+
+    public function check($params, $activity_id = 0)
+    {
+        // 数据验证
+        $params = parent::check($params);
+
+        // 验证添加的活动商品是否至少设置了一个活动规格
+        $this->checkActivitySkuPrice($params['goods_list']);
+        
+        // 检测活动之间是否存在冲突
+        $this->checkActivityConflict($params, $params['goods_list'], $activity_id);
+
+        return $params;
+    }
+
+
+    public function save($activity, $params = [])
+    {
+        $goodsList = $params['goods_list'];
+
+        $this->saveSkuPrice($goodsList, $activity);
+    }
+
+
+
+    public function recoverSkuPrices($goods, $activity)
+    {
+        $activitySkuPrices = $activity['activity_sku_prices'];
+        $skuPrices = $goods->sku_prices;
+
+        foreach ($skuPrices as $key => &$skuPrice) {
+            $stock = $skuPrice->stock;      // 下面要用
+            $skuPrice->stock = 0;
+            $skuPrice->sales = 0;
+            foreach ($activitySkuPrices as $activitySkuPrice) {
+                if ($skuPrice['id'] == $activitySkuPrice['goods_sku_price_id']) {
+                    // 采用活动的 规格内容
+                    $skuPrice->old_price = $skuPrice->price;        // 保存原始普通商品规格的价格(计算活动的优惠)
+                    $skuPrice->stock = ($activitySkuPrice['stock'] > $stock) ? $stock : $activitySkuPrice['stock'];     // 活动库存不能超过商品库存
+                    $skuPrice->sales = $activitySkuPrice['sales'];
+                    $skuPrice->price = $activitySkuPrice['price'];
+                    $skuPrice->status = $activitySkuPrice['status'];        // 采用活动的上下架
+                    $skuPrice->min_price = $activitySkuPrice['price'];      // 当前活动规格最小价格,这里是秒杀价
+                    $skuPrice->max_price = $activitySkuPrice['price'];      // 用作计算活动中最大价格
+
+                    // 记录相关活动类型
+                    $skuPrice->activity_type = $activity['type'];
+                    $skuPrice->activity_id = $activity['id'];
+                    // 下单的时候需要存活动 的 sku_price_id)
+                    $skuPrice->item_goods_sku_price = $activitySkuPrice;
+                    break;
+                }
+            }
+        }
+
+        return $skuPrices;
+    }
+
+
+
+    /**
+     * 这里要使用 shoproException 抛出异常
+     *
+     * @param array $buyInfo
+     * @param array $activity
+     * @return array
+     */
+    public function buyCheck($buyInfo, $activity)
+    {
+        $buy_type = request()->param('buy_type', 'kan');
+        $groupon_id = request()->param('kan_id', 0);
+        // 拼团
+        $rules = $activity['rules'];
+
+        $currentSkuPrice = $buyInfo['current_sku_price'];
+        $is_leader_discount = $currentSkuPrice['is_leader_discount'];
+
+        // 成团人数
+        $num = $rules['team_num'] ?? 1;
+        // 额外需要的库存
+        $need_add_num = 0;
+
+        // 要单独购买
+        if ($buy_type == 'alone') {
+            // 不允许单独购买
+            if (!$is_alone) {
+                throw new ShoproException('该商品不允许单独购买');
+            }
+        } else {
+            // 拼团,临时将拼团价设置为商品价格
+            if (!$groupon_id && $is_leader_discount) {
+                // 开新团,并且有团长优惠,使用优惠价格
+                $buyInfo['current_sku_price']['price'] = $currentSkuPrice['leader_price'];
+            } else {
+                // 参与团,或者没有团长优惠
+                $buyInfo['current_sku_price']['price'] = $currentSkuPrice['groupon_price'];
+            }
+        }
+
+        // 如果是开新团
+        if (!$groupon_id && $buy_type == 'groupon') {
+            // 开团需要的最小库存
+            $need_add_num = ($num - 1);
+        }
+
+        // 当前库存,小于要购买的数量
+        $need_num = $buyInfo['goods_num'] + ($need_add_num ?? 0);
+        if ($currentSkuPrice['stock'] < $need_num) {
+            if ($need_add_num && $is_alone && !$groupon_id && $buy_type == 'groupon') {
+                throw new ShoproException('商品库存不足以开团,请选择单独购买');
+            } else if ($buy_type == 'alone') {
+                throw new ShoproException('商品库存不足');
+            } else {
+                throw new ShoproException('该商品不允商品库存不足以开团许单独购买');
+            }
+        }
+
+        $buyInfo['is_commission'] = $rules['is_commission'] ?? 0;        // 是否参与分销
+        return $buyInfo;
+    }
+
+
+
+    public function buy($buyInfo, $activity)
+    {
+        $user = auth_user();
+        $buy_type = request()->param('buy_type', 'kan');
+        $groupon_id = request()->param('kan_id', 0);
+
+        // 参与现有团
+        if ($buy_type != 'alone' && $groupon_id) {
+            // 检测并获取要参与的团
+            $activityGroupon = $this->checkAndGetJoinGroupon($buyInfo, $user, $groupon_id);
+        }
+
+        // 判断 并 增加 redis 销量
+        $stockSale = new StockSale();
+        $stockSale->cacheForwardSale($buyInfo);
+
+        // (开新团不判断)参与旧团 增加预拼团人数,上面加入团的时候已经判断过一次了,所以这里 99.99% 会加入成功的
+        if (isset($activityGroupon) && $activityGroupon) {
+            // 增加拼团预成员人数
+            $goods = $buyInfo['goods'];
+            $activity = $goods['activity'];
+            $this->grouponCacheForwardNum($activityGroupon, $activity, $user);
+        }
+
+        return $buyInfo;
+    }
+
+
+
+    public function buyOk($order, $user)
+    {
+        // 不需要处理
+    }
+
+
+
+    /**
+     * 拼团购买失败
+     *
+     * @param \think\Model $order
+     * @param string $type
+     * @return void
+     */
+    public function buyFail($order, $type)
+    {
+        // 判断扣除预销量 (活动信息还在 redis)
+        $stockSale = new StockSale();
+        $stockSale->cacheBackSale($order);
+    }
+}