Browse Source

积分兑换商品

zhangdehua 2 years ago
parent
commit
503b172e46

+ 54 - 0
app/api/controller/Checkout.php

@@ -26,6 +26,7 @@ use app\common\enum\order\PayType as OrderPayTypeEnum;
 use app\common\exception\BaseException;
 use app\common\library\helper;
 use app\common\service\card\UserRiceCard as UserRiceCardService;
+use app\api\service\order\CheckoutExchange as CheckoutExchangeService;
 use app\api\service\order\CheckoutGroupbuy as CheckoutGroupBuyService;
 use app\api\service\order\CheckoutGroupbuylb as CheckoutGroupBuylbService;
 use app\api\model\groupbuy\GroupBuyJoin;
@@ -91,11 +92,64 @@ class Checkout extends Controller
             return $this->za();
         }else if ($mode=='zareceive'){
             return $this->zareceive();
+        }elseif($mode == 'pointsExchange'){
+            return $this->pointsExchange();
         }
 
         return $this->renderError('结算模式不合法');
     }
 
+    private function pointsExchange()
+    {
+        // 实例化结算台服务
+        $Checkout = new CheckoutExchangeService;
+        // 订单结算api参数
+        $params = $Checkout->setParam($this->getParam([
+            'goodsId' => 0,
+            'goodsSkuId' => '',
+            'goodsNum' => 0,
+            'staffUserId' => 0,
+            'deliveryType' => 10 // 配送方式 默认10 10-快递配送 20-门店自提
+        ]));
+        // 表单验证
+        if (!$this->validate->scene('pointsExchange')->check($params)) {
+            return $this->renderError($this->validate->getError(), ['is_created' => false]);
+        }
+        // 立即购买:获取订单商品列表
+        $model = new OrderModel;
+        $params['staffUserId'] = $params['staffUserId']??0;
+        $goodsList = $model->getOrderGoodsListByNow(
+            (int)$params['goodsId'],
+            (string)$params['goodsSkuId'],
+            (int)$params['goodsNum'],
+            (int)$params['staffUserId']
+        );
+        // 获取订单确认信息
+        $orderInfo = $Checkout->onCheckoutExchange($goodsList);
+        if ($this->request->isGet()) {
+            return $this->renderSuccess(['order' => $orderInfo]);
+        }
+        // 验证订单是否存在错误
+        if ($Checkout->hasError()) {
+            return $this->renderError($Checkout->getError(), ['is_created' => false]);
+        }
+
+        //金钱和积分的兑换比例 todo
+        if ($this->user['accumulate_points'] < bcmul($orderInfo['orderTotalPrice'] , "100",0)) {
+            return $this->renderError('积分不足哦', ['is_created' => false]);
+        }
+            // 创建订单
+        if (!$Checkout->createOrder($orderInfo)) {
+            return $this->renderError($Checkout->getError() ?: '订单创建失败', ['is_created' => false]);
+        }
+
+        return $this->renderSuccess([
+            'order_id' => $Checkout->model['order_id'],// 订单id
+            'pay_type' => OrderPayTypeEnum::EXCHANGE,// 支付方式
+        ]);
+
+    }
+
     //买一赠一 领取
     public function zareceive(){
         $Checkout = new CheckoutZaService;

+ 7 - 0
app/api/controller/Goods.php

@@ -15,6 +15,7 @@ namespace app\api\controller;
 use app\api\model\Cart as CartModel;
 use app\api\model\Goods as GoodsModel;
 use app\api\service\User as UserService;
+use app\common\enum\goods\GoodsType;
 use app\common\library\helper;
 use app\common\model\BrowseRecords;
 use app\store\model\qc\QcMjSendActivity;
@@ -46,7 +47,13 @@ class Goods extends Controller
         // 获取列表数据
         $model = new GoodsModel;
         $list = $model->getList($this->request->param());
+        $goodsType = $this->request->param('goods_type', null);
         foreach ($list as $item){
+            if ($goodsType == GoodsType::EXCHANGE){
+                $item['za'] = null;
+                $item['miaosha'] = null;
+                continue;
+            }
               //买一赠一
             $za = (new ZaActivityModel())->getZaGood($item['goods_id']);
             if(isset($za)){

+ 4 - 0
app/api/controller/Test.php

@@ -4,6 +4,7 @@ namespace app\api\controller;
 
 
 use app\api\model\Order as OrderModel;
+use app\api\model\User as UserModel;
 use app\common\enum\order\PayType as OrderPayTypeEnum;
 use app\common\enum\order\ReceiptStatus as ReceiptStatusEnum;
 use app\common\service\Message;
@@ -57,6 +58,9 @@ class Test extends Controller
 
 
     public function tj(){
+        $res = UserModel::setIncAccumulatePoints(107633,99.11,10,'老板赠送');
+        dd($res);
+
         $otj = new OrderTj;
         $day = $otj->day(0);
        

+ 17 - 0
app/api/model/Order.php

@@ -688,6 +688,23 @@ class Order extends OrderModel
     }
 
     /**
+     * 积分兑换支付标记订单已支付
+     * @param string $orderNo 订单号
+     * @return bool
+     */
+    public function onPaymentByAccumulatePoints(string $orderNo)
+    {
+        // 获取订单详情
+        $service = new OrderPaySuccesService($orderNo);
+        // 发起积分支付
+        $status = $service->onPaySuccess(OrderPayTypeEnum::EXCHANGE);
+        if (!$status) {
+            $this->error = $service->getError();
+        }
+        return $status;
+    }
+
+    /**
      * 获取用户订单列表
      * @param string $type 订单类型 (all全部 payment待付款 delivery待发货 received待收货 completed已完成 comment待评价)
      * @return \think\Paginator

+ 41 - 0
app/api/model/user/AccumulatePointsLog.php

@@ -0,0 +1,41 @@
+<?php
+// +----------------------------------------------------------------------
+// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
+// +----------------------------------------------------------------------
+// | Author: 萤火科技 <admin@yiovo.com>
+// +----------------------------------------------------------------------
+declare (strict_types = 1);
+
+namespace app\api\model\user;
+
+use app\api\service\User as UserService;
+use app\common\model\user\AccumulatePointsLog as AccPointsLog;
+
+/**
+ * 用户余额变动明细模型
+ * Class PointsLog
+ * @package app\api\model\user
+ */
+class AccumulatePointsLog extends AccPointsLog
+{
+    /**
+     * 获取日志明细列表
+     * @return \think\Paginator
+     * @throws \app\common\exception\BaseException
+     * @throws \think\db\exception\DbException
+     */
+    public function getList()
+    {
+        // 当前用户ID
+        $userId = UserService::getCurrentLoginUserId();
+        // 获取列表数据
+        return $this->where('user_id', '=', $userId)
+            ->order(['create_time' => 'desc'])
+            ->paginate(15);
+    }
+
+}

+ 2 - 0
app/api/service/order/Checkout.php

@@ -71,6 +71,8 @@ class Checkout extends BaseService
 
     // 订单结算商品列表
     private $goodsList = [];
+    private $invalidGoodsList = [];
+    private $shopInfo = [];
 
     // 错误信息
     protected $error;

+ 1887 - 0
app/api/service/order/CheckoutExchange.php

@@ -0,0 +1,1887 @@
+<?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\order;
+
+use app\api\model\card\UserRiceCard as UserRiceCardModel;
+use app\api\model\card\UserRiceCardConsume as UserRiceCardConsumeModel;
+use app\api\model\fullsend\FullSendActivity;
+use app\api\model\GoodsCategoryRel as GoodsCategoryRelModel;
+use app\api\model\GoodsPackage as GoodsPackageModel;
+use app\api\model\member\DeductionLimit as DeductionLimitModel;
+use app\api\model\member\MemberGoods;
+use app\api\model\mj\MjSendActivity;
+use app\api\model\OrderGoodsTaocan as OrderGoodsTaocanModel;
+use app\api\model\Order as OrderModel;
+
+use app\api\model\qc\QcMjSendActivity;
+use app\api\model\User as UserModel;
+use app\api\model\Goods as GoodsModel;
+use app\api\model\Setting as SettingModel;
+use app\api\model\shop\Shops;
+use app\api\model\UserAddress;
+use app\api\model\UserCoupon as UserCouponModel;
+use app\api\model\member\GoldRice as GoldRiceModel;
+
+use app\api\service\User as UserService;
+use app\api\service\Payment as PaymentService;
+use app\api\service\coupon\GoodsDeduct as GoodsDeductService;
+use app\api\service\ricecard\GoodsDeduct as RiceDeductService;
+use app\api\service\points\GoodsDeduct as PointsDeductService;
+use app\api\service\order\source\checkout\Factory as CheckoutFactory;
+
+use app\common\enum\Setting as SettingEnum;
+use app\common\enum\order\PayType as OrderPayTypeEnum;
+use app\common\enum\order\OrderStatus as OrderStatusEnum;
+use app\common\enum\order\OrderSource as OrderSourceEnum;
+use app\common\enum\order\DeliveryType as DeliveryTypeEnum;
+use app\common\service\BaseService;
+use app\common\service\card\UserRiceCard as UserRiceCardService;
+use app\common\service\commission\RecordWaitCommission;
+use app\common\service\delivery\Express as ExpressService;
+use app\common\service\goods\source\Factory as StockFactory;
+use app\common\library\helper;
+use app\common\exception\BaseException;
+use app\common\enum\order\PayStatus as PayStatusEnum;
+use app\common\model\ShopGoodsSku;
+use app\common\model\User;
+
+/**
+ * 订单结算台服务类
+ * Class Checkout
+ * @package app\api\service\order
+ */
+class CheckoutExchange extends BaseService
+{
+    /* $model OrderModel 订单模型 */
+    public $model;
+
+    /* @var UserModel $user 当前用户信息 */
+    private $user;
+
+    // 订单结算商品列表
+    private $goodsList = [];
+    private $invalidGoodsList = [];
+    private $shopInfo = [];
+
+    // 错误信息
+    protected $error;
+
+    // 错误信息状态
+    protected $errorStatus;
+
+    /**
+     * 订单结算api参数
+     * @var array
+     */
+    private $param = [
+        'delivery' => DeliveryTypeEnum::EXPRESS, // 配送方式 默认:快递配送
+        'couponId' => 0,    // 优惠券id
+        'riceCardId' => 0,    // 现金米卡id
+        'isUsePoints' => 0,    // 是否使用积分抵扣
+        'isUseGoldRice' => 0,    // 默认使用金米粒
+        'remark' => '',    // 买家留言
+        'payType' => OrderPayTypeEnum::EXCHANGE,  // 支付方式
+        'addressId' => 0,  //地址ID
+        'staffUserId' => 0,  //分享链接用户ID
+    ];
+
+    /**
+     * 订单结算的规则
+     * @var array
+     */
+    private $checkoutRule = [
+        'isUserGrade' => false,    // 会员等级折扣
+        'isCoupon' => false,        // 优惠券抵扣
+        'isRiceCard' => false,        // 现金米卡抵扣
+        'isUsePoints' => false,        // 是否使用积分抵扣
+    ];
+
+    /**
+     * 订单来源
+     * @var array
+     */
+    private $orderSource = [
+        'source' => OrderSourceEnum::MASTER,
+        'source_id' => 0,
+    ];
+
+    /**
+     * 订单结算数据
+     * @var array
+     */
+    private $orderData = [];
+
+    /**
+     * 构造函数
+     * Checkout constructor.
+     * @throws BaseException
+     */
+    public function __construct()
+    {
+        parent::__construct();
+        $this->user = UserService::getCurrentLoginUser(true);
+        $this->model = new OrderModel;
+        $this->storeId = $this->getStoreId();
+    }
+
+    /**
+     * 设置结算台请求的参数
+     * @param $param
+     * @return array
+     */
+    public function setParam($param)
+    {
+        $this->param = array_merge($this->param, $param);
+        return $this->getParam();
+    }
+
+    /**
+     * 获取结算台请求的参数
+     * @return array
+     */
+    public function getParam()
+    {
+        return $this->param;
+    }
+
+    /**
+     * 订单结算的规则
+     * @param $data
+     * @return $this
+     */
+    public function setCheckoutRule($data)
+    {
+        $this->checkoutRule = array_merge($this->checkoutRule, $data);
+        return $this;
+    }
+
+    /**
+     * 设置订单来源(普通订单)
+     * @param $data
+     * @return $this
+     */
+    public function setOrderSource($data)
+    {
+        $this->orderSource = array_merge($this->orderSource, $data);
+        return $this;
+    }
+
+    /**
+     * 订单确认-结算台
+     * @param $goodsList
+     * @return array
+     * @throws BaseException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function onCheckout($goodsList)
+    {
+        // 订单确认-立即购买
+        $this->goodsList = $goodsList;
+        return $this->checkout();
+    }
+    //积分兑换商品
+    public function onCheckoutExchange($goodsList)
+    {
+        $this->goodsList = $goodsList;
+        $this->orderData = $this->getOrderData();
+        $this->validateGoodsList();
+        $this->orderData['distributorTotalMoney'] = 0;
+        $this->orderData['activityDiscountTotalPrice'] = 0;
+        $this->orderData['memberTotalMoney'] = 0;
+
+        // 设置订单商品总金额(不含优惠折扣,不含会员折扣,不含金米粒抵扣,不含专属优惠)
+        $this->setOrderTotalPrice();
+
+        // 计算优惠券抵扣
+        $this->setOrderCouponMoney([], (int)$this->param['couponId']);
+
+        //订单总运费金额
+        $this->setOrderExpress();
+
+        //金米粒抵扣-V1.4.0版本添加2022年6月1日,运费不能抵扣金米粒
+        $this->setOrderGolRiceAmount();
+        //金米粒获取-V1.4.0版本添加2022年6月7日,运费不获取金米粒
+        $this->setOrderInputGolRiceAmount();
+
+        $this->setOrderRiceCardMoney([],-1);
+
+        // 计算订单最终金额+运费
+        $this->setOrderPayPrice();
+
+        //设置满件送活动是否有赠送商品--一定要放在满就送后面来处理,不然会报错
+        $this->setMjGoodsList();
+
+        // 订单商品总数量
+        $orderTotalNum = helper::getArrayColumnSum($this->goodsList, 'total_num') + helper::getArrayColumnSum($this->invalidGoodsList, 'total_num');
+
+        return array_merge([
+            'goodsList' => $this->goodsList,   // 商品信息
+            'invalidGoodsList' => $this->invalidGoodsList, // 无效商品信息(门店无库存)
+            'shopInfo' => $this->shopInfo, // 门店信息
+            'isPickup' => false, // 是否支持门店自提 true-支持 false-不支持
+            'orderTotalNum' => $orderTotalNum,        // 商品总数量
+//            'couponList' => array_values($couponList), // 优惠券列表
+            'hasError' => $this->hasError(),
+            'errorMsg' => $this->getError(),
+            'errorStatus' => $this->getErrorStatus(),
+        ], $this->orderData);
+    }
+
+    /**
+     * 订单结算台
+     * @return array
+     * @throws BaseException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function checkout()
+    {
+        // 整理订单数据
+        $this->orderData = $this->getOrderData();
+
+        // 门店自提处理
+        $this->setShopPickupData();
+        // 验证商品状态, 是否允许购买
+        $this->validateGoodsList();
+        // 设置订单商品会员折扣价
+        $this->setOrderGoodsGradeMoney();
+        //活动使用排序:N件X折活动 > 会员折扣 > 优惠券 > 推荐官专属折扣 > 金米粒抵扣 > 满就赠 > 全场满件送 > 满件送
+
+        //设置N件X折活动优惠-v1.3.6版本添加2022年3月11日
+        $this->setActivityDiscountMoney();
+        // 设置订单商品总金额(不含优惠折扣,不含会员折扣,不含金米粒抵扣,不含专属优惠)
+        $this->setOrderTotalPrice();
+        //会员折扣-V1.4.0版本添加2022年6月1日
+        $this->setOrderGoodsMemberMoney();
+
+        // 当前用户可用的优惠券列表
+//        $couponList = $this->getUserCouponList((float)$this->orderData['orderTotalPrice']);
+        $couponList = $this->getUserCouponList();
+        // 计算优惠券抵扣
+        $this->setOrderCouponMoney($couponList, (int)$this->param['couponId']);
+        //设置分销员购物或分享后用户购买的折扣价-V1.2.2.2版本添加2021年11月18日
+        $this->setOrderGoodsDistributorMoney();
+        // 计算可用积分抵扣
+        $this->setOrderPoints();
+        //订单总运费金额
+        $this->setOrderExpress();
+
+        //金米粒抵扣-V1.4.0版本添加2022年6月1日,运费不能抵扣金米粒
+        $this->setOrderGolRiceAmount();
+        //金米粒获取-V1.4.0版本添加2022年6月7日,运费不获取金米粒
+        $this->setOrderInputGolRiceAmount();
+        //获取当前可用的现金卡列表
+        $userRiceCardList = $this->getUserRiceCardList();
+        //计算使用米卡现金券抵扣后的金额-start
+        $this->setOrderRiceCardMoney($userRiceCardList,(int)$this->param['riceCardId']);
+        //计算使用米卡现金券抵扣后的金额-end
+
+        // 计算订单商品的实际付款金额
+        $this->setOrderGoodsPayPrice();
+        // 计算订单最终金额+运费
+        $this->setOrderPayPrice();
+        // 计算订单积分赠送数量
+        $this->setOrderPointsBonus();
+        //订单商品的所有店铺集合2021年9月28日 10:56:45
+        $this->setOrderProviderIds();
+
+        // 无效商品信息处理
+        $this->setInvalidGoods();
+        
+        // 订单商品总数量
+        $orderTotalNum = helper::getArrayColumnSum($this->goodsList, 'total_num') + helper::getArrayColumnSum($this->invalidGoodsList, 'total_num');
+
+        //设置满就送活动是否有赠送商品--一定要放在所有优惠后面最后面来处理,不然会报错
+        $this->setFullGoodsList();
+
+        //设置全场满件送活动是否有赠送商品--一定要放在满就送后面来处理,不然会报错
+        $this->setQcMjGoodsList();
+
+        //设置满件送活动是否有赠送商品--一定要放在满就送后面来处理,不然会报错
+        $this->setMjGoodsList();
+
+        // 验证商品状态, 是否允许购买
+//        $this->validateGoodsList();
+        // 返回订单数据
+        return array_merge([
+            'goodsList' => $this->goodsList,   // 商品信息
+            'invalidGoodsList' => $this->invalidGoodsList, // 无效商品信息(门店无库存)
+            'shopInfo' => $this->shopInfo, // 门店信息
+            'isPickup' => $this->isPickup, // 是否支持门店自提 true-支持 false-不支持
+            'orderTotalNum' => $orderTotalNum,        // 商品总数量
+//            'couponList' => array_values($couponList), // 优惠券列表
+            'hasError' => $this->hasError(),
+            'errorMsg' => $this->getError(),
+            'errorStatus' => $this->getErrorStatus(),
+        ], $this->orderData);
+    }
+
+    /**
+     * 设置N件X折活动优惠设置
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author: zjwhust
+     * @Time: 2022/3/11 11:28
+     */
+    public function setActivityDiscountMoney(){
+        // 设置默认数据:订单信息
+        helper::setDataAttribute($this->orderData, [
+            'activityDiscountList' => [],       // N件X折优惠列表
+            'activityDiscountTotalPrice' => 0.00,       // N件X折优惠总金额
+        ], false);
+        // 设置默认数据
+        helper::setDataAttribute($this->goodsList, [
+            // 是否参与N件X折活动 0否 1是
+            'is_activity_discount' => 0,
+            // N件X折活动ID
+            'activity_discount_id' => 0,
+            // N件X折活动折扣金额
+            'activity_discount_total_price' => 0.00,//N件活动折扣金额
+            // N件X折活动描述
+            'activity_discount_desc' => '',
+            // N件X折活动叠加优惠 1-优惠券 2-满就送 3-满件送 多个以逗号分隔
+            'activity_discount_overlay' => '',
+            'activity_discount_count' => '',//数量
+        ], true);
+        $i = 0;
+        foreach ($this->goodsList as $item){
+            (new GoodsModel)->getActivityDiscountDetail($item,2);
+            if($item['is_activity_discount']){
+                $this->orderData['activityDiscountList'][$i]['goods_id'] = $item['goods_id'];
+                $this->orderData['activityDiscountList'][$i]['goods_image'] = $item['goods_image'];
+                $this->orderData['activityDiscountList'][$i]['activity_discount_total_price'] = $item['activity_discount_total_price'];
+                $this->orderData['activityDiscountList'][$i]['activity_discount_desc'] = $item['activity_discount_desc'];
+                $this->orderData['activityDiscountList'][$i]['total_price'] = $item['total_price'];
+                $i++;
+                $this->orderData['activityDiscountTotalPrice'] += $item['activity_discount_total_price'];
+            }
+        }
+        $this->orderData['activityDiscountTotalPrice'] = helper::number2($this->orderData['activityDiscountTotalPrice']);//设置订单优惠合计
+    }
+    /**
+     * 判断满就送商品是否需要添加
+     */
+    public function setFullGoodsList()
+    {
+        $isFull = FullSendActivity::validActivityList($this->goodsList,$this->orderData);
+    }
+    /**
+     * 判断全场满件送商品是否需要添加
+     */
+    public function setQcMjGoodsList()
+    {
+        $isMj = QcMjSendActivity::validActivityList($this->goodsList,$this->orderData);
+        if($isMj){
+            foreach ($this->goodsList as $good){
+                foreach ($isMj as $key=>$num){
+                    if($num>0 && $good['goods_id']==$key && ($good['total_num']+$num)>$good['skuInfo']['stock_num']){
+//                        dd($good['total_num']+$num-$good['skuInfo']['stock_num']);
+                        $this->setError("很抱歉,赠品 [".limit_str((string)$good['goods_name'])."] 库存不足");
+                        $this->setErrorStatus(424);
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 判断满件送商品是否需要添加
+     */
+    public function setMjGoodsList()
+    {
+        $isMj = MjSendActivity::validActivityList($this->goodsList,$this->orderData);
+//        dd($isMj);
+        if($isMj){
+            foreach ($this->goodsList as $good){
+                foreach ($isMj as $key=>$num){
+                    if($num>0 && $good['goods_id']==$key && ($good['total_num']+$num)>$good['skuInfo']['stock_num']){
+//                        dd($good['total_num']+$num-$good['skuInfo']['stock_num']);
+                        $this->setError("很抱歉,赠品 [".limit_str((string)$good['goods_name'])."] 库存不足");
+                        $this->setErrorStatus(424);
+                    }
+                }
+            }
+        }
+//        return $status;
+    }
+
+    /**
+     * 门店自提处理
+     */
+    public function setShopPickupData() {
+        $deliveryType = $this->param['delivery'];
+        // 返回商品处理
+        $normalGoodsList = []; // 正常状态商品
+        $invalidGoodsList = []; // 无货状态商品
+        // 门店信息
+        $userStaff = User::detail($this->param['staffUserId']);
+        $shopInfo = [];
+        $isPickup = false;
+        if (!empty($userStaff) && $userStaff['role'] == User::SHOP_SELLER) {
+            $shopInfo = Shops::find($userStaff['shop_id']);
+            if ($shopInfo['is_pickup']) {
+                $isPickup = true;
+            }
+        }
+        if ($deliveryType == DeliveryTypeEnum::SHOPS_DELIVERY) {
+            if (empty($shopInfo)) {
+                // 门店自提方式 且门店不存在
+                throwError("不支持门店自提方式");
+            }
+            if (!$shopInfo['is_pickup']) {
+                // 门店自提开关
+                throwError("不支持门店自提方式");
+            }
+        }
+        
+        // 门店库存总和
+        $shopStockTotal = 0;
+        foreach($this->goodsList as &$item) {
+            // 获取商品门店库存
+            if ($shopInfo) {
+                $shopGoodsSku = ShopGoodsSku::with('shopGoods')->where(['shop_id' => $shopInfo['shop_id'], 'goods_id' => $item['goods_id'], 'goods_sku_id' => $item['goods_sku_id']])->find();
+                if (!empty($shopGoodsSku) && $shopGoodsSku['stock_num'] > 0) {
+                    $shopStockTotal += $shopGoodsSku['stock_num'];
+                }
+            }
+
+            // 判断配送方式
+            if ($deliveryType == DeliveryTypeEnum::EXPRESS) { // 快递配送
+                $normalGoodsList[] = $item;
+                // 判断库存 todo 购买数量大于实际库存 取实际库存
+                // 有库存
+                if ($item['skuInfo']['stock_num'] >= $item['total_num']) {
+                    $item['stock_enough'] = true;
+                } else {
+                    $item['stock_enough'] = false;
+                    $item['total_num'] = $item['skuInfo']['stock_num']; // 库存不够时,取最大库存
+                    $item['total_price'] = helper::bcmul($item['goods_price'], $item['total_num']);
+                }
+                $item['is_pickup_invalid'] = false;
+            } elseif ($deliveryType == DeliveryTypeEnum::SHOPS_DELIVERY) { // 门店自提
+                // 判断有无库存
+                if (!empty($shopGoodsSku)) {
+                    $item['stock_total'] = $shopGoodsSku['shopGoods']['stock_total'];
+                    $item['alarm_stock_total'] = $shopGoodsSku['shopGoods']['alarm_stock_total'];
+                    $item['skuInfo']['stock_num'] = $shopGoodsSku['stock_num'];
+                    $item['skuInfo']['alarm_stock_num'] = $shopGoodsSku['alarm_stock_num'];
+
+                    if ($shopGoodsSku['stock_num'] > 0) {
+                        // 有库存
+                        if ($shopGoodsSku['stock_num'] >= $item['total_num']) {
+                            $item['stock_enough'] = true;
+                        } else {
+                            $item['stock_enough'] = false;
+                            $item['total_num'] = $shopGoodsSku['stock_num']; // 库存不够时,取最大库存
+                            $item['total_price'] = helper::bcmul($item['goods_price'], $item['total_num']);
+                        }
+                        $normalGoodsList[] = $item;
+                    } else {
+                        // 没有库存
+                        $item['stock_enough'] = false;
+                        $item['is_pickup_invalid'] = true;
+                        $invalidGoodsList[] = $item;
+                    }
+                } else {
+                    // 无库存
+                    // $item['stock_total'] = 0;
+                    // $item['alarm_stock_total'] = 0;
+                    // $item['skuInfo']['stock_num'] = 0;
+                    // $item['skuInfo']['alarm_stock_num'] = 0;
+                    $item['stock_enough'] = false;
+                    // $item['total_num'] = 0; // 无门店库存
+                    // $item['total_price'] = 0;
+                    $item['is_pickup_invalid'] = true;
+                    $invalidGoodsList[] = $item;
+                }
+            }
+        }
+        if ($shopStockTotal <= 0) { // 门店总库存不大于0
+            $isPickup = false;
+        }
+
+        $this->shopInfo = $shopInfo; // 门店信息
+        $this->isPickup = $isPickup; // 是否支持门店自提
+        $this->orderData['shopInfo'] = $shopInfo;
+        // $this->goodsList = $normalGoodsList;
+        // $this->invalidGoodsList = $invalidGoodsList;
+    }
+
+    /**
+     * 无效商品信息处理
+     */
+    public function setInvalidGoods() {
+        $normalGoodsList = []; // 正常状态商品
+        $invalidGoodsList = []; // 无货状态商品
+        foreach($this->goodsList as $item) {
+            if (!$item['is_pickup_invalid']) { // 快递配送
+                $normalGoodsList[] = $item;
+            } else {
+                $invalidGoodsList[] = $item;
+            }
+        }
+        $this->goodsList = $normalGoodsList;
+        $this->invalidGoodsList = $invalidGoodsList;
+    }
+
+    //我的可用现金卡
+    public function getUserRiceCardList(){
+        $user = UserService::getCurrentLoginUser(true);
+        $list = UserRiceCardModel::getUserRiceCardList($user['user_id'])->toArray();
+        $data = [];
+        foreach ($list as $key=>&$item){
+            $i = 0;
+            $exceptGoodsId = helper::getArrayColumn($item['riceCardGoodsExcept'],'goods_id');
+            foreach ($this->goodsList as $good) {
+                if(!empty($item['dk_cat_ids']) && strpos((string)$item['dk_cat_ids'],(string)$good['category']['category_id']) === false){
+                    unset($list[$key]);
+                    $i = 1;
+                }
+                if(!empty($exceptGoodsId) && in_array($good['goods_id'],$exceptGoodsId)){
+                    unset($list[$key]);
+                    $i = 1;
+                }
+            }
+            if(!$i){
+                unset($item['riceCardGoodsExcept']);
+                $data[$item['id']] = $item;
+            }
+        }
+        if($this->param['riceCardId']==0){ //-1表示不使用米卡
+            $this->param['riceCardId'] = key($data)??0;//若果没有选择米卡,默认使用第一张
+        }
+        return $data;
+    }
+
+    /**
+     * 计算订单可用积分抵扣
+     * @return bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function setOrderPoints()
+    {
+        // 设置默认的商品积分抵扣信息
+        $this->setDefaultGoodsPoints();
+        // 积分设置
+        $setting = SettingModel::getItem('points');
+        // 条件:后台开启下单使用积分抵扣
+        if (!$setting['is_shopping_discount'] || !$this->checkoutRule['isUsePoints']) {
+            return false;
+        }
+        // 条件:订单金额满足[?]元
+        if (helper::bccomp($setting['discount']['full_order_price'], $this->orderData['orderTotalPrice']) === 1) {
+            return false;
+        }
+        // 计算订单商品最多可抵扣的积分数量
+        $this->setOrderGoodsMaxPointsNum();
+        // 订单最多可抵扣的积分总数量
+        $maxPointsNumCount = helper::getArrayColumnSum($this->goodsList, 'max_points_num');
+        // 实际可抵扣的积分数量
+        $actualPointsNum = min($maxPointsNumCount, $this->user['points']);
+        if ($actualPointsNum < 1) {
+            return false;
+        }
+        // 计算订单商品实际抵扣的积分数量和金额
+        $GoodsDeduct = new PointsDeductService($this->goodsList);
+        $GoodsDeduct->setGoodsPoints($maxPointsNumCount, $actualPointsNum);
+        // 积分抵扣总金额
+        $orderPointsMoney = helper::getArrayColumnSum($this->goodsList, 'points_money');
+        $this->orderData['pointsMoney'] = helper::number2($orderPointsMoney);
+        // 积分抵扣总数量
+        $this->orderData['pointsNum'] = $actualPointsNum;
+        // 允许积分抵扣
+        $this->orderData['isAllowPoints'] = true;
+        return true;
+    }
+
+    /**
+     * 计算订单商品最多可抵扣的积分数量
+     * @return bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function setOrderGoodsMaxPointsNum()
+    {
+        // 积分设置
+        $setting = SettingModel::getItem('points');
+        foreach ($this->goodsList as &$goods) {
+            // 商品不允许积分抵扣
+            if (!$goods['is_points_discount']) continue;
+            // 积分抵扣比例
+            $deductionRatio = helper::bcdiv($setting['discount']['max_money_ratio'], 100);
+            // 最多可抵扣的金额
+            $totalPayPrice = helper::bcsub($goods['total_price'], $goods['coupon_money']);
+            $maxPointsMoney = helper::bcmul($totalPayPrice, $deductionRatio);
+            // 最多可抵扣的积分数量
+            $goods['max_points_num'] = helper::bcdiv($maxPointsMoney, $setting['discount']['discount_ratio'], 0);
+        }
+        return true;
+    }
+
+    /**
+     * 设置默认的商品积分抵扣信息
+     * @return bool
+     */
+    private function setDefaultGoodsPoints()
+    {
+        foreach ($this->goodsList as &$goods) {
+            // 最多可抵扣的积分数量
+            $goods['max_points_num'] = 0;
+            // 实际抵扣的积分数量
+            $goods['pointsNum'] = 0;
+            // 实际抵扣的金额
+            $goods['points_money'] = 0.00;
+        }
+        return true;
+    }
+
+    /**
+     * 整理订单数据(结算台初始化)
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function getOrderData()
+    {
+        // 系统支持的配送方式 (后台设置)
+        $deliveryType = SettingModel::getItem(SettingEnum::DELIVERY)['delivery_type'];
+        return [
+            // 当前配送类型
+            'delivery' => $this->param['delivery'] > 0 ? $this->param['delivery'] : $deliveryType[0],
+            // 默认地址
+            'address' => '',
+            // 是否存在收货地址
+            'existAddress' => $this->user['address_id'] > 0,
+            // 配送费用
+            'expressPrice' => 0.00,
+            //是否使用了金米粒
+            'isUseGoldRice' => $this->param['isUseGoldRice'],
+            //金米粒数量
+            'userGoldRiceNum' => $this->user['gold_rice']??0,
+            // 当前用户收货城市是否存在配送规则中
+            'isIntraRegion' => true,
+            // 是否允许使用积分抵扣
+            'isAllowPoints' => false,
+            // 是否使用积分抵扣
+            'isUsePoints' => $this->param['isUsePoints'],
+            // 积分抵扣金额
+            'pointsMoney' => 0.00,
+            // 赠送的积分数量
+            'pointsBonus' => 0,
+            // 支付方式
+            'payType' => $this->param['payType'],
+            // 系统设置
+            'setting' => $this->getSetting(),
+            // 推广监控ID
+            "promotionMonitorId" => $this->param['promotionMonitorId'] ?? 0
+        ];
+    }
+
+    /**
+     * 获取订单页面中使用到的系统设置
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function getSetting()
+    {
+        // 系统支持的配送方式 (后台设置)
+        $deliveryType = SettingModel::getItem(SettingEnum::DELIVERY)['delivery_type'];
+        // 积分设置
+        $pointsSetting = SettingModel::getItem(SettingEnum::POINTS);
+        return [
+            'deliveryType' => $deliveryType,                     // 支持的配送方式
+            'points_name' => $pointsSetting['points_name'],      // 积分名称
+            'points_describe' => $pointsSetting['describe'],     // 积分说明
+        ];
+    }
+
+    /**
+     * 当前用户可用的优惠券列表
+     * @param $goodsList 确认订单商品列表
+     * @return array|mixed
+     * @throws \think\db\exception\DbException
+     */
+    private function getUserCouponList()
+    {
+        // 是否开启优惠券折扣
+        if (!$this->checkoutRule['isCoupon']) {
+            return [];
+        }
+        // 整理当前订单所有商品ID集
+        $orderGoodsIds = helper::getArrayColumn($this->goodsList, 'goods_id');
+        // 当前用户可用的优惠券列表(筛选了除外商品)
+//        if($orderTotalPrice<=0){
+//            $couponList = [];
+//        }else{
+            $couponList = UserCouponModel::getUserCouponList($this->user['user_id'], $this->goodsList, $orderGoodsIds);
+//        }
+//        // 判断当前优惠券是否满足订单使用条件 (优惠券适用范围)
+//        $couponList = UserCouponModel::couponListApplyRange($couponList, $orderGoodsIds);
+        if($this->param['couponId']==0){//-1不使用优惠券
+            $this->param['couponId'] = key($couponList)??0;//若果没有选择优惠券,默认使用第一张优惠券
+        }
+        return $couponList;
+
+    }
+
+    /**
+     * 验证订单商品的状态
+     * @return bool
+     */
+    private function validateGoodsList()
+    {
+        $Checkout = CheckoutFactory::getFactory(
+            $this->user,
+            $this->goodsList,
+            $this->orderData['delivery'],
+            $this->shopInfo['shop_id'] ?? 0,
+            $this->orderSource['source']
+        );
+        $status = $Checkout->validateGoodsList();
+        if(!$status){
+            $this->setError($Checkout->getError());
+            $this->setErrorStatus(422);
+        }
+        return $status;
+    }
+
+    /**
+     * 设置订单的商品总金额(不含优惠折扣)
+     */
+    private function setOrderTotalPrice()
+    {
+        // 订单商品的总金额(不含优惠券折扣,不含N件X折优惠券)
+        $this->orderData['orderTotalPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'total_price'));
+    }
+
+    /**
+     * 订单商品的所有店铺集合
+     */
+    private function setOrderProviderIds()
+    {
+        // 订单商品的所有店铺集合
+        $this->orderData['orderProviderIds'] = implode(',',array_values(array_unique(helper::getArrayColumn($this->goodsList, 'provider_id'))));
+    }
+
+    /**
+     * 设置订单的实际支付金额(含配送费)
+     */
+    private function setOrderPayPrice()
+    {
+        // 订单金额(含优惠折扣)
+        //(商品总价 - N件X折 - 优惠券 - 分销员)+ 运费 = 微信支付+米卡抵扣+米卡抵扣运费
+        //(total_price-coupon_money-distrbutor_total_money)+express_price = pay_price+rice_card_money+rice_card_express_money
+        $this->orderData['orderPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'total_pay_price'));
+        // 订单实付款金额(订单金额 + 运费 - 现金卡运费抵扣金额)
+        $this->orderData['orderPayPrice'] = helper::number2(helper::bcadd($this->orderData['orderPrice'], $this->orderData['expressPrice']-$this->orderData['riceCardExpressMoney']));
+    }
+
+    /**
+     * 计算订单积分赠送数量
+     * @return bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function setOrderPointsBonus()
+    {
+        // 初始化商品积分赠送数量
+        foreach ($this->goodsList as &$goods) {
+            $goods['points_bonus'] = 0;
+        }
+        // 积分设置
+        $setting = SettingModel::getItem('points');
+        // 条件:后台开启开启购物送积分
+        if (!$setting['is_shopping_gift']) {
+            return false;
+        }
+        // 设置商品积分赠送数量
+        foreach ($this->goodsList as &$goods) {
+            // 积分赠送比例
+            $ratio = $setting['gift_ratio'] / 100;
+            // 计算抵扣积分数量
+            $goods['points_bonus'] = !$goods['is_points_gift'] ? 0 : helper::bcmul($goods['total_pay_price'], $ratio, 0);
+        }
+        //  订单积分赠送数量
+        $this->orderData['pointsBonus'] = helper::getArrayColumnSum($this->goodsList, 'points_bonus');
+        return true;
+    }
+
+    /**
+     * 设置金稻会员折扣价
+     * @return bool
+     */
+    private function setOrderGoodsMemberMoney()
+    {
+        // 设置默认数据
+        helper::setDataAttribute($this->goodsList, [
+            // 标记金稻会员是否参与购物折扣
+            'is_user_member' => false,
+            // 金稻会员购物抵扣的比例
+            'member_radio' => 0,
+            // 金稻会员购物减去的折扣优惠总额差
+            'member_total_money' => 0.00,
+        ], true);
+        // 设置默认数据:订单信息
+        helper::setDataAttribute($this->orderData, [
+            'memberTotalMoney' => 0,       // 抵扣金额
+            'isUserMember' => false,       // 是否有商品使用了会员折扣
+        ], false);
+        //如果不是会员,或者会员已过期
+        if($this->user['member_expire_time']<time()){
+            return false;
+        }
+
+        $member_total_money = 0;
+        // 计算抵扣金额
+        foreach ($this->goodsList as &$goods) {
+            //判断当前商品是否能使用会员折扣
+            $memberGoods = MemberGoods::where('goods_id',$goods['goods_id'])->where('status',0)->find();
+            if ($memberGoods && $memberGoods['discount']<100) {
+                $memberRatio = helper::bcdiv(100-$memberGoods['discount'], 100);//换算成百分比
+                helper::setDataAttribute($goods, [
+                    'is_user_member' => true,
+                    'member_radio' => $memberRatio,
+                    'member_total_money' => helper::number2(helper::bcmul(($goods['total_price']-$goods['activity_discount_total_price']), $memberRatio)),
+//                    'total_price' => $gradeTotalPrice,
+                ], false);
+                $this->orderData['isUserMember'] = true;
+            }
+            $member_total_money += $goods['member_total_money'];
+        }
+        $this->orderData['memberTotalMoney'] = helper::number2($member_total_money);//设置订单优惠合计
+        return true;
+    }
+
+    /**
+     * 计算订单商品的实际付款金额
+     * @return bool
+     */
+    private function setOrderGoodsPayPrice()
+    {
+        // 商品总价 - 优惠抵扣
+        foreach ($this->goodsList as &$goods) {
+            //减去金稻会员抵扣的金额
+            $value = helper::bcsub($goods['total_price'], $goods['member_total_money']);
+            // 减去N件X折抵扣金额
+            $value = helper::bcsub($value, $goods['activity_discount_total_price']);
+            //减去分销员购物的优惠金额
+            $value = helper::bcsub($value, $goods['distributor_total_money']);
+            // 减去优惠券抵扣金额
+            $value = helper::bcsub($value, $goods['coupon_money']);
+            // 减去积分抵扣金额
+            if ($this->orderData['isAllowPoints'] && $this->orderData['isUsePoints']) {
+                $value = helper::bcsub($value, $goods['points_money']);
+            }
+            //减去金米粒抵扣的金额
+            $value = helper::bcsub($value, $goods['gold_rice_money']);
+            $goods['totalPayPrice'] = helper::number2($value);
+            //减去现金米卡抵扣的金额
+            $value = helper::bcsub($value, $goods['rice_card_money']);
+            $goods['total_pay_price'] = helper::number2($value);
+        }
+        return true;
+    }
+
+    /**
+     * 设置订单商品会员折扣价
+     * @return bool
+     */
+    private function setOrderGoodsGradeMoney()
+    {
+        // 设置默认数据
+        helper::setDataAttribute($this->goodsList, [
+            // 标记参与会员折扣
+            'is_user_grade' => false,
+            // 会员等级抵扣的金额
+            'grade_ratio' => 0,
+            // 会员折扣的商品单价
+            'grade_goods_price' => 0.00,
+            // 会员折扣的总额差
+            'grade_total_money' => 0.00,
+        ], true);
+
+        // 是否开启会员等级折扣
+        if (!$this->checkoutRule['isUserGrade']) {
+            return false;
+        }
+        // 会员等级状态
+        if (!(
+            $this->user['grade_id'] > 0 && !empty($this->user['grade'])
+            && !$this->user['grade']['is_delete'] && $this->user['grade']['status']
+        )) {
+            return false;
+        }
+        // 计算抵扣金额
+        foreach ($this->goodsList as &$goods) {
+            // 判断商品是否参与会员折扣
+            if (!$goods['is_enable_grade']) {
+                continue;
+            }
+            // 商品单独设置了会员折扣
+            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);
+            }
+            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);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 设置分销员购物折扣价
+     * @return bool
+     */
+    private function setOrderGoodsDistributorMoney()
+    {
+        // 设置默认数据
+        helper::setDataAttribute($this->goodsList, [
+            // 标记参与顾客购物折扣
+            'is_user_distributor' => false,
+            // 顾客购物抵扣的比例
+            'distributor_radio' => 0,
+            // 顾客购物减去的折扣优惠价格
+            'distributor_goods_price' => 0.00,
+            // 顾客购物减去的折扣优惠总额差
+            'distributor_total_money' => 0.00,
+        ], true);
+        // 设置默认数据:订单信息
+        helper::setDataAttribute($this->orderData, [
+            'distributorTotalMoney' => 0,       // 优惠券抵扣金额
+            'isUserDistributor' => false,       // 是否有商品使用了推荐官专属折扣
+        ], false);
+
+        //使用了优惠券并且优惠券没有勾选使用分销员优惠
+        if($this->orderData['couponId']>0 && stripos($this->orderData['couponOverlayDiscount'],'1') === false){
+            return true;
+        }
+
+        $distributor_total_money = 0;
+        // 计算抵扣金额
+        foreach ($this->goodsList as &$goods) {
+            $discountRatio = helper::bcdiv($goods['distributorRadio'], 100);//换算成百分比
+            if ($discountRatio > 0) {
+                // 顾客购物折扣的优惠价格
+//                $gradeTotalPrice = max(0.01, helper::bcmul($goods['total_price'], (1-$discountRatio)));
+                helper::setDataAttribute($goods, [
+                    'is_user_distributor' => true,
+                    'distributor_radio' => $discountRatio,
+                    'distributor_goods_price' => $goods['total_num']>0 ? helper::number2(helper::bcmul($goods['goods_price']-($goods['coupon_money']+$goods['activity_discount_total_price']+$goods['member_total_money'])/$goods['total_num'], $discountRatio), true):0,
+                    'distributor_total_money' => helper::number2(helper::bcmul(($goods['total_price']-$goods['coupon_money']-$goods['activity_discount_total_price']-$goods['member_total_money']), $discountRatio)),
+//                    'total_price' => $gradeTotalPrice,
+                ], false);
+                $this->orderData['isUserDistributor'] = true;
+            }
+            $distributor_total_money += $goods['distributor_total_money'];
+        }
+        $this->orderData['distributorTotalMoney'] = helper::number2($distributor_total_money);//设置订单优惠合计
+        return true;
+    }
+
+    /**
+     * 设置订单优惠券抵扣信息
+     * @param array $couponList 当前用户可用的优惠券列表
+     * @param int $couponId 当前选择的优惠券id
+     * @return bool
+     * @throws BaseException
+     */
+    private function setOrderCouponMoney(array $couponList, int $couponId)
+    {
+        // 设置默认数据:订单信息
+        helper::setDataAttribute($this->orderData, [
+            'couponId' => $couponId,       // 用户优惠券id
+            'couponMoney' => 0,    // 优惠券抵扣金额
+            'couponName' => '',    // 优惠券抵扣名称
+            'couponOverlayDiscount' => '',    // 叠加字段
+            'couponList' => [],
+        ], false);
+        // 设置默认数据:订单商品列表
+        helper::setDataAttribute($this->goodsList, [
+            'coupon_money' => 0,    // 优惠券抵扣金额
+            'coupon_id' => 0,    // 优惠券ID
+        ], true);
+        if($couponId<0){//如果米卡ID小于0表示不使用,但是也要返回可使用列表
+            $this->orderData['couponList'] = array_values($couponList);
+            return true;
+        }
+        // 验证选择的优惠券ID是否合法
+        if (!$this->verifyOrderCouponId($couponId, $couponList)) {
+            return false;
+        }
+        // 获取优惠券信息
+        $couponInfo = $this->getCouponInfo($couponId, $couponList);
+        // 整理当前订单所有商品ID集
+//        $orderGoodsIds = helper::getArrayColumn($this->goodsList, 'goods_id');
+        // 获取当前参与商品分佣的ID集
+//        $diffGoodsIds = array_diff($orderGoodsIds,$couponInfo['except_goods_id']);
+        $diffGoodsIds = $couponInfo['new_good_ids'];//在获取可用优惠券列表时就已经计算出哪些商品可以使用优惠券了
+        $goodsListTemp = [];
+        foreach ($this->goodsList as $key=> $good){
+            $goodsListTemp[$key]['total_price'] = helper::bcsub($good['total_price'],$good['activity_discount_total_price']+$good['member_total_money']);
+            if(!in_array($good['goods_id'],$diffGoodsIds)){
+                $goodsListTemp[$key]['total_price'] = 0;
+            }
+        }
+        $CouponMoney = new GoodsDeductService;
+        $completed = $CouponMoney->setGoodsCouponMoney($goodsListTemp, $couponInfo['reduced_price']);
+        // 分配订单商品优惠券抵扣金额
+        foreach ($this->goodsList as $key => &$goods) {
+            $goods['coupon_money'] = isset($completed[$key]['coupon_money']) ? $completed[$key]['coupon_money'] / 100 : 0;
+            $goods['coupon_id'] = $couponId;
+            if(!in_array($goods['goods_id'],$diffGoodsIds)){
+                $goods['coupon_id'] = 0;
+            }
+        }
+        // 记录订单优惠券信息
+        $this->orderData['couponId'] = $couponId;
+        $this->orderData['couponOverlayDiscount'] = $couponInfo['overlay_discount'];
+        $this->orderData['couponMoney'] = helper::number2($CouponMoney->getActualReducedMoney() / 100);
+        $this->orderData['couponName'] = $couponInfo['name'];
+        $this->orderData['couponList'] = array_values($couponList);
+        return true;
+    }
+
+    /**
+     * 设置订单使用金米粒抵扣信息
+     * @return bool
+     * @throws BaseException
+     */
+    private function setOrderGolRiceAmount()
+    {
+        // 设置默认数据:订单信息
+        helper::setDataAttribute($this->orderData, [
+            'goldRiceAmount' => 0,    // 金米粒抵扣总数量 1金米粒=0.01元
+            'goldRiceMoney' => 0.00,    // 金米粒抵扣总金额
+        ], false);
+        // 设置默认数据:订单商品列表
+        helper::setDataAttribute($this->goodsList, [
+            'gold_rice_amount' => 0,    // 金米粒抵扣数量
+            'gold_rice_money' => 0,    // 金米粒抵扣金额
+        ], true);
+
+        if($this->orderData['isUseGoldRice']<1){//没有使用金米粒
+            return false;
+        }
+        $orderTotalPrice = $this->orderData['orderTotalPrice']-$this->orderData['distributorTotalMoney']-$this->orderData['couponMoney']-$this->orderData['activityDiscountTotalPrice']-$this->orderData['memberTotalMoney']; //实际支付金额-N件X折活动优惠-分销员优惠-优惠券优惠-金稻会员优惠
+        // 如果没有可用的现金米卡,直接返回
+        $DeductionLimit = DeductionLimitModel::where('id','>',0)->find();
+        $score = helper::bcmul($orderTotalPrice,$DeductionLimit['discount'],0);
+        //不够起用数量
+        if($score<$DeductionLimit['score']){
+            $this->orderData['isUseGoldRice'] = -1;
+            return false;
+        }
+        //用户可用金米粒数量不够起用数量
+        if($this->user['gold_rice']<$DeductionLimit['score']){
+            $this->orderData['isUseGoldRice'] = -1;
+            return false;
+        }
+        if($score>$this->user['gold_rice']){
+            $score = $this->user['gold_rice'];
+        }
+        // 获取优惠券信息
+        $goodsListTemp = [];
+        foreach ($this->goodsList as $key=> $good){
+            $goodsListTemp[$key]['total_price'] = helper::bcsub($good['total_price'],$good['distributor_total_money']+$good['coupon_money']+$good['activity_discount_total_price']+$good['member_total_money']);
+        }
+        $RiceMoney = new RiceDeductService;
+        $gold_rice_money = helper::bcdiv($score,100);
+        $completed = $RiceMoney->setGoodsCouponMoney($goodsListTemp, $gold_rice_money);
+        // 分配订单商品抵扣的金米粒数量
+        foreach ($this->goodsList as $key => &$goods) {
+            $goods['gold_rice_amount'] = isset($completed[$key]['rice_card_money']) ? $completed[$key]['rice_card_money'] : 0;
+            $goods['gold_rice_money'] = helper::bcdiv($goods['gold_rice_amount'],100);
+        }
+        // 记录订单抵扣的金米粒数量
+        $this->orderData['goldRiceAmount'] = $score;
+        $this->orderData['goldRiceMoney'] = $gold_rice_money;
+        return true;
+    }
+
+    /**
+     * 设置订单使用金米粒获取信息
+     * @return bool
+     * @throws BaseException
+     */
+    private function setOrderInputGolRiceAmount()
+    {
+        // 设置默认数据:订单信息
+        helper::setDataAttribute($this->orderData, [
+            'goldRiceAmountInput' => 0,    // 金米粒获取总数量 累加商品金额
+        ], false);
+        // 设置默认数据:订单商品列表
+        helper::setDataAttribute($this->goodsList, [
+            'gold_rice_amount_input' => 0,    // 金米粒获取数量,1元可以获取1金米粒,只舍不入
+        ], true);
+        //如果不是会员,或者会员已过期
+        if($this->user['member_expire_time']<time()){
+            return false;
+        }
+        $score = 0;
+        // 分配订单商品获取的金米粒数量
+        foreach ($this->goodsList as $key => &$goods) {
+            //获取商品需要实付的金额
+            $good_total_price = helper::bcsub($goods['total_price'],$goods['distributor_total_money']+$goods['coupon_money']+$goods['activity_discount_total_price']+$goods['member_total_money']+$goods['gold_rice_money']);
+            $goods['gold_rice_amount_input'] = floor($good_total_price);//金米粒获取数量,1元可以获取1金米粒,只舍不入
+            $score += $goods['gold_rice_amount_input'];
+        }
+        // 记录订单获得的金米粒数量
+        $this->orderData['goldRiceAmountInput'] = $score;
+        return true;
+    }
+    /**
+     * 设置订单现金米卡抵扣信息
+     * @param int $riceCardId 可使用米卡列表
+     * @param int $riceCardId 当前选择的现金米卡id
+     * @return bool
+     * @throws BaseException
+     */
+    private function setOrderRiceCardMoney($userRiceCardList,int $riceCardId)
+    {
+        // 设置默认数据:订单信息
+        helper::setDataAttribute($this->orderData, [
+            'riceCardId' => $riceCardId,       // 用户现金米卡id
+            'riceCardMoney' => 0,    // 现金米卡抵扣总金额
+            'riceCardExpressMoney' => 0,    // 现金米卡抵扣运费
+            'userRiceCardList' => [],    // 米卡列表
+            'userRiceCard' => [],    // 已选择的米卡
+        ], false);
+        // 设置默认数据:订单商品列表
+        helper::setDataAttribute($this->goodsList, [
+            'rice_card_id' => 0,    // 用户现金米卡id
+            'rice_card_money' => 0,    // 金米卡抵扣金额
+        ], true);
+
+        if($riceCardId<0){//如果米卡ID小于0表示不使用,但是也要返回可使用列表
+            $this->orderData['userRiceCardList'] = array_values($userRiceCardList);
+            return true;
+        }
+        // 验证选择的优惠券ID是否合法
+        if (!$this->verifyUserRiceCard($riceCardId, $userRiceCardList)) {
+            return false;
+        }
+        // 获取优惠券信息
+        $riceCard = $this->getRiceCardInfo($riceCardId, $userRiceCardList);
+        $goodsListTemp = [];
+        foreach ($this->goodsList as $key=> $good){
+            $goodsListTemp[$key]['total_price'] = helper::bcsub($good['total_price'],$good['distributor_total_money']+$good['coupon_money']+$good['activity_discount_total_price']+$good['gold_rice_money']+$good['member_total_money']);
+        }
+        $RiceMoney = new RiceDeductService;
+        $completed = $RiceMoney->setGoodsCouponMoney($goodsListTemp, $riceCard['balance']);
+        // 分配订单商品优惠券抵扣金额
+        $rice_card_money = 0;
+        foreach ($this->goodsList as $key => &$goods) {
+            $goods['rice_card_money'] = isset($completed[$key]['rice_card_money']) ? $completed[$key]['rice_card_money'] / 100 : 0;
+            $goods['rice_card_id'] = $riceCardId;
+            $rice_card_money += $goods['rice_card_money'];
+        }
+        $orderTotalPrice = $this->orderData['orderTotalPrice']-$this->orderData['distributorTotalMoney']-$this->orderData['couponMoney']-$this->orderData['activityDiscountTotalPrice']-$this->orderData['goldRiceMoney']-$this->orderData['memberTotalMoney']; //实际支付金额-N件X折活动优惠-分销员优惠-优惠券优惠-金米粒抵扣金额
+        //有运费,并且现金米卡可用的金额大于商品总价
+        $rice_card_express_money = 0;
+        if($riceCard['balance']>$orderTotalPrice && $this->orderData['expressPrice']>0){
+            $residueMoney = $riceCard['balance']-$orderTotalPrice;
+            if($residueMoney-$this->orderData['expressPrice']>0){
+                $rice_card_express_money += $this->orderData['expressPrice'];
+            }else{
+                $rice_card_express_money += $residueMoney;
+            }
+        }
+        // 记录订单现金米卡信息
+        $this->orderData['userRiceCard'] = $userRiceCardList[$riceCardId];
+        $this->orderData['riceCardId'] = $riceCardId;
+        $this->orderData['riceCardMoney'] = helper::bcmul($rice_card_money+$rice_card_express_money,1);
+        $this->orderData['riceCardExpressMoney'] = helper::bcmul($rice_card_express_money,1);
+        $this->orderData['userRiceCardList'] = array_values($userRiceCardList);
+        return true;
+    }
+
+    /**
+     * 验证用户选择的现金米卡
+     * @param $riceCard
+     * @return bool
+     * @throws BaseException
+     */
+    private function verifyUserRiceCard($riceCardId,$userRiceCardList)
+    {
+        // 是否开启现金米卡抵扣
+        if (!$this->checkoutRule['isRiceCard']) {
+            return false;
+        }
+        // 如果没有可用的现金米卡,直接返回
+        if ($riceCardId <= 0) {
+            return false;
+        }
+
+        // 判断优惠券是否存在
+        $riceCard = $this->getRiceCardInfo($riceCardId, $userRiceCardList);
+        // 如果没有现金米卡,直接返回
+        if (empty($riceCard)) {
+            throwError('未找到米卡信息');
+        }
+
+//        $UserRiceCardService = new UserRiceCardService($this->goodsList);
+//        $isExceptGoods = $UserRiceCardService->isIncludeGoods($riceCard);
+//        if ($isExceptGoods == false) {
+//            $notExceptGoodsName = $UserRiceCardService->getExceptGoodsName();
+//            $this->setError("很抱歉,商品 [".limit_str((string)$notExceptGoodsName)."] 不可使用该米卡");
+//            $this->setErrorStatus(422);
+//        }else{
+//            $isExceptGoods = $UserRiceCardService->isExceptGoods($riceCard);
+//            if ($isExceptGoods == false) {
+//                $notExceptGoodsName = $UserRiceCardService->getExceptGoodsName();
+//                $this->setError("很抱歉,商品 [".limit_str((string)$notExceptGoodsName)."] 不可使用该米卡");
+//                $this->setErrorStatus(422);
+//            }
+//        }
+        return true;
+    }
+
+
+    /**
+     * 验证用户选择的优惠券ID是否合法
+     * @param $couponId
+     * @param $couponList
+     * @return bool
+     * @throws BaseException
+     */
+    private function verifyOrderCouponId($couponId, $couponList)
+    {
+        // 是否开启优惠券折扣
+        if (!$this->checkoutRule['isCoupon']) {
+            return false;
+        }
+        // 如果没有可用的优惠券,直接返回
+        if ($couponId <= 0 || empty($couponList)) {
+            return false;
+        }
+        // 判断优惠券是否存在
+        $couponInfo = $this->getCouponInfo($couponId, $couponList);
+        if (!$couponInfo) {
+//            throwError('未找到优惠券信息');
+            $this->param['couponId'] = key($couponList)??0;//若果没有选择优惠券,默认使用第一张优惠券
+            $this->orderData['couponList'] = array_values($couponList);
+            return false;
+        }
+        // 判断优惠券适用范围是否合法
+//        if (!$couponInfo['is_apply']) {
+//            throwError($couponInfo['not_apply_info']);
+//        }
+        return true;
+    }
+
+    /**
+     * 查找指定的优惠券信息
+     * @param int $couponId 优惠券ID
+     * @param array $couponList 优惠券列表
+     * @return false|mixed
+     */
+    private function getCouponInfo(int $couponId, array $couponList)
+    {
+        return helper::getArrayItemByColumn($couponList, 'user_coupon_id', $couponId);
+    }
+
+    /**
+     * 查找指定的优惠券信息
+     * @param int $couponId 优惠券ID
+     * @param array $couponList 优惠券列表
+     * @return false|mixed
+     */
+    private function getRiceCardInfo(int $riceCardId, array $userRiceCardList)
+    {
+        return helper::getArrayItemByColumn($userRiceCardList, 'id', $riceCardId);
+    }
+
+    /**
+     * 订单配送-快递配送
+     * @return bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function setOrderExpress()
+    {
+        // 设置默认数据:配送费用
+        helper::setDataAttribute($this->goodsList, [
+            'expressPrice' => 0,
+        ], true);
+        // 当前用户收货城市id
+        if($this->param['addressId']){ //有传参
+            $addredd = UserAddress::get(['user_id' => $this->user['user_id'], 'address_id' => $this->param['addressId']]);
+            $cityId = $addredd ? (int)$addredd['city_id'] : 0;
+            $this->orderData['address'] = $addredd;
+        }else{ //没有传参读默认地址
+            $cityId = $this->user['address_default'] ? (int)$this->user['address_default']['city_id'] : 0;
+            $this->orderData['address'] = $this->user['address_default'];
+        }
+        if ($this->param['delivery'] == DeliveryTypeEnum::EXPRESS) { // 普通快递
+            // 初始化配送服务类
+            $ExpressService = new ExpressService($cityId, $this->goodsList);
+            // 验证商品是否在限购配送范围
+            $isDeliveryLimit = $ExpressService->isDeliveryLimit();
+            if($cityId > 0){
+                if ($isDeliveryLimit == false) {
+                    $this->setError("很抱歉,您的收货地址在限购地区的配送范围内");
+                    $this->setErrorStatus(423);
+                    $this->orderData['isIntraRegion'] = $isDeliveryLimit;
+                }else{
+                    // 验证商品是否在配送范围
+                    $isIntraRegion = $ExpressService->isIntraRegion();
+                    if ($isIntraRegion == false) {
+                        $notInRuleGoodsName = $ExpressService->getNotInRuleGoodsName();
+                        $this->setError("很抱歉,您的收货地址不在商品 [".limit_str((string)$notInRuleGoodsName)."] 的配送范围内");
+                        $this->setErrorStatus(423);
+                    }
+                    $this->orderData['isIntraRegion'] = $isIntraRegion;
+                }
+            }
+            // 订单总运费金额
+            $this->orderData['expressPrice'] = $ExpressService->getDeliveryFee();
+        } else { // 门店自提
+            $this->orderData['expressPrice'] = "0.00";
+        }
+        
+        return true;
+    }
+
+    /**
+     * 创建新订单
+     * @param array $order 订单信息
+     * @return bool
+     */
+    public function createOrder(array $order)
+    {
+        // 表单验证
+        if (!$this->validateOrderForm($order)) {
+            return false;
+        }
+        // 创建新的订单
+        $status = $this->model->transaction(function () use ($order) {
+            // 创建订单事件
+            return $this->createOrderEvent($order);
+        });
+        if ($status && $order['payType'] == OrderPayTypeEnum::EXCHANGE) {
+            return $this->model->onPaymentByAccumulatePoints($this->model['order_no']);
+        }
+        return $status;
+    }
+
+    /**
+     * 创建订单事件
+     * @param $order
+     * @return bool
+     * @throws BaseException
+     * @throws \Exception
+     */
+    private function createOrderEvent($order)
+    {
+        // 门店自提
+        if ($order['delivery'] == DeliveryTypeEnum::SHOPS_DELIVERY) {
+            $order['hx_code'] = $this->model->hxCode();
+            $order['pickup_deadline'] = time() + OrderModel::getPickupDeadline() * 60; // 提货截止时间:提交订单2天内
+            $order['shop_id'] = $order['shopInfo']['shop_id']; // 订单自提门店id
+        }
+
+        // 新增订单记录
+        $status = $this->add($order, $this->param['remark']);
+        if ($order['delivery'] == DeliveryTypeEnum::EXPRESS) {
+            // 记录收货地址
+            $this->saveOrderAddress($order['address']);
+        }
+        
+        // 保存订单商品信息
+        $this->saveOrderGoods($order);
+
+        //保存满件送商品信息
+        $this->saveOrderGoodsMj($order);
+
+        // 保存订单套餐商品信息
+        $this->saveOrderGoodsTaocan($order);
+
+        // 更新商品库存 (针对下单减库存的商品)
+        $this->updateGoodsStockNum($order);
+        // 更新多个活动的活动库存
+        $this->updateActivityStock($order);
+
+        // 设置优惠券使用状态
+        $order['couponId'] > 0 && UserCouponModel::setIsUse((int)$order['couponId']);
+        //设置福利状态zq
+        if ($order['couponId'] > 0)UserCouponModel::setWelfareStatus((int)$order['couponId'],1);
+
+        // 获取订单详情
+//        $detail = OrderModel::getUserOrderDetail((int)$this->model['order_id']);
+        return $status;
+    }
+
+    /**
+     * 构建支付请求的参数
+     * @return array
+     * @throws BaseException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function onOrderPayment()
+    {
+        return PaymentService::orderPayment($this->model, $this->param['payType']);
+    }
+
+    /**
+     * 表单验证 (订单提交)
+     * @param array $order 订单信息
+     * @return bool
+     */
+    private function validateOrderForm(array $order)
+    {
+        if ($order['delivery'] == DeliveryTypeEnum::EXPRESS) {
+            if (empty($order['address'])) {
+                $this->error = '您还没有选择配送地址';
+                return false;
+            }
+        }
+        // 余额支付时判断用户余额是否足够
+        if ($order['payType'] == OrderPayTypeEnum::BALANCE) {
+            if ($this->user['balance'] < $order['orderPayPrice']) {
+                $this->error = '您的余额不足,无法使用余额支付';
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 当前订单是否存在和使用积分抵扣
+     * @param $order
+     * @return bool
+     */
+    private function isExistPointsDeduction($order)
+    {
+        return $order['isAllowPoints'] && $order['isUsePoints'];
+    }
+
+    /**
+     * 新增订单记录
+     * @param $order
+     * @param string $remark
+     * @return false|int
+     */
+    private function add($order, $remark = '')
+    {
+        // 当前订单是否存在和使用积分抵扣
+        $isExistPointsDeduction = $this->isExistPointsDeduction($order);
+        // 订单数据
+        $data = [
+            'user_id' => $this->user['user_id'],
+            'order_no' => $this->model->orderNo(),
+            'total_price' => $order['orderTotalPrice'],
+            'order_price' => $order['orderPrice'],
+            'coupon_id' => $order['couponId']>0?$order['couponId']:0,
+            'coupon_money' => $order['couponMoney'],
+            'points_money' => $isExistPointsDeduction ? $order['pointsMoney'] : 0.00,
+            'points_num' => $isExistPointsDeduction ? $order['pointsNum'] : 0,
+            'pay_price' => $order['orderPayPrice'],
+            'delivery_type' => $order['delivery'],
+            'pay_type' => $order['orderPayPrice'] > 0 ? $order['payType'] : OrderPayTypeEnum::MICAH_EXCHANGE,
+            'buyer_remark' => trim($remark),
+            'order_source' => $this->orderSource['source'],
+            'order_source_id' => $this->orderSource['source_id'],
+            'points_bonus' => $order['pointsBonus'],
+            'order_status' => OrderStatusEnum::NORMAL,
+            'store_id' => $this->storeId,
+            'provider_ids' => $order['orderProviderIds']??0,
+            'distributor_total_money' => $order['distributorTotalMoney']??0,
+            'member_total_money' => $order['memberTotalMoney']??0,
+            'gold_rice_amount' => $order['goldRiceAmount']??0,
+            'gold_rice_money' => $order['goldRiceMoney']??0,
+            'gold_rice_amount_input' => $order['goldRiceAmountInput']??0,
+            'rice_card_id' => $order['riceCardId']>0?$order['riceCardId']:0,
+            'rice_card_money' => $order['riceCardMoney']??0,
+            'rice_card_express_money' => $order['riceCardExpressMoney']??0,
+            'hx_code' => $order['hx_code'] ?? '',
+            'pickup_deadline' => $order['pickup_deadline'] ?? 0,
+            'shop_id' => $order['shop_id'] ?? 0,
+            'invoice_deadline' => $order['invoice_deadline'] ?? 0,
+            'is_full_send' => $order['is_full_send'] ?? 0,
+            'full_send_activity_id' => $order['full_send_activity_id'] ?? 0,
+            'is_qc_send_send' => $order['is_qc_send_send'] ?? 0,//是否参与全场满件送活动
+            'qc_send_activity_id' => $order['qc_send_activity_id'] ?? 0,//全场满件送活动ID
+            'activity_discount_total_price' => $order['activityDiscountTotalPrice'] ?? 0,
+            'staff_user_id' => $order['goodsList'][0]['staffUserId'] ?? 0,
+            'staff_shop_id' => $order['goodsList'][0]['shopId'] ?? 0,
+            'promotion_monitor_id' => $order['promotionMonitorId'] ?? 0,
+
+        ];
+
+        
+
+        //米卡兑换直接成功
+        if ($order['orderPayPrice']<=0 && $order['payType']==OrderPayTypeEnum::EXCHANGE){
+            $data['pay_status'] = PayStatusEnum::PENDING;
+        }else{
+            //米卡兑换直接成功
+            if($order['orderPayPrice']<=0 || $order['payType']==OrderPayTypeEnum::MICAH_EXCHANGE){
+                $data['pay_status'] = PayStatusEnum::SUCCESS;
+                $data['pay_time'] = time();
+                $data['invoice_deadline'] = time() + OrderModel::getInvoiceDeadline() * 60; // 申请开票截止时间:订单付款后的40天内可以申请开票
+            }
+        }
+
+        if ($order['delivery'] == DeliveryTypeEnum::EXPRESS) {
+            $data['express_price'] = $order['expressPrice'];
+        }
+        // 保存订单记录
+        return $this->model->save($data);
+    }
+
+    /**
+     * 保存订单商品信息
+     * @param $order
+     * @return int
+     */
+    private function saveOrderGoods($order)
+    {
+        // 当前订单是否存在和使用积分抵扣
+        $isExistPointsDeduction = $this->isExistPointsDeduction($order);
+        // 订单商品列表
+        $goodsList = [];
+        foreach ($order['goodsList'] as $key=> $goods) {
+//            dd($goods['total_pay_price']);
+            /* @var GoodsModel $goods */
+            $item = [
+                'user_id' => $this->user['user_id'],
+                'store_id' => $this->storeId,
+                'goods_id' => $goods['goods_id'],
+                'goods_name' => $goods['goods_name'],
+                'goods_no' => $goods['goods_no'] ?: '',
+                'image_id' => (int)current($goods['goods_images'])['file_id'],
+                'deduct_stock_type' => $goods['deduct_stock_type'],
+                'spec_type' => $goods['spec_type'],
+                'goods_sku_id' => $goods['skuInfo']['goods_sku_id'],
+                'goods_props' => $goods['skuInfo']['goods_props'] ?: '',
+                'content' => $goods['content'] ?? '',
+                'goods_sku_no' => $goods['skuInfo']['goods_sku_no'] ?: '',
+                'goods_price' => $goods['skuInfo']['goods_price'],
+                'specs' => $goods['skuInfo']['specs'],
+                'supplier' => $goods['supplier'],
+                'line_price' => $goods['skuInfo']['line_price'],
+                'goods_weight' => $goods['skuInfo']['goods_weight'],
+                'is_user_grade' => (int)$goods['is_user_grade'],
+                'grade_ratio' => $goods['grade_ratio']??0,
+                'grade_goods_price' => $goods['grade_goods_price']??0,
+                'grade_total_money' => $goods['grade_total_money']??0,
+                'coupon_id' => $goods['coupon_id']??0,
+                'coupon_money' => $goods['coupon_money']??0,
+                'points_money' => $isExistPointsDeduction ? $goods['points_money'] : 0.00,
+                'points_num' => $isExistPointsDeduction ? $goods['points_num'] : 0,
+                'points_bonus' => $goods['points_bonus']??0,
+                'total_num' => $goods['total_num'],
+                'total_price' => $goods['total_price'],
+                'total_pay_price' => $goods['total_pay_price']??0,
+                'provider_id' => $goods['provider_id'],
+                'brand' => $goods['brand'],
+                'province_id' => $goods['province_id'],
+                'city_id' => $goods['city_id'],
+                'storage' => $goods['storage'],
+                'unit' => $goods['unit'],
+                'clearing_price' => $goods['skuInfo']['clearing_price']??'0.00',
+                'platform_rate' => $goods['skuInfo']['platform_rate']??'0.00',
+                'staff_user_id' => $goods['staffUserId'],
+                'shop_id' => $goods['shopId'],
+                'distributor_radio' => $goods['distributor_radio']??0,
+                'distributor_goods_price' => $goods['distributor_goods_price']??0,
+                'distributor_total_money' => $goods['distributor_total_money']??0,
+                'member_radio' => $goods['member_radio']??0,
+                'member_total_money' => $goods['member_total_money']??0,
+                'gold_rice_amount' => $goods['gold_rice_amount']??0,
+                'gold_rice_money' => $goods['gold_rice_money']??0,
+                'gold_rice_amount_input' => $goods['gold_rice_amount_input']??0,
+                'rice_card_id' => $goods['rice_card_id']??0,
+                'rice_card_money' => $goods['rice_card_money']??0,
+                'goods_type' => $goods['goods_type']??10,
+//                'has_refund_full' => $goods['goods_type']==20? 1 : 0,//赠品直接默认为全额退款状态
+                'is_full_send' => $goods['is_full_send'] ?? 0,
+                'full_send_activity_id' => $goods['full_send_activity_id'] ?? 0,
+                'full_send_count' => $goods['full_send_count'] ?? 0,//满就送活动实际参与活动数量
+                'is_qc_send_send' => $goods['is_qc_send_send'] ?? 0,//是否参与全场满件送活动
+                'qc_send_activity_id' => $goods['qc_send_activity_id'] ?? 0,//全场满件送活动ID
+                'qc_send_count' => $goods['qc_send_count'] ?? 0,//全场满件送活动赠品的数量
+                'qc_send_use_count' => $goods['qc_send_use_count'] ?? 0,//全场满件送活动实际参与活动数量
+                'is_activity_discount' => $goods['is_activity_discount'] ?? 0,//是否参与了N件X折活动 0否 1是
+                'activity_discount_id' => $goods['activity_discount_id'] ?? 0,//N件X折活动ID
+                'activity_discount_total_price' => $goods['activity_discount_total_price'] ?? 0,//N件X折活动折扣金额
+                'activity_discount_desc' => $goods['activity_discount_desc'] ?? 0,//N件X折活动描述
+                'activity_discount_count' => $goods['activity_discount_count'] ?? 0,//N件X折活动实际参与活动数量
+                'is_mj_send' => $goods['is_mj_send'] ?? 0,
+                'mj_send_activity_id' => $goods['mj_send_activity_id'] ?? 0,
+                'mj_send_num' => $goods['mj_send_num'] ?? 0,
+                'mj_send_count' => $goods['mj_send_count'] ?? 0,//满件送活动赠品的数量
+                'mj_send_use_count' => $goods['mj_send_use_count'] ?? 0,//满件送活动实际参与活动数量
+//                'promotion_monitor_id' => $goods['promotion_monitor_id'] ?? 0, // 推广监控ID
+            ];
+            // 记录订单商品来源id
+            $item['goods_source_id'] = isset($goods['goods_source_id']) ? $goods['goods_source_id'] : 0;
+            $goodsList[] = $item;
+        }
+
+        return $this->model->goods()->saveAll($goodsList) !== false;
+    }
+
+    /**
+     * 保存订单套餐商品信息
+     * @param $order
+     * @return int
+     */
+    private function saveOrderGoodsMj($order)
+    {
+        // 订单商品列表
+        $goodsList = [];
+        foreach ($order['goodsList'] as $key=> $goods) {
+            //如果存在满减商品也保存起来
+            foreach ($goods['mj_send_goods_list'] as $mj_send_goods){
+                $mj_item = [
+                    'user_id' => $this->user['user_id'],
+                    'store_id' => $this->storeId,
+                    'goods_id' => $mj_send_goods['goods_id'],
+                    'goods_name' => $mj_send_goods['goods_name'],
+                    'goods_no' => $mj_send_goods['goods_no'] ?: '',
+                    'image_id' => (int)current($mj_send_goods['goods_images'])['file_id'],
+                    'deduct_stock_type' => $mj_send_goods['deduct_stock_type'],
+                    'spec_type' => $mj_send_goods['spec_type'],
+                    'goods_sku_id' => $mj_send_goods['skuInfo']['goods_sku_id'],
+                    'goods_props' => $mj_send_goods['skuInfo']['goods_props'] ?: '',
+                    'content' => $mj_send_goods['content'] ?? '',
+                    'goods_sku_no' => $mj_send_goods['skuInfo']['goods_sku_no'] ?: '',
+                    'goods_price' => $mj_send_goods['skuInfo']['goods_price'],
+                    'line_price' => $mj_send_goods['skuInfo']['line_price'],
+                    'goods_weight' => $mj_send_goods['skuInfo']['goods_weight'],
+                    'is_user_grade' => (int)$mj_send_goods['is_user_grade'],
+                    'grade_ratio' => $mj_send_goods['grade_ratio']??0,
+                    'grade_goods_price' => $mj_send_goods['grade_goods_price']??0,
+                    'grade_total_money' => $mj_send_goods['grade_total_money']??0,
+                    'coupon_id' => $mj_send_goods['coupon_id']??0,
+                    'coupon_money' => $mj_send_goods['coupon_money']??0,
+                    'points_bonus' => $mj_send_goods['points_bonus']??0,
+                    'total_num' => $mj_send_goods['total_num'],
+                    'total_price' => $mj_send_goods['total_price'],
+                    'total_pay_price' => $mj_send_goods['total_pay_price']??0,
+                    'provider_id' => $mj_send_goods['provider_id'],
+                    'brand' => $mj_send_goods['brand'],
+                    'province_id' => $mj_send_goods['province_id'],
+                    'city_id' => $mj_send_goods['city_id'],
+                    'storage' => $mj_send_goods['storage'],
+                    'unit' => $mj_send_goods['unit'],
+                    'clearing_price' => $mj_send_goods['skuInfo']['clearing_price']??'0.00',
+                    'platform_rate' => $mj_send_goods['skuInfo']['platform_rate']??'0.00',
+                    'staff_user_id' => $mj_send_goods['staffUserId'],
+                    'shop_id' => $mj_send_goods['shopId'],
+                    'rice_card_id' => $mj_send_goods['rice_card_id']??0,
+                    'rice_card_money' => $mj_send_goods['rice_card_money']??0,
+                    'goods_type' => $mj_send_goods['goods_type']??20, //默认赠品
+                    'is_mj_send' => $goods['is_mj_send'] ?? 0,
+                    'mj_send_activity_id' => $goods['mj_send_activity_id'] ?? 0,
+                    'master_order_goods_id' => $this->model->goods[$key]['order_goods_id'],
+                ];
+                // 记录订单商品来源id
+                $mj_item['goods_source_id'] = isset($goods['goods_source_id']) ? $goods['goods_source_id'] : 0;
+                $goodsList[] = $mj_item;
+            }
+        }
+
+        return $this->model->goods()->saveAll($goodsList) !== false;
+    }
+
+
+    /**
+     * 保存订单套餐商品信息
+     * @param $order
+     * @return int
+     */
+    private function saveOrderGoodsTaocan($order)
+    {
+        // 当前订单是否存在和使用积分抵扣
+        $isExistPointsDeduction = $this->isExistPointsDeduction($order);
+        // 订单商品列表
+        $goodsList = [];
+        foreach ($order['goodsList'] as $key=> $goods) {
+            if($goods['goods_type']!=30){//是套餐商品
+                continue;
+            }
+            $relGoodList = GoodsPackageModel::with(['relGood'=>['images','skuList']])->where('goods_id',$goods['goods_id'])->select();
+//            dd( $relGoodList->toArray());
+            foreach ($relGoodList as $relGood){
+                $relGood['skuList'] = [];
+                foreach ($relGood['relGood']['skuList'] as $sku){
+                    if($sku['goods_sku_id']==$relGood['rel_goods_sku_id']){
+                        $relGood['skuList'] = $sku;
+                    }
+                }
+                $item = [
+                    'user_id' => $this->user['user_id'],
+                    'order_id' => $this->model['order_id'],
+                    'order_goods_id' => $this->model->goods[$key]['order_goods_id'],
+                    'store_id' => $this->storeId,
+                    'goods_id' => $relGood['relGood']['goods_id'],
+                    'goods_name' => $relGood['relGood']['goods_name'],
+                    'goods_no' => $relGood['relGood']['goods_no'] ?: '',
+                    'image_id' => (int)$relGood['relGood']['images'][0]['image_id']??0,
+                    'deduct_stock_type' => $relGood['relGood']['deduct_stock_type'],
+                    'spec_type' => $relGood['relGood']['spec_type'],
+                    'goods_sku_id' => $relGood['skuList']['goods_sku_id']??0,
+                    'goods_props' => $relGood['skuList']['goods_props'] ?? '',
+                    'content' => $relGood['relGood']['content'] ?? '',
+                    'goods_sku_no' => $relGood['skuList']['goods_sku_no'] ?? '',
+                    'goods_price' => $relGood['skuList']['goods_price']??'0.00',
+                    'line_price' => $relGood['skuList']['line_price']??'0.00',
+                    'goods_weight' => $relGood['skuList']['goods_weight']??'0.00',
+                    'is_user_grade' => (int)$relGood['relGood']['is_user_grade'],
+                    'grade_ratio' => $relGood['relGood']['grade_ratio']??0,
+                    'grade_goods_price' => $relGood['relGood']['grade_goods_price']??0,
+                    'grade_total_money' => $relGood['relGood']['grade_total_money']??0,
+                    'coupon_id' => $relGood['relGood']['coupon_id']??0,
+                    'coupon_money' => $relGood['relGood']['coupon_money']??0,
+                    'points_money' => $isExistPointsDeduction ? $relGood['relGood']['points_money'] : 0.00,
+                    'points_num' => $isExistPointsDeduction ? $relGood['relGood']['points_num'] : 0,
+                    'points_bonus' => $relGood['relGood']['points_bonus']??0,
+                    'total_num' => 1,
+                    'total_price' => $relGood['relGood']['total_price']??0,
+                    'total_pay_price' => $relGood['relGood']['total_pay_price']??0,
+                    'provider_id' => $relGood['relGood']['provider_id'],
+                    'brand' => $relGood['relGood']['brand'],
+                    'province_id' => $goods['province_id'],
+                    'city_id' => $relGood['relGood']['city_id'],
+                    'storage' => $relGood['relGood']['storage'],
+                    'unit' => $relGood['relGood']['unit'],
+                    'clearing_price' => $relGood['skuList']['clearing_price']??'0.00',
+                    'platform_rate' => $relGood['skuList']['platform_rate']??'0.00',
+                    'goods_type' => 30,
+                ];
+                // 记录订单商品来源id
+                $item['goods_source_id'] = isset($relGood['goods_source_id']) ? $relGood['goods_source_id'] : 0;
+                $goodsList[] = $item;
+            }
+        }
+
+        return (new OrderGoodsTaocanModel())->saveAll($goodsList) !== false;
+    }
+
+    /**
+     * 更新商品库存 (针对下单减库存的商品)
+     * 普通快递、门店自提 分开扣库存
+     * @param $order
+     * @return mixed
+     */
+    private function updateGoodsStockNum($order)
+    {
+        return StockFactory::getFactory($this->model['order_source'])->updateGoodsStock($order);
+    }
+
+    /**
+     * 更新商品库存 (针对下单减库存的商品)
+     * 普通快递、门店自提 分开扣库存
+     * @param $order
+     * @return mixed
+     */
+    private function updateActivityStock($order)
+    {
+        return StockFactory::getFactory($this->model['order_source'])->updateActivityStock($order);
+    }
+
+
+    /**
+     * 记录收货地址
+     * @param $address
+     * @return false|\think\Model
+     */
+    private function saveOrderAddress($address)
+    {
+        return $this->model->address()->save([
+            'user_id' => $this->user['user_id'],
+            'store_id' => $this->storeId,
+            'name' => $address['name'],
+            'phone' => $address['phone'],
+            'province_id' => $address['province_id'],
+            'city_id' => $address['city_id'],
+            'region_id' => $address['region_id'],
+            'detail' => $address['detail'],
+        ]);
+    }
+
+    /**
+     * 设置错误信息
+     * @param $error
+     */
+    protected function setError($error)
+    {
+        empty($this->error) && $this->error = $error;
+    }
+
+    /**
+     * 获取错误信息
+     * @return mixed
+     */
+    public function getError()
+    {
+        return $this->error ?: '';
+    }
+
+    /**
+     * 设置错误状态
+     * @param $errorStatus
+     */
+    protected function setErrorStatus($errorStatus)
+    {
+        empty($this->errorStatus) && $this->errorStatus = $errorStatus;
+    }
+
+    /**
+     * 获取错误信息
+     * @return mixed
+     */
+    public function getErrorStatus()
+    {
+        return $this->errorStatus ?: 0;
+    }
+
+    /**
+     * 是否存在错误
+     * @return bool
+     */
+    public function hasError()
+    {
+        return !empty($this->error);
+    }
+
+}

+ 25 - 2
app/api/service/order/PaySuccess.php

@@ -15,6 +15,7 @@ namespace app\api\service\order;
 use app\api\model\card\UserRiceCard as UserRiceCardModel;
 use app\api\model\card\UserRiceCardConsume as UserRiceCardConsumeModel;
 use app\api\model\member\GoldRice as GoldRiceModel;
+use app\common\enum\user\AccumulatePointsScene;
 use app\common\service\BaseService;
 use app\api\model\User as UserModel;
 use app\api\model\Order as OrderModel;
@@ -99,6 +100,26 @@ class PaySuccess extends BaseService
                 return false;
             }
         }
+
+        //积分不足 todo 补充积分兑换商品比例
+        if ($payType == OrderPayTypeEnum::EXCHANGE) {
+            if ($this->user['accumulate_points'] < $this->model['total_price']) {
+                $this->error = '用户积分不足,无法兑换成功';
+                return false;
+            }
+            $this->model->transaction(function () use ($payType, $payData) {
+                // 更新订单状态
+                $this->updateOrderInfo($payType, $payData);
+                //扣除用户积分 todo 确定积分兑换商品金额比例
+                $points = bcmul($this->model['total_price'],"100",0);
+                UserModel::setDecAccumulatePoints($this->user['user_id'], $points,AccumulatePointsScene::CONSUME,'兑换商品');
+                // 记录订单支付信息
+                $this->updatePayInfo($payType);
+            });
+            return true;
+
+        }
+
         // 事务处理
         $this->model->transaction(function () use ($payType, $payData) {
             // 更新订单状态
@@ -107,10 +128,12 @@ class PaySuccess extends BaseService
             UserModel::setIncPayMoney($this->user['user_id'], (float)$this->model['pay_price']);
             //累积VIP用户积分
             UserModel::setIncGrowthValue($this->user,$this->model['rice_card_money']+$this->model['pay_price']);
+            //累计用户积分
+            UserModel::setIncAccumulatePoints($this->user['user_id'], $this->model['pay_price']);
             // 记录订单支付信息
             $this->updatePayInfo($payType);
-            // 如果是普通订单,写入分销记录
-            if($this->model['order_source']!=OrderSourceEnum::BARGAIN){
+            // 如果是普通订单,写入分销记录(积分兑换商品订单无分佣)
+            if($this->model['order_source']!=OrderSourceEnum::BARGAIN || $this->model['or'] != OrderSourceEnum::EXCHANGE){
                 $this->writeCommission($payType);
             }
             //写入金米粒记录

+ 1 - 0
app/api/validate/order/Checkout.php

@@ -100,6 +100,7 @@ class Checkout extends Validate
      */
     protected $scene = [
         'buyNow' => ['goodsId', 'goodsNum', 'goodsSkuId', 'staffUserId'],
+        'pointsExchange' => ['goodsId', 'goodsNum', 'goodsSkuId', 'staffUserId'],
         'cart' => ['cartIds'],
     ];
 

+ 5 - 0
app/common/enum/OrderType.php

@@ -42,6 +42,7 @@ class OrderType extends EnumBasics
 
     const ZA = 70;
 
+    const EXCHANGE = 500;
     /**
      * 获取订单类型值
      * @return array
@@ -77,6 +78,10 @@ class OrderType extends EnumBasics
             self::ZA =>[
                 'name' => '买一赠一订单',
                 'value' => self::ZA
+            ],
+            self::EXCHANGE =>[
+                'name' => '积分兑换订单',
+                'value' => self::EXCHANGE
             ]
         ];
     }

+ 7 - 0
app/common/enum/goods/GoodsType.php

@@ -29,6 +29,9 @@ class GoodsType extends EnumBasics
 
     const MULTI = 30;
 
+    //积分兑换商品
+    const EXCHANGE = 40;
+
     /**
      * 获取枚举类型值
      * @return array
@@ -48,6 +51,10 @@ class GoodsType extends EnumBasics
                 'name' => '套餐商品',
                 'value' => self::MULTI,
             ],
+            self::EXCHANGE => [
+                'name' => '积分兑换商品',
+                'value' => self::EXCHANGE,
+            ],
         ];
     }
 }

+ 7 - 0
app/common/enum/order/OrderSource.php

@@ -42,6 +42,9 @@ class OrderSource extends EnumBasics
     //买一赠一订单
     const ZA = 70;
 
+    //积分兑换商品订单
+    const EXCHANGE = 80;
+
     /**
      * 获取枚举数据
      * @return array
@@ -76,6 +79,10 @@ class OrderSource extends EnumBasics
             self::ZA => [
                 'name'=>'买一赠一订单',
                 'value'=> self::ZA
+            ],
+            self::EXCHANGE => [
+                'name'=>'积分兑换商品订单',
+                'value'=> self::EXCHANGE
             ]
         ];
     }

+ 7 - 1
app/common/enum/order/PayType.php

@@ -31,8 +31,10 @@ class PayType extends EnumBasics
     const MICAH_EXCHANGE = 30;
 
     //活动赠送
-    const ACTIVITY = 40; 
+    const ACTIVITY = 40;
 
+    //积分兑换
+    const EXCHANGE = 50;
 
 
     /**
@@ -57,6 +59,10 @@ class PayType extends EnumBasics
             self::ACTIVITY => [
                 'name'=>'活动赠送',
                 'value' => self::ACTIVITY
+            ],
+            self::EXCHANGE => [
+                'name'=>'积分兑换',
+                'value' => self::EXCHANGE
             ]
         ];
     }

+ 58 - 0
app/common/enum/user/AccumulatePointsScene.php

@@ -0,0 +1,58 @@
+<?php
+// +----------------------------------------------------------------------
+// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
+// +----------------------------------------------------------------------
+// | Author: 萤火科技 <admin@yiovo.com>
+// +----------------------------------------------------------------------
+declare (strict_types = 1);
+
+namespace app\common\enum\user;
+
+use app\common\enum\EnumBasics;
+
+/**
+ * 用户积分枚举类
+ * Class AccumulatePointsScene
+ * @package app\common\enum\user
+ */
+class AccumulatePointsScene extends EnumBasics
+{
+    // 用户消费获得
+    const RECHARGE = 10;
+
+    // 兑换商品
+    const CONSUME = 20;
+
+    // 管理员操作
+    const ADMIN = 30;
+
+    /**
+     * 获取订单类型值
+     * @return array
+     */
+    public static function data()
+    {
+        return [
+            self::RECHARGE => [
+                'name' => '用户消费获得',
+                'value' => self::RECHARGE,
+                'describe' => '用户消费获得:%s',
+            ],
+            self::CONSUME => [
+                'name' => '兑换商品',
+                'value' => self::CONSUME,
+                'describe' => '兑换商品:%s',
+            ],
+            self::ADMIN => [
+                'name' => '管理员操作',
+                'value' => self::ADMIN,
+                'describe' => '后台管理员 [%s] 操作',
+            ]
+        ];
+    }
+
+}

+ 4 - 0
app/common/model/Goods.php

@@ -443,6 +443,10 @@ class Goods extends BaseModel
             //需要单规格的商品或赠品
             $filter[] = ['goods_type','<',GoodsType::MULTI];
             $filter[] = ['stock_total','>',0];
+        }elseif(isset($params['goods_type']) &&  $params['goods_type'] == GoodsType::EXCHANGE){
+            //积分兑换商品
+            $filter[] = ['goods_type','=',GoodsType::EXCHANGE];
+            $filter[] = ['stock_total','>',0];
         }else{
             if (isset($params['is_backend']) && $params['is_backend'] == 1){
 

+ 55 - 0
app/common/model/User.php

@@ -12,6 +12,8 @@ declare (strict_types=1);
 
 namespace app\common\model;
 
+use app\common\enum\user\AccumulatePointsScene;
+use app\common\model\user\AccumulatePointsLog;
 use app\common\library\helper;
 use app\common\model\store\Setting as SettingModel;
 use app\common\model\user\CommissionsDetail;
@@ -279,6 +281,59 @@ class User extends BaseModel
     }
 
     /**
+     * @param int $userId
+     * @param int $payMoney 支付金额
+     * @param int $scene 积分场景
+     * @param string $describe
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function setIncAccumulatePoints(int $userId, string $payMoney, int $scene = AccumulatePointsScene::RECHARGE, string $describe = '')
+    {
+        $rate = SettingModel::getItem('points_rate')['points_rate'];
+        $points = bcmul(strval($payMoney),$rate,0);
+        // 新增积分变动明细
+        AccumulatePointsLog::add([
+            'user_id' => $userId,
+            'value' => $points,
+            'scene' => $scene,
+            'describe' => $describe,
+        ]);
+
+        // 更新用户可用积分
+        return (new static)->setInc($userId, 'accumulate_points', intval($points));
+    }
+
+    /**
+     * 积分扣减
+     * @param int $userId
+     * @param float $payMoney
+     * @param int $scene
+     * @param string $describe
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function setDecAccumulatePoints(int $userId, string $payMoney, int $scene = AccumulatePointsScene::RECHARGE, string $describe = '')
+    {
+        $rate = SettingModel::getItem('points_rate')['points_rate'];
+        $points = bcmul(strval($payMoney),$rate,0);
+        // 新增积分变动明细
+        AccumulatePointsLog::add([
+            'user_id' => $userId,
+            'value' => $points,
+            'scene' => $scene,
+            'describe' => $describe,
+        ]);
+
+        // 更新用户可用积分
+        return (new static)->setDec($userId, 'accumulate_points', intval($points));
+    }
+
+    /**
      * 多字段增减
      * @param array|int|bool $where 支持自增ID  也支持where语句
      * @param array $incData //自增字段

+ 62 - 0
app/common/model/user/AccumulatePointsLog.php

@@ -0,0 +1,62 @@
+<?php
+// +----------------------------------------------------------------------
+// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
+// +----------------------------------------------------------------------
+// | Author: 萤火科技 <admin@yiovo.com>
+// +----------------------------------------------------------------------
+declare (strict_types = 1);
+
+namespace app\common\model\user;
+
+use app\common\model\BaseModel;
+
+/**
+ * 用户积分变动明细模型
+ * Class PointsLog
+ * @package app\common\model\user
+ */
+class AccumulatePointsLog extends BaseModel
+{
+    // 定义表名
+    protected $name = 'user_accumulate_points_log';
+
+    // 定义主键
+    protected $pk = 'log_id';
+
+    protected $updateTime = false;
+
+    /**
+     * 关联会员记录表
+     * @return \think\model\relation\BelongsTo
+     */
+    public function user()
+    {
+        $module = self::getCalledModule();
+        return $this->belongsTo("app\\{$module}\\model\\User");
+    }
+
+    /**
+     * 新增记录
+     * @param $data
+     */
+    public static function add($data)
+    {
+        $static = new static;
+        $static->save(array_merge(['store_id' => $static::$storeId], $data));
+    }
+
+    /**
+     * 新增记录 (批量)
+     * @param $saveData
+     * @return bool
+     */
+    public function onBatchAdd($saveData)
+    {
+        return $this->addAll($saveData) !== false;
+    }
+
+}