Przeglądaj źródła

Merge branch 'v4.7.0dev' of https://gitee.com/ZhongBangKeJi/CRMEB into v4.7.0dev

From-wh 2 lat temu
rodzic
commit
daa400ee85

+ 5 - 2
crmeb/app/api/ApiExceptionHandle.php

@@ -14,6 +14,7 @@ namespace app\api;
 
 use crmeb\exceptions\AdminException;
 use crmeb\exceptions\ApiException;
+use crmeb\exceptions\ApiStatusException;
 use crmeb\exceptions\AuthException;
 use think\db\exception\DbException;
 use think\exception\Handle;
@@ -86,11 +87,13 @@ class ApiExceptionHandle extends Handle
         ] : [];
         $message = Env::get('app_debug', false) ? $e->getMessage() : '很抱歉,系统开小差了';
         // 添加自定义异常处理机制
+        if ($e instanceof ApiStatusException) {
+            return app('json')->status($e->getApiStatus(), $message, $e->getApiData());
+        }
         if ($e instanceof AuthException || $e instanceof AdminException || $e instanceof ApiException || $e instanceof ValidateException) {
             return app('json')->make($e->getCode() ?: 400, $message, $massageData);
-        } else {
-            return app('json')->fail($message, $massageData);
         }
+        return app('json')->fail($message, $massageData);
     }
 
 }

+ 73 - 72
crmeb/app/api/controller/v1/order/StoreOrderController.php

@@ -15,6 +15,8 @@ use app\services\pay\PayServices;
 use app\services\shipping\ExpressServices;
 use app\services\system\admin\SystemAdminServices;
 use app\services\user\UserInvoiceServices;
