Przeglądaj źródła

Merge branch 'dev' of git.huaml.com:zhh/huahuibao into dev

shizhongqi 3 tygodni temu
rodzic
commit
deab143aa6

+ 18 - 3
app-ghs/controllers/OrderController.php

@@ -2773,6 +2773,10 @@ class OrderController extends BaseController
         if (!isset($shopAdmin->super) || $shopAdmin->super != 1) {
             util::fail('超管才能取消订单');
         }
+        //避免重复提交
+        $adminId = $this->adminId;
+        util::checkRepeatCommit($adminId, 3);
+
         $get = Yii::$app->request->get();
         $cashier = $get['cashier'] ?? 0;
         //是否强制取消订单 0不要强制 1强制,没有关单成功也要取消
@@ -2828,15 +2832,26 @@ class OrderController extends BaseController
                         noticeUtil::push("拉卡拉聚合支付关单失败:{$orderSn},原因:{$msg} 原单状态:{$tradeState}", '15280215347');
                         if ($forceCancel == 0) {
                             //返回禁止关单
-                            util::success(['returnStatus' => 'FORBID']);
+                            util::fail('取消失败,如必要请强制取消');
                         }
+                    }else{
+                        noticeUtil::push("关单成功,订单号:{$orderSn} 原单状态:{$tradeState}", '15280215347');
                     }
                 }
                 // 如果状态是 CLOSED 或 CANCELED,则视为已关单,直接继续本地流程
             }
         }
-        OrderService::expire($order);
-        util::complete('已取消');
+        $connection = Yii::$app->db;
+        $transaction = $connection->beginTransaction();
+        try {
+            OrderService::expire($order);
+            $transaction->commit();
+            util::complete('已取消');
+        } catch (\Exception $exception) {
+            $transaction->rollBack();
+            Yii::info("取消原因:" . $exception->getMessage());
+            util::fail('取消失败');
+        }
     }
 
     //获取收款语音播报地址 ssh 20211231

+ 3 - 1
app-ghs/controllers/TestController.php

@@ -505,7 +505,9 @@ class TestController extends BaseController
             //['name' => '深圳每日鲜花批发', 'merchantNo' => '82258405992020E', 'wx' => [902309136, 902307468], 'zfb' => '2088780298610704'],
             //['name' => '滨州花镜鲜花', 'merchantNo' => '82246605992005U', 'wx' => [904373612, 904373338], 'zfb' => '2088780426621723'],
             //['name' => '广州情意鲜花', 'merchantNo' => '8225810599201U2', 'wx' => [904871059, 904872401], 'zfb' => '2088780455410378'],
-            ['name' => '我要花义乌店', 'merchantNo' => '8223380599200A6', 'wx' => [2000005220, 907253683], 'zfb' => '2088780613953851'],
+            //['name' => '我要花义乌店', 'merchantNo' => '8223380599200A6', 'wx' => [2000005220, 907253683], 'zfb' => '2088780613953851'],
+            ['name' => '宣城花农鲜花批发', 'merchantNo' => '82237705992001J', 'wx' => [908946077, 908945971], 'zfb' => '2088780700979012'],
+            ['name' => '亳州花鲜谷', 'merchantNo' => '82238105992004A', 'wx' => [908947821, 908946480], 'zfb' => '2088780700742980'],
             //['name' => '厦门纯彩花艺', 'merchantNo' => '8223930599200LD', 'wx' => [894984230, 894983290], 'zfb' => '2088680439152343'],
             //['name' => '东莞我要花鲜花', 'merchantNo' => '8226020599200R8', 'wx' => [894794554, 894794917], 'zfb' => '2088680405463378'],
             //['name' => '镇江花珩鲜花批发', 'merchantNo' => '82231405992003N', 'wx' => [894925711, 894925626], 'zfb' => '2088680426877183'],

+ 57 - 4
app-hd/controllers/OrderController.php