+use crmeb\exceptions\ApiException;
+use crmeb\exceptions\ApiStatusException;
 use crmeb\services\pay\extend\allinpay\AllinPay;
 use app\services\activity\{lottery\LuckLotteryServices,
     bargain\StoreBargainServices,
@@ -166,7 +168,7 @@ class StoreOrderController
         $uid = (int)$request->uid();
         if ($checkOrder = $this->services->getOne(['order_id|unique' => $key, 'uid' => $uid, 'is_del' => 0]))
             return app('json')->status('extend_order', 410209, ['orderId' => $checkOrder['order_id'], 'key' => $key]);
-        [$addressId, $couponId, $payType, $useIntegral, $mark, $combinationId, $pinkId, $seckill_id, $bargainId, $shipping_type, $real_name, $phone, $storeId, $news, $invoice_id, $quitUrl, $advanceId, $virtual_type, $customForm] = $request->postMore([
+        [$addressId, $couponId, $payType, $useIntegral, $mark, $combinationId, $pinkId, $seckillId, $bargainId, $shipping_type, $real_name, $phone, $storeId, $news, $invoice_id, $quitUrl, $advanceId, $virtual_type, $customForm] = $request->postMore([
             [['addressId', 'd'], 0],
             [['couponId', 'd'], 0],
             ['payType', ''],
@@ -188,77 +190,76 @@ class StoreOrderController
             ['custom_form', []],
         ], true);
         $payType = strtolower($payType);
-        $cartGroup = $this->services->getCacheOrderInfo($uid, $key);
-        if (!$cartGroup) {
-            return app('json')->fail(410208);
-        }
-        //下单前砍价验证
-        if ($bargainId) {
-            $bargainServices->checkBargainUser((int)$bargainId, $uid);
-        }
-
-        if ($pinkId) {
-            $pinkId = (int)$pinkId;
-            /** @var StorePinkServices $pinkServices */
-            $pinkServices = app()->make(StorePinkServices::class);
-            if ($pinkServices->isPink($pinkId, $uid))
-                return app('json')->status('ORDER_EXIST', 410210, ['orderId' => $this->services->getStoreIdPink($pinkId, $uid)]);
-            if ($this->services->getIsOrderPink($pinkId, $uid))
-                return app('json')->status('ORDER_EXIST', 410211, ['orderId' => $this->services->getStoreIdPink($pinkId, $uid)]);
-            if (!CacheService::checkStock(md5($pinkId), 1, 3) || !CacheService::popStock(md5($pinkId), 1, 3)) {
-                return app('json')->fail(410212);
-            }
-        }
-
-        $cartInfo = null;
-        if ($seckill_id || $combinationId || $bargainId || $advanceId) {
-            $cartInfo = $cartGroup['cartInfo'];
-            foreach ($cartInfo as $item) {
-                $type = 0;
-                if (!isset($item['product_attr_unique']) || !$item['product_attr_unique']) continue;
-                if ($item['seckill_id']) {
-                    $type = 1;
-                } elseif ($item['bargain_id']) {
-                    $type = 2;
-                } elseif ($item['combination_id']) {
-                    $type = 3;
-                } elseif ($item['advance_id']) {
-                    $type = 6;
-                }
-                if ($type && (!CacheService::checkStock($item['product_attr_unique'], (int)$item['cart_num'], $type) || !CacheService::popStock($item['product_attr_unique'], (int)$item['cart_num'], $type))) {
-                    return app('json')->fail(410214, null, ['cart_num' => $item['cart_num'], 'unit_name' => $item['productInfo']['unit_name']]);
-
-                }
-            }
-        }
-        $virtual_type = $cartGroup['cartInfo'][0]['productInfo']['virtual_type'] ?? 0;
-        $order = $createServices->createOrder($uid, $key, $cartGroup, $request->user()->toArray(), $addressId, $payType, !!$useIntegral, $couponId, $mark, $combinationId, $pinkId, $seckill_id, $bargainId, $shipping_type, $real_name, $phone, $storeId, !!$news, $advanceId, $virtual_type, $customForm, $invoice_id);
-        if ($order === false) {
-            if ($seckill_id || $combinationId || $advanceId || $bargainId) {
-                foreach ($cartInfo as $item) {
-                    $value = $item['cart_info'];
-                    $type = 0;
-                    if (!isset($value['product_attr_unique']) || $value['product_attr_unique']) continue;
-                    if ($value['seckill_id']) {
-                        $type = 1;
-                    } elseif ($value['bargain_id']) {
-                        $type = 2;
-                    } elseif ($value['combination_id']) {
-                        $type = 3;
-                    } elseif ($value['advance_id']) {
-                        $type = 6;
-                    }
-                    if ($type) CacheService::setStock($value['product_attr_unique'], (int)$value['cart_num'], $type, false);
-                }
-            }
-            return app('json')->fail(410200);
-        }
+//        $cartGroup = $this->services->getCacheOrderInfo($uid, $key);
+//        if (!$cartGroup) {
+//            return app('json')->fail(410208);
+//        }
+//        //下单前砍价验证
+//        if ($bargainId) {
+//            $bargainServices->checkBargainUser((int)$bargainId, $uid);
+//        }
+//
+//        if ($pinkId) {
+//            $pinkId = (int)$pinkId;
+//            /** @var StorePinkServices $pinkServices */
+//            $pinkServices = app()->make(StorePinkServices::class);
+//            if ($pinkServices->isPink($pinkId, $uid))
+//                return app('json')->status('ORDER_EXIST', 410210, ['orderId' => $this->services->getStoreIdPink($pinkId, $uid)]);
+//            if ($this->services->getIsOrderPink($pinkId, $uid))
+//                return app('json')->status('ORDER_EXIST', 410211, ['orderId' => $this->services->getStoreIdPink($pinkId, $uid)]);
+//            if (!CacheService::checkStock(md5($pinkId), 1, 3) || !CacheService::popStock(md5($pinkId), 1, 3)) {
+//                return app('json')->fail(410212);
+//            }
+//        }
+//
+//        $cartInfo = null;
+//        if ($seckill_id || $combinationId || $bargainId || $advanceId) {
+//            $cartInfo = $cartGroup['cartInfo'];
+//            foreach ($cartInfo as $item) {
+//                $type = 0;
+//                if (!isset($item['product_attr_unique']) || !$item['product_attr_unique']) continue;
+//                if ($item['seckill_id']) {
+//                    $type = 1;
+//                } elseif ($item['bargain_id']) {
+//                    $type = 2;
+//                } elseif ($item['combination_id']) {
+//                    $type = 3;
+//                } elseif ($item['advance_id']) {
+//                    $type = 6;
+//                }
+//                if ($type && (!CacheService::checkStock($item['product_attr_unique'], (int)$item['cart_num'], $type) || !CacheService::popStock($item['product_attr_unique'], (int)$item['cart_num'], $type))) {
+//                    return app('json')->fail(410214, null, ['cart_num' => $item['cart_num'], 'unit_name' => $item['productInfo']['unit_name']]);
+//
+//                }
+//            }
+//        }
+//        $virtual_type = $cartGroup['cartInfo'][0]['productInfo']['virtual_type'] ?? 0;
+        $order = $createServices->createOrder($uid, $key, $request->user()->toArray(), $addressId, $payType, !!$useIntegral, $couponId, $mark, $combinationId, $pinkId, $seckillId, $bargainId, $shipping_type, $real_name, $phone, $storeId, !!$news, $advanceId, $customForm, $invoice_id);
+//        if ($order === false) {
+//            if ($seckill_id || $combinationId || $advanceId || $bargainId) {
+//                foreach ($cartInfo as $item) {
+//                    $value = $item['cart_info'];
+//                    $type = 0;
+//                    if (!isset($value['product_attr_unique']) || $value['product_attr_unique']) continue;
+//                    if ($value['seckill_id']) {
+//                        $type = 1;
+//                    } elseif ($value['bargain_id']) {
+//                        $type = 2;
+//                    } elseif ($value['combination_id']) {
+//                        $type = 3;
+//                    } elseif ($value['advance_id']) {
+//                        $type = 6;
+//                    }
+//                    if ($type) CacheService::setStock($value['product_attr_unique'], (int)$value['cart_num'], $type, false);
+//                }
+//            }
+//            throw new ApiException(410200);
+//        }
         $orderId = $order['order_id'];
-        $orderInfo = $this->services->getOne(['order_id' => $orderId]);
-        if (!$orderInfo || !isset($orderInfo['paid'])) {
-            return app('json')->fail(410194);
-        }
-
+//        $orderInfo = $this->services->getOne(['order_id' => $orderId]);
+//        if (!$orderInfo || !isset($orderInfo['paid'])) {
+//            return app('json')->fail(410194);
+//        }
         return app('json')->status('success', 410203, compact('orderId', 'key'));
     }
 
@@ -338,7 +339,7 @@ class StoreOrderController
             if ($payPriceStatus)//0元支付成功
                 return app('json')->status('success', 410195, ['order_id' => $orderInfo['order_id'], 'key' => $orderInfo['unique']]);
             else
-                return app('json')->status('pay_error');
+                return app('json')->status('pay_error', 410216);
         }
 
         switch ($paytype) {

+ 6 - 0
crmeb/app/dao/order/StoreOrderStoreOrderStatusDao.php

@@ -81,6 +81,12 @@ class StoreOrderStoreOrderStatusDao extends BaseDao
      * @param array $where
      * @param int $limit
      * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
      */
     public function getTakeOrderIds(array $where, int $limit = 0)
     {

+ 10 - 127
crmeb/app/listener/crontab/SystemCrontabListener.php

@@ -2,17 +2,10 @@
 
 namespace app\listener\crontab;
 
-use app\services\activity\combination\StorePinkServices;
-use app\services\activity\live\LiveGoodsServices;
-use app\services\activity\live\LiveRoomServices;
-use app\services\agent\AgentManageServices;
-use app\services\order\StoreOrderServices;
-use app\services\order\StoreOrderTakeServices;
-use app\services\product\product\StoreProductServices;
-use app\services\system\attachment\SystemAttachmentServices;
+use app\services\system\crontab\CrontabRunServices;
 use app\services\system\crontab\SystemCrontabServices;
 use crmeb\interfaces\ListenerInterface;
-use think\facade\Log;
+use think\helper\Str;
 use Workerman\Crontab\Crontab;
 
 /**
@@ -22,133 +15,23 @@ class SystemCrontabListener implements ListenerInterface
 {
     public function handle($event): void
     {
+        $systemCrontabServices = app()->make(SystemCrontabServices::class);
+        $crontabRunServices = app()->make(CrontabRunServices::class);
+
         //自动写入文件方便检测是否启动定时任务命令
         new Crontab('*/6 * * * * *', function () {
             file_put_contents(root_path() . 'runtime/.timer', time());
         });
 
-        /** @var SystemCrontabServices $systemTimerServices */
-        $systemCrontabServices = app()->make(SystemCrontabServices::class);
         $list = $systemCrontabServices->selectList(['is_del' => 0, 'is_open' => 1])->toArray();
         foreach ($list as &$item) {
+            //转化小驼峰
+            $functionName = Str::camel($item['mark']);
             //获取定时任务时间字符串
             $timeStr = $this->getTimerStr($item);
-            //未支付自动取消订单
-            if ($item['mark'] == 'order_cancel') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(StoreOrderServices::class)->orderUnpaidCancel();
-                        $this->crontabLog(' 执行未支付自动取消订单');
-                    } catch (\Throwable $e) {
-                        Log::error('自动取消订单失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //拼团到期订单处理
-            elseif ($item['mark'] == 'pink_expiration') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(StorePinkServices::class)->statusPink();
-                        $this->crontabLog(' 执行拼团到期订单处理');
-                    } catch (\Throwable $e) {
-                        Log::error('拼团到期订单处理失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //自动解绑上级绑定
-            elseif ($item['mark'] == 'agent_unbind') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(AgentManageServices::class)->removeSpread();
-                        $this->crontabLog(' 执行自动解绑上级绑定');
-                    } catch (\Throwable $e) {
-                        Log::error('自动解除上级绑定失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //更新直播商品状态
-            elseif ($item['mark'] == 'live_product_status') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(LiveGoodsServices::class)->syncGoodStatus();
-                        $this->crontabLog(' 执行更新直播商品状态');
-                    } catch (\Throwable $e) {
-                        Log::error('更新直播商品状态失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //更新直播间状态
-            elseif ($item['mark'] == 'live_room_status') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(LiveRoomServices::class)->syncRoomStatus();
-                        $this->crontabLog(' 执行更新直播间状态');
-                    } catch (\Throwable $e) {
-                        Log::error('更新直播间状态失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //自动收货
-            elseif ($item['mark'] == 'take_delivery') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(StoreOrderTakeServices::class)->autoTakeOrder();
-                        $this->crontabLog(' 执行自动收货');
-                    } catch (\Throwable $e) {
-                        Log::error('自动收货失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //查询预售到期商品自动下架
-            elseif ($item['mark'] == 'advance_off') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(StoreProductServices::class)->downAdvance();
-                        $this->crontabLog(' 执行预售到期商品自动下架');
-                    } catch (\Throwable $e) {
-                        Log::error('预售到期商品自动下架失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //自动好评
-            elseif ($item['mark'] == 'product_replay') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(StoreOrderServices::class)->autoComment();
-                        $this->crontabLog(' 执行自动好评');
-                    } catch (\Throwable $e) {
-                        Log::error('自动好评失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //清除昨日海报
-            elseif ($item['mark'] == 'clear_poster') {
-                new Crontab($timeStr, function () {
-                    try {
-                        app()->make(SystemAttachmentServices::class)->emptyYesterdayAttachment();
-                        $this->crontabLog(' 执行清除昨日海报');
-                    } catch (\Throwable $e) {
-                        Log::error('清除昨日海报失败,失败原因:' . $e->getMessage());
-                    }
-                });
-            }
-            //
-            else {
-
-            }
-        }
-    }
-
-    /**
-     * 定时任务日志
-     * @param $msg
-     */
-    public function crontabLog($msg)
-    {
-        $timer_log_open = config("log.timer_log", false);
-        if ($timer_log_open){
-            $date = date('Y-m-d H:i:s', time());
-            Log::write($date . $msg, 'crontab');
+            new Crontab($timeStr, function () use ($crontabRunServices, $functionName) {
+                $crontabRunServices->$functionName();
+            });
         }
     }
 

+ 212 - 137
crmeb/app/services/order/StoreOrderCreateServices.php

@@ -13,10 +13,12 @@ namespace app\services\order;
 
 
 use app\services\activity\advance\StoreAdvanceServices;
+use app\services\activity\combination\StorePinkServices;
 use app\services\agent\AgentLevelServices;
 use app\services\activity\coupon\StoreCouponUserServices;
 use app\services\agent\DivisionServices;
 use app\services\pay\PayServices;
+use app\services\pc\OrderServices;
 use app\services\product\product\StoreCategoryServices;
 use app\services\shipping\ShippingTemplatesFreeServices;
 use app\services\shipping\ShippingTemplatesRegionServices;
@@ -25,6 +27,7 @@ use app\services\user\UserInvoiceServices;
 use app\services\wechat\WechatUserServices;
 use app\services\BaseServices;
 use crmeb\exceptions\ApiException;
+use crmeb\exceptions\ApiStatusException;
 use crmeb\services\CacheService;
 use app\dao\order\StoreOrderDao;
 use app\services\user\UserServices;
@@ -116,11 +119,10 @@ class StoreOrderCreateServices extends BaseServices
      * 创建订单
      * @param $uid
      * @param $key
-     * @param $cartGroup
      * @param $userInfo
      * @param $addressId
      * @param $payType
-     * @param bool $useIntegral
+     * @param false $useIntegral
      * @param int $couponId
      * @param string $mark
      * @param int $combinationId
@@ -131,158 +133,231 @@ class StoreOrderCreateServices extends BaseServices
      * @param string $real_name
      * @param string $phone
      * @param int $storeId
-     * @param bool $news
+     * @param false $news
      * @param int $advanceId
-     * @param int $virtual_type
      * @param array $customForm
      * @param int $invoice_id
      * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     * @throws \Throwable
      * @throws \think\db\exception\DataNotFoundException
      * @throws \think\db\exception\DbException
      * @throws \think\db\exception\ModelNotFoundException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
      */
-    public function createOrder($uid, $key, $cartGroup, $userInfo, $addressId, $payType, $useIntegral = false, $couponId = 0, $mark = '', $combinationId = 0, $pinkId = 0, $seckillId = 0, $bargainId = 0, $shippingType = 1, $real_name = '', $phone = '', $storeId = 0, $news = false, $advanceId = 0, $virtual_type = 0, $customForm = [], $invoice_id = 0)
+    public function createOrder($uid, $key, $userInfo, $addressId, $payType, $useIntegral = false, $couponId = 0, $mark = '', $combinationId = 0, $pinkId = 0, $seckillId = 0, $bargainId = 0, $shippingType = 1, $real_name = '', $phone = '', $storeId = 0, $news = false, $advanceId = 0, $customForm = [], $invoice_id = 0)
     {
-        //下单前发票验证
-        if ($invoice_id) {
-            app()->make(UserInvoiceServices::class)->checkInvoice((int)$invoice_id, $uid);
+        /** @var StoreOrderServices $orderService */
+        $storeOrderServices = app()->make(StoreOrderServices::class);
+        $bargainServices = app()->make(StoreBargainServices::class);
+        $cartGroup = $storeOrderServices->getCacheOrderInfo($uid, $key);
+        if (!$cartGroup) {
+            throw new ApiException(410208);
+        }
+        //下单前砍价验证
+        if ($bargainId) {
+            $bargainServices->checkBargainUser((int)$bargainId, $uid);
         }
 
-        /** @var StoreOrderComputedServices $computedServices */
-        $computedServices = app()->make(StoreOrderComputedServices::class);
-        $priceData = $computedServices->computedOrder($uid, $userInfo, $cartGroup, $addressId, $payType, $useIntegral, $couponId, true, $shippingType);
-        /** @var WechatUserServices $wechatServices */
-        $wechatServices = app()->make(WechatUserServices::class);
-        /** @var UserAddressServices $addressServices */
-        $addressServices = app()->make(UserAddressServices::class);
-        if ($shippingType == 1 && $virtual_type == 0) {
-            if (!$addressId) {
-                throw new ApiException(410045);
+        if ($pinkId) {
+            $pinkId = (int)$pinkId;
+            /** @var StorePinkServices $pinkServices */
+            $pinkServices = app()->make(StorePinkServices::class);
+            if ($pinkServices->isPink($pinkId, $uid))
+                throw new ApiStatusException('ORDER_EXIST', 410210, ['orderId' => $storeOrderServices->getStoreIdPink($pinkId, $uid)]);
+            if ($storeOrderServices->getIsOrderPink($pinkId, $uid))
+                throw new ApiStatusException('ORDER_EXIST', 410211, ['orderId' => $storeOrderServices->getStoreIdPink($pinkId, $uid)]);
+            if (!CacheService::checkStock(md5($pinkId), 1, 3) || !CacheService::popStock(md5($pinkId), 1, 3)) {
+                throw new ApiException(410212);
             }
-            if (!$addressInfo = $addressServices->getOne(['uid' => $uid, 'id' => $addressId, 'is_del' => 0]))
-                throw new ApiException(410046);
-            $addressInfo = $addressInfo->toArray();
-        } else {
-            if ((!$real_name || !$phone) && $virtual_type == 0) {
-                throw new ApiException(410245);
-            }
-            $addressInfo['real_name'] = $real_name;
-            $addressInfo['phone'] = $phone;
-            $addressInfo['province'] = '';
-            $addressInfo['city'] = '';
-            $addressInfo['district'] = '';
-            $addressInfo['detail'] = '';
-        }
-        $cartInfo = $cartGroup['cartInfo'];
-        $priceGroup = $cartGroup['priceGroup'];
-        $cartIds = [];
-        $totalNum = 0;
-        $gainIntegral = 0;
-        foreach ($cartInfo as $cart) {
-            $cartIds[] = $cart['id'];
-            $totalNum += $cart['cart_num'];
-            if (!$seckillId) $seckillId = $cart['seckill_id'];
-            if (!$bargainId) $bargainId = $cart['bargain_id'];
-            if (!$combinationId) $combinationId = $cart['combination_id'];
-            if (!$advanceId) $advanceId = $cart['advance_id'];
-            $cartInfoGainIntegral = isset($cart['productInfo']['give_integral']) ? bcmul((string)$cart['cart_num'], (string)$cart['productInfo']['give_integral'], 0) : 0;
-            $gainIntegral = bcadd((string)$gainIntegral, (string)$cartInfoGainIntegral, 0);
-        }
-        if (count($cartInfo) == 1 && isset($cartInfo[0]['productInfo']['presale']) && $cartInfo[0]['productInfo']['presale'] == 1) {
-            $advance_id = $cartInfo[0]['product_id'];
-        } else {
-            $advance_id = 0;
         }
-        $deduction = $seckillId || $bargainId || $combinationId;
-        if ($deduction) {
-            $couponId = 0;
-            $useIntegral = false;
-        }
-        //$shipping_type = 1 快递发货 $shipping_type = 2 门店自提
-        $storeSelfMention = sys_config('store_self_mention') ?? 0;
-        if (!$storeSelfMention) $shippingType = 1;
-
-        $orderInfo = [
-            'uid' => $uid,
-            'order_id' => $this->getNewOrderId('cp'),
-            'real_name' => $addressInfo['real_name'],
-            'user_phone' => $addressInfo['phone'],
-            'user_address' => $addressInfo['province'] . ' ' . $addressInfo['city'] . ' ' . $addressInfo['district'] . ' ' . $addressInfo['detail'],
-            'cart_id' => $cartIds,
-            'total_num' => $totalNum,
-            'total_price' => $priceGroup['totalPrice'],
-            'total_postage' => $shippingType == 1 ? $priceGroup['storePostage'] : 0,
-            'coupon_id' => $couponId,
-            'coupon_price' => $priceData['coupon_price'],
-            'pay_price' => $priceData['pay_price'],
-            'pay_postage' => $priceData['pay_postage'],
-            'deduction_price' => $priceData['deduction_price'],
-            'paid' => 0,
-            'pay_type' => $payType,
-            'use_integral' => $priceData['usedIntegral'],
-            'gain_integral' => $gainIntegral,
-            'mark' => htmlspecialchars($mark),
-            'combination_id' => $combinationId,
-            'pink_id' => $pinkId,
-            'seckill_id' => $seckillId,
-            'bargain_id' => $bargainId,
-            'advance_id' => $advance_id,
-            'cost' => $priceGroup['costPrice'],
-            'add_time' => time(),
-            'unique' => $key,
-            'shipping_type' => $shippingType,
-            'channel_type' => $userInfo['user_type'],
-            'province' => strval($userInfo['user_type'] == 'wechat' || $userInfo['user_type'] == 'routine' ? $wechatServices->value(['uid' => $uid, 'user_type' => $userInfo['user_type']], 'province') : ''),
-            'spread_uid' => 0,
-            'spread_two_uid' => 0,
-            'virtual_type' => $virtual_type,
-            'pay_uid' => $uid,
-            'custom_form' => json_encode($customForm),
-            'division_id' => $userInfo['division_id'],
-            'agent_id' => $userInfo['agent_id'],
-            'staff_id' => $userInfo['staff_id'],
-        ];
-
-        if ($shippingType == 2) {
-            $orderInfo['verify_code'] = $this->getStoreCode();
-            /** @var SystemStoreServices $storeServices */
-            $storeServices = app()->make(SystemStoreServices::class);
-            $orderInfo['store_id'] = $storeServices->getStoreDispose($storeId, 'id');
-            if (!$orderInfo['store_id']) {
-                throw new ApiException(410247);
+        $cartInfo = null;
+        if ($seckillId || $combinationId || $bargainId || $advanceId) {
+            $cartInfo = $cartGroup['cartInfo'];
+            foreach ($cartInfo as $item) {
+                $type = 0;
+                if (!isset($item['product_attr_unique']) || !$item['product_attr_unique']) continue;
+                if ($item['seckill_id']) {
+                    $type = 1;
+                } elseif ($item['bargain_id']) {
+                    $type = 2;
+                } elseif ($item['combination_id']) {
+                    $type = 3;
+                } elseif ($item['advance_id']) {
+                    $type = 6;
+                }
+                if ($type && (!CacheService::checkStock($item['product_attr_unique'], (int)$item['cart_num'], $type) || !CacheService::popStock($item['product_attr_unique'], (int)$item['cart_num'], $type))) {
+                    throw new ApiException(410214, ['cart_num' => $item['cart_num'], 'unit_name' => $item['productInfo']['unit_name']]);
+
+                }
             }
         }
-        /** @var StoreOrderCartInfoServices $cartServices */
-        $cartServices = app()->make(StoreOrderCartInfoServices::class);
-        /** @var StoreSeckillServices $seckillServices */
-        $seckillServices = app()->make(StoreSeckillServices::class);
-        $priceData['coupon_id'] = $couponId;
-        $order = $this->transaction(function () use ($cartIds, $orderInfo, $cartInfo, $key, $userInfo, $useIntegral, $priceData, $combinationId, $seckillId, $bargainId, $cartServices, $seckillServices, $uid, $addressId, $advanceId) {
-            //创建订单
-            $order = $this->dao->save($orderInfo);
-            if (!$order) {
-                throw new ApiException(410200);
+
+        $virtual_type = $cartGroup['cartInfo'][0]['productInfo']['virtual_type'] ?? 0;
+
+        try {
+            //下单前发票验证
+            if ($invoice_id) {
+                app()->make(UserInvoiceServices::class)->checkInvoice((int)$invoice_id, $uid);
             }
-            //记录自提人电话和姓名
-            /** @var UserServices $userService */
-            $userService = app()->make(UserServices::class);
-            $userService->update(['uid' => $uid], ['real_name' => $orderInfo['real_name'], 'record_phone' => $orderInfo['user_phone']]);
-            //占用库存
-            $seckillServices->occupySeckillStock($cartInfo, $key);
-            //积分抵扣
-            if ($priceData['usedIntegral'] > 0) {
-                $this->deductIntegral($userInfo, $useIntegral, $priceData, (int)$userInfo['uid'], $order['id']);
+
+            /** @var StoreOrderComputedServices $computedServices */
+            $computedServices = app()->make(StoreOrderComputedServices::class);
+            $priceData = $computedServices->computedOrder($uid, $userInfo, $cartGroup, $addressId, $payType, $useIntegral, $couponId, true, $shippingType);
+            /** @var WechatUserServices $wechatServices */
+            $wechatServices = app()->make(WechatUserServices::class);
+            /** @var UserAddressServices $addressServices */
+            $addressServices = app()->make(UserAddressServices::class);
+            if ($shippingType == 1 && $virtual_type == 0) {
+                if (!$addressId) {
+                    throw new ApiException(410045);
+                }
+                if (!$addressInfo = $addressServices->getOne(['uid' => $uid, 'id' => $addressId, 'is_del' => 0]))
+                    throw new ApiException(410046);
+                $addressInfo = $addressInfo->toArray();
+            } else {
+                if ((!$real_name || !$phone) && $virtual_type == 0) {
+                    throw new ApiException(410245);
+                }
+                $addressInfo['real_name'] = $real_name;
+                $addressInfo['phone'] = $phone;
+                $addressInfo['province'] = '';
+                $addressInfo['city'] = '';
+                $addressInfo['district'] = '';
+                $addressInfo['detail'] = '';
+            }
+            $cartInfo = $cartGroup['cartInfo'];
+            $priceGroup = $cartGroup['priceGroup'];
+            $cartIds = [];
+            $totalNum = 0;
+            $gainIntegral = 0;
+            foreach ($cartInfo as $cart) {
+                $cartIds[] = $cart['id'];
+                $totalNum += $cart['cart_num'];
+                if (!$seckillId) $seckillId = $cart['seckill_id'];
+                if (!$bargainId) $bargainId = $cart['bargain_id'];
+                if (!$combinationId) $combinationId = $cart['combination_id'];
+                if (!$advanceId) $advanceId = $cart['advance_id'];
+                $cartInfoGainIntegral = isset($cart['productInfo']['give_integral']) ? bcmul((string)$cart['cart_num'], (string)$cart['productInfo']['give_integral'], 0) : 0;
+                $gainIntegral = bcadd((string)$gainIntegral, (string)$cartInfoGainIntegral, 0);
+            }
+            if (count($cartInfo) == 1 && isset($cartInfo[0]['productInfo']['presale']) && $cartInfo[0]['productInfo']['presale'] == 1) {
+                $advance_id = $cartInfo[0]['product_id'];
+            } else {
+                $advance_id = 0;
+            }
+            $deduction = $seckillId || $bargainId || $combinationId;
+            if ($deduction) {
+                $couponId = 0;
+                $useIntegral = false;
+            }
+            //$shipping_type = 1 快递发货 $shipping_type = 2 门店自提
+            $storeSelfMention = sys_config('store_self_mention') ?? 0;
+            if (!$storeSelfMention) $shippingType = 1;
+
+            $orderInfo = [
+                'uid' => $uid,
+                'order_id' => $this->getNewOrderId('cp'),
+                'real_name' => $addressInfo['real_name'],
+                'user_phone' => $addressInfo['phone'],
+                'user_address' => $addressInfo['province'] . ' ' . $addressInfo['city'] . ' ' . $addressInfo['district'] . ' ' . $addressInfo['detail'],
+                'cart_id' => $cartIds,
+                'total_num' => $totalNum,
+                'total_price' => $priceGroup['totalPrice'],
+                'total_postage' => $shippingType == 1 ? $priceGroup['storePostage'] : 0,
+                'coupon_id' => $couponId,
+                'coupon_price' => $priceData['coupon_price'],
+                'pay_price' => $priceData['pay_price'],
+                'pay_postage' => $priceData['pay_postage'],
+                'deduction_price' => $priceData['deduction_price'],
+                'paid' => 0,
+                'pay_type' => $payType,
+                'use_integral' => $priceData['usedIntegral'],
+                'gain_integral' => $gainIntegral,
+                'mark' => htmlspecialchars($mark),
+                'combination_id' => $combinationId,
+                'pink_id' => $pinkId,
+                'seckill_id' => $seckillId,
+                'bargain_id' => $bargainId,
+                'advance_id' => $advance_id,
+                'cost' => $priceGroup['costPrice'],
+                'add_time' => time(),
+                'unique' => $key,
+                'shipping_type' => $shippingType,
+                'channel_type' => $userInfo['user_type'],
+                'province' => strval($userInfo['user_type'] == 'wechat' || $userInfo['user_type'] == 'routine' ? $wechatServices->value(['uid' => $uid, 'user_type' => $userInfo['user_type']], 'province') : ''),
+                'spread_uid' => 0,
+                'spread_two_uid' => 0,
+                'virtual_type' => $virtual_type,
+                'pay_uid' => $uid,
+                'custom_form' => json_encode($customForm),
+                'division_id' => $userInfo['division_id'],
+                'agent_id' => $userInfo['agent_id'],
+                'staff_id' => $userInfo['staff_id'],
+            ];
+
+            if ($shippingType == 2) {
+                $orderInfo['verify_code'] = $this->getStoreCode();
+                /** @var SystemStoreServices $storeServices */
+                $storeServices = app()->make(SystemStoreServices::class);
+                $orderInfo['store_id'] = $storeServices->getStoreDispose($storeId, 'id');
+                if (!$orderInfo['store_id']) {
+                    throw new ApiException(410247);
+                }
+            }
+            /** @var StoreOrderCartInfoServices $cartServices */
+            $cartServices = app()->make(StoreOrderCartInfoServices::class);
+            /** @var StoreSeckillServices $seckillServices */
+            $seckillServices = app()->make(StoreSeckillServices::class);
+            $priceData['coupon_id'] = $couponId;
+            $order = $this->transaction(function () use ($cartIds, $orderInfo, $cartInfo, $key, $userInfo, $useIntegral, $priceData, $combinationId, $seckillId, $bargainId, $cartServices, $seckillServices, $uid, $addressId, $advanceId) {
+                //创建订单
+                $order = $this->dao->save($orderInfo);
+                if (!$order) {
+                    throw new ApiException(410200);
+                }
+                //记录自提人电话和姓名
+                /** @var UserServices $userService */
+                $userService = app()->make(UserServices::class);
+                $userService->update(['uid' => $uid], ['real_name' => $orderInfo['real_name'], 'record_phone' => $orderInfo['user_phone']]);
+                //占用库存
+                $seckillServices->occupySeckillStock($cartInfo, $key);
+                //积分抵扣
+                if ($priceData['usedIntegral'] > 0) {
+                    $this->deductIntegral($userInfo, $useIntegral, $priceData, (int)$userInfo['uid'], $order['id']);
+                }
+                //扣库存
+                $this->decGoodsStock($cartInfo, $combinationId, $seckillId, $bargainId, $advanceId);
+                //保存购物车商品信息
+                $cartServices->setCartInfo($order['id'], $uid, $cartInfo);
+                return $order;
+            });
+
+            //创建开票数据
+            if ($invoice_id) {
+                app()->make(StoreOrderInvoiceServices::class)->makeUp($uid, $order['order_id'], (int)$invoice_id);
+            }
+        } catch (\Throwable $e) {
+            if ($seckillId || $combinationId || $advanceId || $bargainId) {
+                foreach ($cartInfo as $item) {
+                    $value = $item['cart_info'];
+                    $type = 0;
+                    if (!isset($value['product_attr_unique']) || $value['product_attr_unique']) continue;
+                    if ($value['seckill_id']) {
+                        $type = 1;
+                    } elseif ($value['bargain_id']) {
+                        $type = 2;
+                    } elseif ($value['combination_id']) {
+                        $type = 3;
+                    } elseif ($value['advance_id']) {
+                        $type = 6;
+                    }
+                    if ($type) CacheService::setStock($value['product_attr_unique'], (int)$value['cart_num'], $type, false);
+                }
             }
-            //扣库存
-            $this->decGoodsStock($cartInfo, $combinationId, $seckillId, $bargainId, $advanceId);
-            //保存购物车商品信息
-            $cartServices->setCartInfo($order['id'], $uid, $cartInfo);
-            return $order;
-        });
-
-        //创建开票数据
-        if ($invoice_id) {
-            app()->make(StoreOrderInvoiceServices::class)->makeUp($uid, $order['order_id'], (int)$invoice_id);
+            throw $e;
         }
 
         // 订单创建成功后置事件

+ 193 - 0
crmeb/app/services/system/crontab/CrontabRunServices.php

@@ -0,0 +1,193 @@
+<?php
+
+namespace app\services\system\crontab;
+
+use app\services\activity\combination\StorePinkServices;
+use app\services\activity\live\LiveGoodsServices;
+use app\services\activity\live\LiveRoomServices;
+use app\services\agent\AgentManageServices;
+use app\services\order\StoreOrderServices;
+use app\services\order\StoreOrderTakeServices;
+use app\services\product\product\StoreProductServices;
+use app\services\system\attachment\SystemAttachmentServices;
+use think\facade\Log;
+
+/**
+ * 执行定时任务
+ * @author 吴汐
+ * @email 442384644@qq.com
+ * @date 2023/03/01
+ */
+class CrontabRunServices
+{
+    /**
+     * 调用不存在的方法
+     * @param $name
+     * @param $arguments
+     * @return mixed|void
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function __call($name, $arguments)
+    {
+        $this->crontabLog($name . '方法不存在');
+    }
+
+    /**
+     * 定时任务日志
+     * @param $msg
+     */
+    protected function crontabLog($msg)
+    {
+        $timer_log_open = config("log.timer_log", false);
+        if ($timer_log_open) {
+            $date = date('Y-m-d H:i:s', time());
+            Log::write($date . $msg, 'crontab');
+        }
+    }
+
+    /**
+     * 未支付自动取消订单
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function orderCancel()
+    {
+        try {
+            app()->make(StoreOrderServices::class)->orderUnpaidCancel();
+            $this->crontabLog(' 执行未支付自动取消订单');
+        } catch (\Throwable $e) {
+            $this->crontabLog('自动取消订单失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 拼团到期订单处理
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function pinkExpiration()
+    {
+        try {
+            app()->make(StorePinkServices::class)->statusPink();
+            $this->crontabLog(' 执行拼团到期订单处理');
+        } catch (\Throwable $e) {
+            $this->crontabLog('拼团到期订单处理失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 自动解除上级绑定
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function agentUnbind()
+    {
+        try {
+            app()->make(AgentManageServices::class)->removeSpread();
+            $this->crontabLog(' 执行自动解绑上级绑定');
+        } catch (\Throwable $e) {
+            $this->crontabLog('自动解除上级绑定失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 更新直播商品状态
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function liveProductStatus()
+    {
+        try {
+            app()->make(LiveGoodsServices::class)->syncGoodStatus();
+            $this->crontabLog(' 执行更新直播商品状态');
+        } catch (\Throwable $e) {
+            $this->crontabLog('更新直播商品状态失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 更新直播间状态
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function liveRoomStatus()
+    {
+        try {
+            app()->make(LiveRoomServices::class)->syncRoomStatus();
+            $this->crontabLog(' 执行更新直播间状态');
+        } catch (\Throwable $e) {
+            $this->crontabLog('更新直播间状态失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 自动收货
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function takeDelivery()
+    {
+        try {
+            app()->make(StoreOrderTakeServices::class)->autoTakeOrder();
+            $this->crontabLog(' 执行自动收货');
+        } catch (\Throwable $e) {
+            $this->crontabLog('自动收货失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 预售到期商品自动下架
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function advanceOff()
+    {
+        try {
+            app()->make(StoreProductServices::class)->downAdvance();
+            $this->crontabLog(' 执行预售到期商品自动下架');
+        } catch (\Throwable $e) {
+            $this->crontabLog('预售到期商品自动下架失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 自动好评
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function productReplay()
+    {
+        try {
+            app()->make(StoreOrderServices::class)->autoComment();
+            $this->crontabLog(' 执行自动好评');
+        } catch (\Throwable $e) {
+            $this->crontabLog('自动好评失败,失败原因:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 清除昨日海报
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
+    public function clearPoster()
+    {
+        try {
+            app()->make(SystemAttachmentServices::class)->emptyYesterdayAttachment();
+            $this->crontabLog(' 执行清除昨日海报');
+        } catch (\Throwable $e) {
+            $this->crontabLog('清除昨日海报失败,失败原因:' . $e->getMessage());
+        }
+    }
+}

+ 6 - 53
crmeb/app/services/system/crontab/SystemCrontabServices.php

@@ -14,6 +14,7 @@ use app\services\product\product\StoreProductServices;
 use app\services\system\attachment\SystemAttachmentServices;
 use crmeb\exceptions\AdminException;
 use think\facade\Log;
+use think\helper\Str;
 
 class SystemCrontabServices extends BaseServices
 {
@@ -205,67 +206,19 @@ class SystemCrontabServices extends BaseServices
      */
     public function crontabRun()
     {
+        $crontabRunServices = app()->make(CrontabRunServices::class);
         $time = time();
         file_put_contents(root_path() . 'runtime/.timer', $time); //检测定时任务是否正常
         $list = $this->dao->selectList(['is_open' => 1, 'is_del' => 0])->toArray();
         foreach ($list as $item) {
             if ($item['next_execution_time'] < $time) {
-                if ($item['mark'] == 'order_cancel') {
-                    //未支付自动取消订单
-                    app()->make(StoreOrderServices::class)->orderUnpaidCancel();
-                    $this->crontabLog(' 执行未支付自动取消订单');
-                } elseif ($item['mark'] == 'pink_expiration') {
-                    //拼团到期订单处理
-                    app()->make(StorePinkServices::class)->statusPink();
-                    $this->crontabLog(' 执行拼团到期订单处理');
-                } elseif ($item['mark'] == 'agent_unbind') {
-                    //自动解绑上级绑定
-                    app()->make(AgentManageServices::class)->removeSpread();
-                    $this->crontabLog(' 执行自动解绑上级绑定');
-                } elseif ($item['mark'] == 'live_product_status') {
-                    //更新直播商品状态
-                    app()->make(LiveGoodsServices::class)->syncGoodStatus();
-                    $this->crontabLog(' 执行更新直播商品状态');
-                } elseif ($item['mark'] == 'live_room_status') {
-                    //更新直播间状态
-                    app()->make(LiveRoomServices::class)->syncRoomStatus();
-                    $this->crontabLog(' 执行更新直播间状态');
-                } elseif ($item['mark'] == 'take_delivery') {
-                    //自动收货
-                    app()->make(StoreOrderTakeServices::class)->autoTakeOrder();
-                    $this->crontabLog(' 执行自动收货');
-                } elseif ($item['mark'] == 'advance_off') {
-                    //查询预售到期商品自动下架
-                    app()->make(StoreProductServices::class)->downAdvance();
-                    $this->crontabLog(' 执行预售到期商品自动下架');
-                } elseif ($item['mark'] == 'product_replay') {
-                    //自动好评
-                    app()->make(StoreOrderServices::class)->autoComment();
-                    $this->crontabLog(' 执行自动好评');
-                } elseif ($item['mark'] == 'clear_poster') {
-                    //清除昨日海报
-                    app()->make(SystemAttachmentServices::class)->emptyYesterdayAttachment();
-                    $this->crontabLog(' 执行清除昨日海报');
-                }
+                //转化小驼峰方法名
+                $functionName = Str::camel($item['mark']);
+                //执行定时任务
+                $crontabRunServices->$functionName();
                 //写入本次执行时间和下次执行时间
                 $this->dao->update(['mark' => $item['mark']], ['last_execution_time' => $time, 'next_execution_time' => $this->getTimerCycleTime($item)]);
             }
         }
     }
-
-    /**
-     * 定时任务日志
-     * @param $msg
-     * @author 吴汐
-     * @email 442384644@qq.com
-     * @date 2023/02/21
-     */
-    public function crontabLog($msg)
-    {
-        $timer_log_open = config("log.timer_log", false);
-        if ($timer_log_open) {
-            $date = date('Y-m-d H:i:s', time());
-            Log::write($date . $msg, 'crontab');
-        }
-    }
 }

+ 24 - 6
crmeb/app/services/user/UserServices.php

@@ -68,8 +68,15 @@ class UserServices extends BaseServices
 
     /**
      * 获取用户信息
-     * @param $id
-     * @param $field
+     * @param int $uid
+     * @param string $field
+     * @return array|\think\Model|null
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
      */
     public function getUserInfo(int $uid, $field = '*')
     {
@@ -1014,14 +1021,25 @@ class UserServices extends BaseServices
 
     /**
      * 赠送付费会员时长
-     * @param int $uid
-     * @return mixed
-     * */
+     * @param $id
+     * @return array
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/01
+     */
     public function giveLevelTime($id)
     {
-        if (!$this->getUserInfo($id)) {
+        $userInfo = $this->getUserInfo($id);
+        if (!$userInfo) {
             throw new AdminException(400214);
         }
+        $timeDiff = $userInfo['is_ever_level'] == 1 ? '永久' : date('Y-m-d H:i:s', $userInfo['overdue_time']);
+        $dayDiff = intval(($userInfo['overdue_time'] - time()) / 86400);
+        $field[] = Form::input('time_diff', '到期时间', $timeDiff)->style(['width' => '200px'])->readonly(true);
+        if ($userInfo['is_ever_level'] == 0) {
+            $field[] = Form::input('day_diff', '剩余天数', $dayDiff)->style(['width' => '200px'])->readonly(true);
+        }
         $field[] = Form::number('days', '增加时长(天)')->precision(0)->style(['width' => '200px'])->required();
         return create_form('赠送付费会员时长', $field, Url::buildUrl('/user/save_give_level_time/' . $id), 'PUT');
     }

+ 60 - 0
crmeb/crmeb/exceptions/ApiStatusException.php

@@ -0,0 +1,60 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace crmeb\exceptions;
+
+/**
+ * API应用错误信息
+ * Class ApiException
+ * @package crmeb\exceptions
+ */
+class ApiStatusException extends \RuntimeException
+{
+    protected $apiStatus;
+    protected $apiData;
+
+    public function __construct($status, $message, $data = [], $replace = [], $code = 0, \Throwable $previous = null)
+    {
+        if (is_array($message)) {
+            $errInfo = $message;
+            $message = $errInfo[1] ?? '未知错误';
+            if ($code === 0) {
+                $code = $errInfo[0] ?? 400;
+            }
+        }
+
+        if (is_numeric($message)) {
+            $code = $message;
+            $message = getLang($message, $replace);
+        }
+
+        $this->apiData = $data;
+        $this->apiStatus = $status;
+
+        parent::__construct($message, $code, $previous);
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getApiStatus()
+    {
+        return $this->apiStatus;
+    }
+
+    /**
+     * @return array|mixed
+     */
+    public function getApiData()
+    {
+        return $this->apiData;
+    }
+}

+ 2 - 1
crmeb/public/install/crmeb.sql

@@ -33520,7 +33520,8 @@ INSERT INTO `eb_system_config` (`id`, `menu_name`, `type`, `input_type`, `config
 (428, 'queue_open', 'radio', 'input', 26, '0=>关闭\n1=>开启', 1, '', 0, 0, '\"0\"', '消息队列', '是否启用消息队列,启用后提升程序运行速度,启用前必须配置Redis缓存,文档地址:https://doc.crmeb.com/single/crmeb_v4/7217', 0, 1),
 (429, 'get_avatar', 'radio', 'input', 7, '0=>关闭\n1=>开启', 1, '', 0, 0, '\"0\"', '强制获取昵称头像', '是否在小程序用户授权之后,弹窗获取用户的昵称和头像', 0, 1),
 (430, 'share_qrcode', 'radio', 'input', 2, '0=>商城\n1=>公众号', 1, '', 0, 0, '\"0\"', '公众号推广码类型', '公众号生成的推广码类型:商城:扫码直接进入商城,公众号:扫码进入公众号后推送商城的链接', 0, 1),
-(431, 'member_brokerage', 'radio', 'input', 73, '1=>开启\n0=>关闭', 1, '', 0, 0, '\"0\"', '购买付费会员返佣', '购买付费会员是否按照设置的佣金比例进行返佣', 98, 1);
+(431, 'member_brokerage', 'radio', 'input', 73, '1=>开启\n0=>关闭', 1, '', 0, 0, '\"0\"', '购买付费会员返佣', '购买付费会员是否按照设置的佣金比例进行返佣', 98, 1),
+(432, 'user_brokerage_type', 'radio', 'input', 73, '0=>按照商品价格返佣\n1=>按照实际支付价格返佣', 1, '', 0, 0, '\"0\"', '返佣类型', '选择返佣类型,按照商品价格返佣(按照商品售价计算返佣金额)以及按照实际支付价格返佣(按照商品的实际支付价格计算返佣 )', 97, 1);
 
 -- --------------------------------------------------------
 

+ 1 - 1
template/admin/src/pages/system/crontab/index.vue

@@ -3,7 +3,7 @@
     <Alert closable="true">
       <template slot="desc">
         启动定时任务两种方式:<br />
-        1、使用命令启动:php think timer start --d<br />
+        1、使用命令启动:php think timer start --d;如果更改了执行周期、编辑是否开启、删除定时任务需要重新启动下定时任务确保生效;<br />
         2、使用接口触发定时任务,建议每分钟调用一次,接口地址 https://您的域名/api/crontab/run
       </template>
     </Alert>