@@ -98,25 +98,78 @@ class OrderController extends BaseController
     //取消订单 ssh 20221231
     public function actionCancel()
     {
+        $shopAdmin = $this->shopAdmin;
         //避免重复提交
         $adminId = $this->adminId;
-        util::checkRepeatCommit($adminId, 8);
+        util::checkRepeatCommit($adminId, 3);
 
         $get = Yii::$app->request->get();
+        $cashier = $get['cashier'] ?? 0;
+        //是否强制取消订单 0不要强制 1强制,没有关单成功也要取消
+        $forceCancel = $get['forceCancel'] ?? 0;
         $id = $get['id'] ?? 0;
         $order = OrderClass::getById($id, true);
         if ($order->mainId != $this->mainId) {
             util::fail('不是你的订单');
         }
+        //如果收银台的订单,取消时要关闭拉卡拉的订单
+        if ($cashier == 1) {
+            //已取消,不需要再走下面的流程
+            if ($order->status == 5) {
+                util::complete('已取消');
+            }
+            $orderSn = $order->orderSn ?? '';
+
+            $shop = $this->shop;
+            $merchantPrivateKeyPath = Yii::getAlias("@vendor/lakala") . '/production/api_private_key.pem';
+            $lklCertificatePath = Yii::getAlias("@vendor/lakala") . '/production/lkl-apigw-v1.cer';
+            $params = [
+                'appid' => 'OP00002119',
+                'serial_no' => '018b08cfddbd',
+                'merchant_no' => $shop->lklSjNo,
+                'term_no' => $shop->lklScanTermNo,
+                'merchantPrivateKeyPath' => $merchantPrivateKeyPath,
+                'lklCertificatePath' => $lklCertificatePath,
+            ];
+            $laResource = new Lakala($params);
+
+            // 1. 先查询拉卡拉侧订单状态
+            $queryResponse = $laResource->query(['orderSn' => $orderSn]);
+            //响应CODE为BBS00000,仅表示查到了这笔交易。交易本身的成功与否状态,要查看响应报文中的trade_state这个值
+            if (isset($queryResponse['code']) && $queryResponse['code'] == 'BBS00000') {
+                $tradeState = $queryResponse['resp_data']['trade_state'] ?? '';
+
+                // 订单已支付,拦截取消操作
+                if ($tradeState == 'SUCCESS') {
+                    util::fail('已付款,不能取消');
+                }
 
-        $staff = $this->shopAdmin;
+                // 根据拉卡拉聚合支付文档(id=116)及实际情况,判断是否为非终态
+                // INIT:初始化, CREATE:下单成功, DEAL:交易处理中, USERPAYING:支付中, NOTPAY:未支付
+                $pendingStates = ['INIT', 'CREATE', 'DEAL', 'USERPAYING', 'NOTPAY'];
+                if (in_array($tradeState, $pendingStates)) {
+                    $closeParams = ['orderSn' => $orderSn];
+                    $closeResponse = $laResource->close($closeParams);
+                    if (!isset($closeResponse['code']) || $closeResponse['code'] != 'BBS00000') {
+                        $msg = $closeResponse['msg'] ?? '关闭失败';
+                        noticeUtil::push("拉卡拉聚合支付关单失败:{$orderSn},原因:{$msg} 原单状态:{$tradeState}", '15280215347');
+                        if ($forceCancel == 0) {
+                            //返回禁止关单
+                            util::fail('取消失败,如必要请强制取消');
+                        }
+                    }else{
+                        noticeUtil::push("关单成功,订单号:{$orderSn} 原单状态:{$tradeState}", '15280215347');
+                    }
+                }
+            }
+        }
 
         $connection = Yii::$app->db;
         $transaction = $connection->beginTransaction();
         try {
-            OrderClass::setExpire($order, true, $staff);
+            OrderClass::setExpire($order, true, $shopAdmin);
             $transaction->commit();
-            util::complete();
+            util::complete('已取消');
         } catch (\Exception $exception) {
             $transaction->rollBack();
             Yii::info("取消原因:" . $exception->getMessage());

+ 423 - 0
app-mall/controllers/OrderController.php

@@ -903,6 +903,429 @@ class OrderController extends BaseController
 
     }
 
+    /**
+     * 花束+花材合并结算下单
+     * 复用 OrderService::createHdOrder,不改动 buy-item / create-order
+     */
+    public function actionCreateMixOrder()
+    {
+        $post = Yii::$app->request->post();
+        $post['sjId'] = $this->sjId;
+        $post['shopId'] = $this->shopId;
+        $post['payWay'] = 0;
+        $post['mainId'] = $this->mainId ?? 0;
+        $post['userId'] = $this->userId ?? 0;
+
+        $userId = $this->userId;
+        util::checkRepeatCommit($userId, 3);
+
+        $shop = $this->shop;
+        $openShop = \bizHd\shop\classes\ShopClass::getOpenShop($shop);
+        if ($openShop == 0) {
+            util::fail('已休店');
+        }
+
+        $mainId = $this->mainId;
+        if (getenv('YII_ENV') == 'production') {
+            if (in_array($mainId, [40057, 7779, 42940, 26374, 10536, 65381])) {
+                util::fail('暂时无法访问');
+            }
+        }
+
+        $hdId = $post['hdId'] ?? 0;
+        $hd = HdClass::getById($hdId, true);
+        if (empty($hd)) {
+            util::fail('没有找到花店');
+        }
+        if ($hd->shopId != $this->shopId) {
+            util::fail('不是你的花店');
+        }
+        $post['hdName'] = $hd->name ?? '';
+        // 合并结算沿用花材购物车的客户身份(花店客户)
+        $hdCustomId = $hd->customId ?? 0;
+        $custom = CustomClass::getById($hdCustomId, true);
+        if (empty($custom)) {
+            util::fail('没有找到客户');
+        }
+        $customName = $custom->name ?? '';
+        $post['customId'] = $hdCustomId;
+        $post['customName'] = $customName;
+        $post['customNamePy'] = stringUtil::py($customName);
+
+        $productJson = $post['product'] ?? '';
+        if (empty($productJson)) {
+            util::fail('请选择商品');
+        }
+        $productList = json_decode($productJson, true);
+        if (empty($productList) || !is_array($productList)) {
+            util::fail('请选择商品');
+        }
+
+        $itemRows = [];
+        $goodsRows = [];
+        foreach ($productList as $idx => $row) {
+            $property = intval($row['property'] ?? -1);
+            if ($property === 1) {
+                $itemRows[$idx] = $row;
+            } elseif ($property === 0) {
+                $goodsRows[$idx] = $row;
+            } else {
+                util::fail('商品类型错误');
+            }
+        }
+        if (empty($itemRows) && empty($goodsRows)) {
+            util::fail('请选择商品');
+        }
+
+        // ---- 花材校验与定价 ----
+        $productInfoList = [];
+        if (!empty($itemRows)) {
+            $ids = array_unique(array_filter(array_map(function ($r) {
+                return intval($r['productId'] ?? 0);
+            }, $itemRows)));
+            $productInfoList = ProductClass::getByIds($ids, null, 'id');
+            if (empty($productInfoList)) {
+                util::fail('花材不存在');
+            }
+            $presellData = [];
+            $nowTime = strtotime(date("Y-m-d"));
+            foreach ($productInfoList as $currentInfo) {
+                if (!isset($currentInfo['mainId']) || $currentInfo['mainId'] != $this->mainId) {
+                    util::fail('只能选一家的商品,请清空重新选呢');
+                }
+                $presell = $currentInfo['presell'] ?? 0;
+                $presellData[] = $presell;
+                if ($presell == 1) {
+                    if (empty($post['reachDate'])) {
+                        util::fail('请选择配送或取货日期');
+                    }
+                    $sendTimeWant = $post['reachDate'];
+                    if (strtotime($sendTimeWant) < $nowTime) {
+                        util::fail('不能选择过去时间');
+                    }
+                    $hasDateStr = $currentInfo['presellDate'] ?? [];
+                    $hasDate = explode(',', trim($hasDateStr));
+                    if (empty($hasDate)) {
+                        util::fail('预售日期有问题,请提醒门店');
+                    }
+                    if (!in_array(strtotime($sendTimeWant), $hasDate)) {
+                        util::fail("有预售花材在{$sendTimeWant}没到货");
+                    }
+                    $post['presell'] = 1;
+                }
+            }
+            if (count($productInfoList) != count($ids)) {
+                util::fail('存在无效花材');
+            }
+            $presellData = array_unique($presellData);
+            if (count($presellData) > 1) {
+                util::fail('预售和非预售花材不能一起下单');
+            }
+        }
+
+        $connection = Yii::$app->db;
+        $transaction = $connection->beginTransaction();
+        $transactionFinished = false;
+        register_shutdown_function(function () use (&$transactionFinished, $transaction) {
+            if ($transactionFinished) {
+                return;
+            }
+            \bizHd\product\classes\ProductClass::rollbackLimitBuySnapshot();
+            if ($transaction->isActive) {
+                $transaction->rollBack();
+            }
+        });
+
+        try {
+            $orderValidTime = !getenv('ORDER_VALID_TIME') ? 600 : getenv('ORDER_VALID_TIME');
+            $post['deadline'] = time() + $orderValidTime;
+            $post['reachDate'] = !empty($post['reachDate']) ? $post['reachDate'] : date("Y-m-d");
+            $post['needPrint'] = dict::getDict('needPrint', 'need');
+            $post['fromType'] = dict::getDict('fromType', 'mall');
+            $post['store'] = 0;
+            $user = $this->user;
+            $post['bookMobile'] = $user->mobile ?? '';
+            $post['bookName'] = $user->name ?? '';
+            $hasPay = 0;
+
+            $modifyPrice = 0;
+            $totalWeight = 0;
+            $totalNum = 0;
+            $totalReachDiscount = 0;
+            $resolvedProduct = [];
+
+            $priceMap = \bizGhs\custom\classes\CustomClass::$levelPriceKeyMap;
+            $addPriceMap = \bizGhs\custom\classes\CustomClass::$levelAddPriceKeyMap;
+
+            foreach ($productList as $eleKey => $element) {
+                $property = intval($element['property'] ?? -1);
+                if ($property === 1) {
+                    $level = 0;
+                    $productId = $element['productId'];
+                    $product = $productInfoList[$productId] ?? null;
+                    if (empty($product)) {
+                        util::fail('有花材信息没有找到');
+                    }
+                    $num = $element['num'] ?? 0;
+                    $limitKey = \bizHd\product\classes\ProductClass::LIMIT_BUY_KEY . $productId;
+                    $hasBuyNum = Yii::$app->redis->executeCommand('HGET', [$limitKey, $hdCustomId]);
+                    $hasBuyNum = $num + ($hasBuyNum == null ? 0 : $hasBuyNum);
+                    $price = \bizGhs\product\classes\ProductClass::getFinalPrice($product, $level, $priceMap, $addPriceMap, 0, $num, $hasBuyNum);
+                    $reachNum = $product['reachNum'] ?? 0;
+                    $reachNumDiscount = $product['reachNumDiscount'] ?? 0;
+                    if ($reachNum > 0 && $num >= $reachNum && $reachNumDiscount > 0) {
+                        $currentReachDiscount = bcmul($reachNumDiscount, $num, 2);
+                        $totalReachDiscount = bcadd($totalReachDiscount, $currentReachDiscount, 2);
+                    }
+                    $currentTotal = bcmul($price, $num, 2);
+                    $modifyPrice = bcadd($modifyPrice, $currentTotal, 2);
+                    $weight = $product['weight'] ?? 0;
+                    $currentWeight = bcmul($num, $weight, 2);
+                    $totalWeight = bcadd($totalWeight, $currentWeight, 2);
+                    $totalNum = bcadd($totalNum, $num);
+                    if (($product['limitBuy'] ?? 0) > 0) {
+                        $product['productId'] = $productId;
+                        \bizHd\product\classes\ProductClass::handleLimitBuy($product, $hdCustomId, floatval($num));
+                    }
+                    $resolvedProduct[] = [
+                        'productId' => $productId,
+                        'num' => $num,
+                        'itemId' => $element['itemId'] ?? 0,
+                        'unitType' => $element['unitType'] ?? 0,
+                        'property' => 1,
+                        'unitPrice' => $price,
+                    ];
+                } else {
+                    $goodsId = intval($element['goodsId'] ?? 0);
+                    $specGoodsId = intval($element['specGoodsId'] ?? 0);
+                    $saleGoodsId = intval($element['productId'] ?? 0);
+                    $goodsNum = isset($element['num']) && $element['num'] > 0 ? $element['num'] : 1;
+                    if ($goodsId <= 0 && $saleGoodsId > 0) {
+                        $probe = GoodsClass::getById($saleGoodsId, true);
+                        if (!empty($probe)) {
+                            $masterId = intval($probe->masterId ?? 0);
+                            if ($masterId > 0) {
+                                $goodsId = $masterId;
+                                $specGoodsId = $saleGoodsId;
+                            } else {
+                                $goodsId = $saleGoodsId;
+                            }
+                        }
+                    }
+                    if ($goodsId <= 0) {
+                        util::fail('请选择花束商品');
+                    }
+                    $goodsInfo = GoodsClass::getById($goodsId, true);
+                    if (empty($goodsInfo)) {
+                        util::fail('没有找到花束商品');
+                    }
+                    if ($goodsInfo->mainId != $mainId) {
+                        util::fail('不是你的商品');
+                    }
+                    if ($specGoodsId > 0) {
+                        $specGoods = GoodsClass::getById($specGoodsId, true);
+                        if (empty($specGoods) || $specGoods->mainId != $mainId || $specGoods->masterId != $goodsId || $specGoods->delStatus != 0 || $specGoods->status != 1) {
+                            util::fail('规格不可用');
+                        }
+                        $goodsInfo = $specGoods;
+                        $saleGoodsId = $specGoodsId;
+                    } else {
+                        if ((int)($goodsInfo->masterId ?? 0) === 0) {
+                            $hasSpecs = GoodsClass::getByCondition(['masterId' => $goodsId, 'delStatus' => 0], true);
+                            if (!empty($hasSpecs)) {
+                                util::fail('请选择规格');
+                            }
+                        }
+                        $saleGoodsId = $goodsId;
+                    }
+                    $stock = $goodsInfo->stock ?? 0;
+                    $stockSet = $goodsInfo->stockSet ?? 0;
+                    if ($stockSet == 1 && $stock <= 0) {
+                        util::fail('花束库存不足');
+                    }
+                    $goodsData = $goodsInfo->attributes;
+                    $ret = \bizHd\goods\classes\GoodsClass::getFinalPrice($goodsData, $shop, $custom, []);
+                    $priceType = $ret['priceType'] ?? 0;
+                    if ($priceType == 0) {
+                        util::fail('花束没有价格,不能下单');
+                    }
+                    $unitPrice = $ret['price'] ?? 0;
+                    if ($unitPrice <= 0) {
+                        util::fail('花束没有价格,不能下单');
+                    }
+                    $currentTotal = bcmul($unitPrice, $goodsNum, 2);
+                    $modifyPrice = bcadd($modifyPrice, $currentTotal, 2);
+                    $weight = $goodsInfo->weight ?? 0;
+                    if ($weight > 5) {
+                        $weight = 5;
+                    }
+                    $currentWeight = bcmul($weight, $goodsNum, 2);
+                    $totalWeight = bcadd($totalWeight, $currentWeight, 2);
+                    $totalNum = bcadd($totalNum, $goodsNum);
+                    $resolvedProduct[] = [
+                        'productId' => $saleGoodsId,
+                        'unitType' => 0,
+                        'property' => 0,
+                        'unitPrice' => $unitPrice,
+                        'num' => $goodsNum,
+                    ];
+                }
+            }
+
+            $post['product'] = $resolvedProduct;
+            $post['reachDiscountPrice'] = $totalReachDiscount;
+            unset($post['sendCost']);
+
+            $mapSet = ShopClass::hasIntraCity($this->shop);
+            $openIntraCity = $mapSet['openIntraCity'] ?? 0;
+            $hasItem = !empty($itemRows);
+            // 含花材(含混合)按花材报价 goodsType=1;纯花束按 0
+            $quoteGoodsType = $hasItem ? 1 : 0;
+
+            if (isset($post['sendType']) && $post['sendType'] == 2 && $openIntraCity != 0) {
+                if ($openIntraCity == 2) {
+                    util::fail('不能使用跑腿');
+                }
+                if (empty($post['long']) || empty($post['lat'])) {
+                    util::fail('位置错误');
+                }
+                $shopLat = $shop->lat ?? '';
+                $shopLong = $shop->long ?? '';
+                if (empty($shopLat) || empty($shopLong)) {
+                    util::fail('商家门店地址定位未设置,编号263');
+                }
+                $distance = 0;
+                $sendCost = 0;
+                $prefix = 'PT-MIX-' . $this->mainId . '-';
+                $orderSn = $prefix . round(microtime(true) * 1000);
+                $ghsInfo = ['mainId' => $this->mainId, 'shopId' => $this->shopId];
+                try {
+                    if (empty($post['deliveryPlatform'])) {
+                        util::fail('请选择跑腿');
+                    }
+                    $quoteCustom = $this->user;
+                    if ($quoteGoodsType === 0) {
+                        $quoteCustom = (object)[
+                            'name' => $post['receiveUserName'] ?? '',
+                            'mobile' => $post['receiveMobile'] ?? '',
+                            'fullAddress' => $post['address'] ?? '',
+                            'floor' => $post['floor'] ?? '',
+                            'dist' => '',
+                            'lat' => $post['lat'],
+                            'long' => $post['long'],
+                            'address' => $post['address'] ?? '',
+                            'city' => $post['city'] ?? '',
+                        ];
+                    }
+                    $quoteResult = DeliveryQuoteUtil::getDeliveryQuote([
+                        'productList' => $resolvedProduct,
+                        'deliveryPlatform' => $post['deliveryPlatform'],
+                        'deliveryBracketContent' => $post['deliveryBracketContent'] ?? '',
+                        'ghsInfo' => $ghsInfo,
+                        'custom' => $quoteCustom,
+                        'order' => [
+                            'orderSn' => $orderSn,
+                            'goodsType' => $quoteGoodsType,
+                            'itemTotalAmount' => $modifyPrice,
+                            'remark' => $post['remark'] ?? '',
+                        ],
+                        'mainId' => $this->mainId,
+                        'productCount' => $totalNum,
+                    ]);
+                    $sendCost = $quoteResult['sendCost'];
+                    $distance = $quoteResult['sendDistance'];
+                } catch (\Exception $e) {
+                    util::fail($e->getMessage());
+                }
+                $post['sendCost'] = $sendCost;
+                $post['sendDistance'] = $distance;
+                $modifyPrice = bcadd($modifyPrice, $sendCost, 2);
+            }
+
+            // 红包(归属花店客户,与 buy-item 一致)
+            $hbId = $post['hbId'] ?? 0;
+            $hb = null;
+            if ($hbId > 0) {
+                $hb = HbClass::getById($hbId, true);
+                if (!empty($hb)) {
+                    if ($hb->customId != $hdCustomId) {
+                        util::fail('不是你的红包');
+                    }
+                    if ($hb->amount != $post['hbAmount']) {
+                        util::fail('红包金额不相等');
+                    }
+                    if ($hb->status == 1) {
+                        util::fail('红包已使用');
+                    }
+                    if ($hb->status == -1) {
+                        util::fail('红包已作废');
+                    }
+                    if ($hb->endTime < time()) {
+                        $hb->status = -1;
+                        $hb->save();
+                        util::fail('红包已失效');
+                    }
+                    if ($hb->beginTime > time()) {
+                        util::fail('红包可使用期未到');
+                    }
+                    if (bccomp($modifyPrice, $hb->minConsume) == -1) {
+                        util::fail("不满足最低消费金额{$hb->minConsume}元");
+                    }
+                    $modifyPrice = bcsub($modifyPrice, $hb->amount, 2);
+                } else {
+                    util::fail('红包无效');
+                }
+            }
+
+            $sendType = $post['sendType'] ?? 0;
+            if ($sendType != 1) {
+                if (empty($post['reachPeriod'])) {
+                    util::fail('请选择配送时间哈');
+                }
+                $post['reachTime'] = strtotime($post['reachDate'] . ' ' . $post['reachPeriod']);
+            }
+
+            $post['bigNum'] = $totalNum;
+            $post['modifyPrice'] = $modifyPrice;
+            $return = \bizHd\order\services\OrderService::createHdOrder($post, $custom, $hasPay);
+
+            if (!empty($hb)) {
+                $hb->status = 1;
+                $hb->orderId = $return->id;
+                $hb->save();
+            }
+
+            if ($return->sendType == 2) {
+                $ext = ShopExtClass::getByCondition(['shopId' => $return->shopId], true, null, 'id,shopId,thirdSend');
+                if (!empty($ext) && $ext->thirdSend == 1) {
+                    util::fail('本店暂不能使用跑腿呢');
+                }
+            }
+
+            $transaction->commit();
+            $transactionFinished = true;
+            \bizHd\product\classes\ProductClass::clearLimitBuyRollbackSnapshot();
+
+            $orderSn = $return->orderSn ?? '';
+            $orderPrice = $return->orderPrice ?? ($return->actPrice ?? 0);
+            $id = $return->id ?? 0;
+            $getPayType = dict::getDict('getPayType');
+            util::success([
+                'orderSn' => $orderSn,
+                'totalPrice' => $orderPrice,
+                'couponId' => 0,
+                'id' => $id,
+                'getPayType' => $getPayType,
+            ]);
+        } catch (\Exception $e) {
+            $transaction->rollBack();
+            \bizHd\product\classes\ProductClass::rollbackLimitBuySnapshot();
+            $transactionFinished = true;
+            Yii::error("合并下单失败:" . $e->getMessage());
+            util::fail('下单失败');
+        }
+    }
+
     //下单要用到的相关信息 ssh 2019.12.6
     public function actionOrderRelate()
     {

+ 2 - 2
app-pt/views/main/app.php

@@ -237,8 +237,8 @@
             const downloadUrls = {
                 'xiaohuabao': 'https://api.shop.hzghd.com/1312.apk', // 销花宝APP下载链接
                 'huazhanggui': 'https://api.shop.hzghd.com/246.apk', // 花掌柜APP下载链接
-                'huazhanggui_cashier': 'https://api.shop.hzghd.com/219.apk', // 花掌柜收银下载链接
-                'xiaohuabao_cashier': 'https://api.shop.hzghd.com/176.apk' // 销花宝收银下载链接
+                'huazhanggui_cashier': 'https://api.shop.hzghd.com/220.apk', // 花掌柜收银下载链接
+                'xiaohuabao_cashier': 'https://api.shop.hzghd.com/178.apk' // 销花宝收银下载链接
             };
             const url = downloadUrls[appType];
             if (url && url !== '#') {

+ 36 - 0
biz-hd/goods/classes/GoodsClass.php

@@ -505,6 +505,40 @@ class GoodsClass extends BaseClass
         return $data;
     }
 
+    /**
+     * 批量判断主商品是否启用多规格(masterId 指向该商品且未删除)
+     * @param array $goodsIds 主商品 id 列表
+     * @return array [goodsId => 1|0]
+     */
+    public static function getSpecEnabledMap($goodsIds)
+    {
+        $map = [];
+        if (empty($goodsIds)) {
+            return $map;
+        }
+        $goodsIds = array_values(array_unique(array_filter(array_map('intval', $goodsIds))));
+        if (empty($goodsIds)) {
+            return $map;
+        }
+        foreach ($goodsIds as $gid) {
+            $map[$gid] = 0;
+        }
+        $specs = self::getAllByCondition(
+            ['masterId' => ['in', $goodsIds], 'delStatus' => 0],
+            null,
+            'masterId'
+        );
+        if (!empty($specs)) {
+            foreach ($specs as $spec) {
+                $masterId = intval($spec['masterId'] ?? 0);
+                if ($masterId > 0) {
+                    $map[$masterId] = 1;
+                }
+            }
+        }
+        return $map;
+    }
+
     public static function groupGoodsBaseInfo($list, $shop, $custom, $params)
     {
         if (empty($list)) {
@@ -514,6 +548,7 @@ class GoodsClass extends BaseClass
         $goodsIds = array_column($list, 'id');
         // 一次性获取所有商品的分类关系
         $allGoodsCategories = GoodsCategoryClass::getGoodsHasCategoryIdsBatch($goodsIds);
+        $specEnabledMap = self::getSpecEnabledMap($goodsIds);
         // &$val 这里的指向符号不能去掉
         foreach ($list as $key => &$val) {
             $id = $val['id'];
@@ -548,6 +583,7 @@ class GoodsClass extends BaseClass
             $val['classId'] = 0;
             $val['bigPrice'] = $price;
             $val['smallPrice'] = $price;
+            $val['specEnabled'] = intval($specEnabledMap[$id] ?? 0);
         }
         //获取最终需要的价格
         return $list;

+ 8 - 1
biz-hd/homePageConfig/classes/HomePageModuleClass.php

@@ -618,17 +618,24 @@ class HomePageModuleClass
     public static function formatGoodsRows($rows)
     {
         $list = [];
+        $goodsIds = [];
+        foreach ($rows as $row) {
+            $goodsIds[] = intval($row['id'] ?? 0);
+        }
+        $specEnabledMap = GoodsClass::getSpecEnabledMap($goodsIds);
         foreach ($rows as $row) {
+            $id = intval($row['id']);
             $cover = strval($row['cover'] ?? '');
             $coverUrl = $cover !== '' ? imgUtil::groupImg($cover) . '?x-oss-process=image/resize,m_fill,h_700,w_700' : '';
             $list[] = [
-                'id' => intval($row['id']),
+                'id' => $id,
                 'name' => strval($row['name'] ?? ''),
                 'price' => floatval($row['price'] ?? 0),
                 'stock' => intval($row['stock'] ?? 0),
                 'cover' => $cover,
                 'coverUrl' => $coverUrl,
                 'sold' => intval(bcadd($row['actualSold'] ?? 0, $row['sold'] ?? 0)),
+                'specEnabled' => intval($specEnabledMap[$id] ?? 0),
             ];
         }
         return $list;

+ 6 - 3
biz-hd/purchase/services/PurchaseService.php

@@ -129,7 +129,7 @@ class PurchaseService extends BaseService
             'transType' => $transType,
             'sendDistance' => $sendDistance,
         ];
-        $result = OrderClass::addOrder($arr,$custom);
+        $result = OrderClass::addOrder($arr, $custom);
         $respond->saleId = $result['id'];
         $respond->save();
 
@@ -299,7 +299,7 @@ class PurchaseService extends BaseService
         $id = $purchase->id;
         $purchase = PurchaseClass::cancel($id);
         $saleId = $purchase->saleId;
-        
+
         //销售单失效
         OrderClass::cancel($saleId);
         $couponId = $purchase->hbId;
@@ -574,7 +574,10 @@ class PurchaseService extends BaseService
 
         $info->payStatus = 1;
         $payTime = date("Y-m-d H:i:s");
-        $info->payTime = $payTime;
+        if (empty($info->payTime) || $info->payTime == '0000-00-00 00:00:00') {
+            //如果外面没有设置支付时间,即账单时间,则赋值支付时间
+            $info->payTime = $payTime;
+        }
 
         if ($payWay == dict::getDict('payWay', 'debtPay')) {
             //欠款支付(批发开单若销售单已 payAfter,沿用其待结,支持开单余额抵挂账)

+ 4 - 4
common/components/book.php

@@ -104,7 +104,7 @@ class book
             ['style' => 'info', 'value' => '提现时间:第2天上午7点前,就会把昨天收入的钱打到你的银行卡,一般法人收款,也可以委托别人收款,签委托协议即可。',],
             ['style' => 'info', 'value' => '根据你自身门店情况,选择以下套餐。下面列出的套餐,已经过全国200多家鲜花批发店和13万家花店磨合使用,非常成熟好用,请放心购买使用,以下套餐已含第一年年费。',],
             ['style' => 'miniTitle', 'value' => '软件的研发成本巨大,不管是年费、费率和套餐,都已经底价,已无商谈的空间,请理解。付费后不支持退货。',],
-            ['style' => 'miniTitle', 'value' => '以下硬件请通过我们来购买,公司统一跟厂家采购,售后各方面比较有保障。',],
+            ['style' => 'miniTitle', 'value' => '小票机、收银机等硬件请通过我们这边购买,自行在外面购买,将无法连接使用,因为参数各方面不匹配。',],
             ['style' => 'info', 'value' => '小票机和标签机,使用的是飞鹅4G带切刀版本,比较好维护,里面带流量卡的,第二年开始,每年要充60块话费。请不要贪便宜使用wifi版,维护成本很高,很容易出问题。',],
             ['style' => 'info', 'value' => '提供上门培训服务,培训时间3天,需报销差旅住宿费用,公司地址在福建厦门。',],
             ['style' => 'info', 'value' => '首家年费1580元,第二家起每家年费800元',],
@@ -116,7 +116,7 @@ class book
             ['style' => 'blankLine', 'value' => '',],
             ['style' => 'smallTitle', 'value' => '门店版-单屏收银',],
             ['style' => 'info', 'value' => '整套软件功能(一年)',],
-            ['style' => 'info', 'value' => '色单屏收银机1台',],
+            ['style' => 'info', 'value' => '色单屏收银机1台',],
             ['style' => 'info', 'value' => '扫码枪1台',],
             ['style' => 'info', 'value' => '收款小闪1个',],
             ['style' => 'info', 'value' => '收钱箱1个',],
@@ -130,7 +130,7 @@ class book
             ['style' => 'blankLine', 'value' => '',],
             ['style' => 'smallTitle', 'value' => '门店版-双屏收银',],
             ['style' => 'info', 'value' => '整套软件功能(一年)',],
-            ['style' => 'info', 'value' => '色双屏收银机1台',],
+            ['style' => 'info', 'value' => '色双屏收银机1台',],
             ['style' => 'info', 'value' => '扫码枪1台',],
             ['style' => 'info', 'value' => '收款小闪1个',],
             ['style' => 'info', 'value' => '收钱箱1个',],
@@ -285,4 +285,4 @@ class book
         ],
     ];
 
-}
+}