['name' => '达达', 'logo' => '📦'], 'shunfeng' => ['name' => '顺丰同城', 'logo' => '🚚'], 'meituan' => ['name' => '美团', 'logo' => '🍱'], 'fengniao' => ['name' => '蜂鸟', 'logo' => '🍜'], 'huolala' => ['name' => '货拉拉跑腿', 'logo' => '🚛'], 'shansong' => ['name' => '闪送', 'logo' => '⚡'], 'didi' => ['name' => '滴滴', 'logo' => '🚗'], 'uu' => ['name' => 'UU跑腿', 'logo' => '🛵'] ]; $mainId = $this->mainId; $allDeliveries = DeliveryAuthTokenClass::getAllByCondition(['mainId' => $mainId]); foreach ($allDeliveries as $d) { $item = [ 'id' => $d['platform'], 'logo' => $platformLogos[$d['platform']]['logo'], 'name' => $platformLogos[$d['platform']]['name'], 'is_authorized' => true, 'balance' => $d['balance'] / 100.0, 'access_type' => 'oauth' ]; $platformList[] = $item; } util::success(['platformList' => $platformList]); } // 花店发货时 -- 获取多个平台报价 public function actionHdAllDeliveryQuotes() { $post = Yii::$app->request->post(); $orderTime = $post['pickupTime']; $weight = $post['weight']; $remark = $post['remark'] ?? ''; $adminId = $this->adminId; util::checkRepeatCommit($adminId, 3); $orderId = intval($post['orderId']); $order = OrderClass::getById($orderId); if (empty($order)) { util::fail('没有找到订单'); } if ($order['mainId'] != $this->mainId) { util::fail('不是你的订单'); } if (empty($order['address'])) { util::fail('客户地址缺失'); } if (empty($order['long']) || empty($order['lat'])) { util::fail('客户地址信息缺失'); } if (empty($order['receiveMobile'])) { util::fail('收货人手机为空'); } if (empty($order['receiveUserName'])) { util::fail('收货人名称为空'); } $shop = ShopClass::getById($this->shopId); $order['weight'] = $weight; $order['remark'] = $remark; $ds = new DispatchService($this->mainId); $platformQuotes = $ds->getAllPlatformPrice($order, $shop, $orderTime); if (isset($platformQuotes['error'])) { util::fail($platformQuotes['error']); } // 格式化各平台报价为前端展示格式 $deliveryList = $ds->formatPlatformQuotesForDisplay($platformQuotes); // 按 price 从低到高排序 ArrayHelper::multisort($deliveryList, 'price', SORT_ASC); $ret['deliveryList'] = $deliveryList; util::success($ret, "success"); } // 花店快捷开单时 -- 获取各跑腿平台报价 public function actionQuickOrderDeliveryQuotes() { $post = Yii::$app->request->post(); $orderTime = date('Y-m-d H:i:s'); // --------- $customId ---------- $customId = $post['customId']; $custom = \bizHd\custom\classes\CustomClass::getById($customId, true); if (empty($custom)) { util::fail('获取custom数据失败'); } // 生成随机订单号,不要跟原来的混起来,跑腿-销售单- $prefix = 'PT-XSD-' . $this->mainId . '-'; $orderSn = $prefix . round(microtime(true) * 1000); //构建出 Order 数据 $order = [ 'orderSn' => $orderSn, 'customName' => $custom['name'], 'customMobile' => $custom['mobile'], 'fullAddress' => $custom['fullAddress'], 'floor' => $custom['floor'], 'dist' => $custom['dist'], 'lat' => $custom['lat'], 'long' => $custom['long'], 'address' => $custom['address'], //'toAddress' => $order['address'], 'city' => $custom['city'], 'weight' => $post['weight'] ?? 1, 'remark' => $post['remark'] ?? '', 'prePrice' => floatval($post['totalPrice'] ?? 0), 'actPrice' => floatval($post['totalPrice'] ?? 0), ]; $shop = ShopClass::getById($this->shopId); $ds = new DispatchService($this->mainId); $ds->validateOrder($order); //对 $order 进行验证 $platformQuotes = $ds->getAllPlatformPrice($order, $shop, $orderTime); if (isset($platformQuotes['error'])) { util::fail($platformQuotes['error']); } // 格式化各平台报价为前端展示格式 $deliveryList = $ds->formatPlatformQuotesForDisplay($platformQuotes); // 按 price 从低到高排序 ArrayHelper::multisort($deliveryList, 'price', SORT_ASC); $ret['deliveryList'] = $deliveryList; util::success($ret, "success"); } // 花店向批发买花时 -- 获取各跑腿平台报价 public function actionAllDeliveryQuotes() { $post = Yii::$app->request->post(); $orderTime = date('Y-m-d H:i:s'); // --------- $ghsShopId ---------- $ghsId = $post['ghsId'] ?? 0; $ghs = GhsClass::getById($ghsId, true); if (empty($ghs)) { util::fail('获取批发商失败'); } $ghsShopId = $ghs->shopId; // --------- $customId $customId = $ghs->customId ?? 0; $custom = \bizGhs\custom\classes\CustomClass::getById($customId, true); // 批发的 custom if (empty($custom)) { util::fail('获取custom数据失败'); } // 生成随机订单号,不要跟原来的混起来,跑腿-销售单- $prefix = 'PT-XSD-' . $ghs->mainId . '-'; $orderSn = $prefix . round(microtime(true) * 1000); //构建出 Order 数据 $order = [ 'orderSn' => $orderSn, 'customName' => $custom['name'], 'customMobile' => $custom['mobile'], 'fullAddress' => $custom['fullAddress'], 'floor' => $custom['floor'], 'dist' => $custom['dist'], 'lat' => $custom['lat'], 'long' => $custom['long'], 'address' => $custom['address'], //'toAddress' => $order['address'], 'city' => $custom['city'], 'weight' => $post['weight'] ?? 1, 'remark' => $post['remark'] ?? '', 'prePrice' => floatval($post['totalPrice'] ?? 0), 'actPrice' => floatval($post['totalPrice'] ?? 0), ]; $ghsShop = ShopClass::getById($ghsShopId); $ds = new DispatchService($ghs->mainId); $ds->validateOrder($order); //对 $order 进行验证 $platformQuotes = $ds->getAllPlatformPrice($order, $ghsShop, $orderTime); if (isset($platformQuotes['error'])) { util::fail($platformQuotes['error']); } $deliveryList = []; // 格式化各平台报价为前端展示格式 $deliveryList = $ds->formatPlatformQuotesForDisplay($platformQuotes); // 按 price 从低到高排序 ArrayHelper::multisort($deliveryList, 'price', SORT_ASC); $ret['deliveryList'] = $deliveryList; util::success($ret, "success"); } // 创建订单(真实下单) public function actionCreateOrder() { $form = new CreateOrderForm(); $form->loadAndValidate(); $post = $form->getAttributes(); $orderId = $post['orderId'] ?? 0; // xhOrder.id $params = $post['allParams'] ?? ''; $platform = $params['en_name'] ?? '';// 平台英文名,$post['platform'] 是中文 if (empty($platform)) { util::fail('请选择跑腿'); } $pickupTime = $post['pickupTime'] ?? ''; $params['mainId'] = $this->mainId; $params['ip'] = Yii::$app->request->userIP; $params['weight'] = $post['weight'] ?? 1; $params['remark'] = $post['remark'] ?? ''; $params['total_price_fen'] = $post['price'] ?? ''; $params['pickupTime'] = $pickupTime['value'] ?? ''; $Order = OrderClass::getById($orderId, true); if (empty($Order)) { util::fail('没有找到订单'); } if ($Order->mainId != $this->mainId) { util::fail('不是你的订单'); } if (!in_array($Order['sendStatus'], [-4, -2, -1])) { Yii::error('订单已经发过跑腿'); util::fail('订单已经发过跑腿'); } //避免连续点击的重复提交 ssh $adminId = $this->adminId; util::checkRepeatCommit($adminId, 3); $ds = new DispatchService($this->mainId, $platform); $ret = $ds->createOrder($Order, 'xhOrder', $this->shopId, $params); if (isset($ret['code']) && $ret['code'] == 0) { $gdo = HdDeliveryOrderClass::getByCondition(['mainId' => $this->mainId, 'orderId' => $ret['data']['orderId']]); if (empty($gdo)) { $data = [ 'mainId' => $this->mainId, 'shopId' => $this->shopId, 'deliveryId' => $ret['platform'], 'hdOrderId' => $orderId, 'orderId' => $ret['data']['orderId'], 'distance' => $ret['data']['distance'], 'fee' => $ret['data']['fee'], 'orderStatus' => 0 ]; // createdAt 中保存了滴滴跑腿订单的后半截数据 if($platform == 'didi'){ $data['createdAt'] = date('Y-m-d H:i:s', $ret['data']['timeStamp']); } HdDeliveryOrderClass::add($data); } else { Yii::info('重复创建订单'); } //更新订单 $Order->sendDistance = $ret['data']['distance']; $Order->sendStatus = 0; $Order->deliveryId = $platform; $Order->sendType = 2;// 2指跑腿 $Order->status = 3;// 3配送中 $save = $Order->save(); if ($save) { util::success($ret, "success"); } else { util::fail('创建跑腿失败(更新订单失败)'); } } else { if (isset($ret['msg'])) { util::fail($ret['msg']); } util::fail('创建跑腿失败'); } } // 取消订单 public function actionCancelOrder() { $form = new CancelOrderForm(); $form->loadAndValidate(); $post = $form->getAttributes(); $deliveryOrderId = $post['orderId'] ?? 0; // 平台的orderId, $platform = $post['platform'] ?? ''; $hdOrderId = $post['hdOrderId']; // 先获取配送订单,确保 $gdo 始终可用 $hdo = HdDeliveryOrderClass::getByCondition(['mainId' => $this->mainId, 'hdOrderId' => $hdOrderId, 'orderStatus' => ['not in', [-1, -2]]], true, 'id DESC'); if (empty($hdo)) { util::fail('未找到对应订单: ' . $hdOrderId); } $orderId = $hdo->hdOrderId; // 如果没有提供平台和订单ID,从配送订单中获取 if ($platform == '' || $deliveryOrderId == 0) { $deliveryOrderId = $hdo->orderId; $platform = $hdo->deliveryId; } $ds = new DispatchService($this->mainId, $platform); $cancelCostCent = 0; if ($platform == 'fengniao') { //请求订单预取消接口,获取是否可取消。如果运单状态不允许取消,则直接返回 $cancelParams = ['order_id' => $deliveryOrderId, 'order_cancel_code' => $post['order_cancel_code']]; $res = $ds->getAdapter()->preCancelOrder($cancelParams); if ($res['code'] != 0) { util::fail('运单状态不允许取消'); } $cancelCostCent = $res['data']['actual_cancel_cost_cent']; //取消实际需金额(单位:分) } if ($platform == 'shunfeng') { //请求订单预取消接口,获取是否可取消。如果运单状态不允许取消,则直接返回 $cancelParams = ['order_id' => $deliveryOrderId, 'order_cancel_code' => $post['order_cancel_code']]; $res = $ds->getAdapter()->preCancelOrder($cancelParams); if ($res['code'] != 0) { util::fail('运单状态不允许取消'); } $post['order_type'] = 1; //查询订单ID类型 1、顺丰订单号 2、商家订单号 } if ($platform == 'dada') { $order = OrderClass::getById($orderId, false, 'id,orderSn'); $deliveryOrderId = $order['orderSn']; } if ($platform == 'didi') { $order = OrderClass::getById($orderId, false, 'id,orderSn'); $timeStamp = strtotime($hdo->createdAt); $post['outOrderNo'] = \common\components\delivery\platform\didi\Didi::generateUniOroder($order['orderSn'], $timeStamp); $post['cancelSource'] = 1; // TODO 要增加取消码判断 } $post['order_cancel_role'] = 1; //1:商户取消, 2:用户取消 $ret = $ds->cancelOrder($deliveryOrderId, $post); if ($ret['code'] == 0) { $Order = OrderClass::getById($hdOrderId, true, 'id, sendDistance, sendStatus, deliveryId'); $Order->sendDistance = 0; if(in_array($platform, ['shunfeng', 'fengniao'])){ // 测试发现取消配送没回调的平台,统一在这主动更新配送状态 $Order->sendStatus = -1; // 更新跑腿订单与批发订单状态 $hdo->orderStatus = -1; HdNotifyClass::ptErrorNotify($Order->id, '门店主动取消'); } $hdo->cancelCost = $ret['platform'] !== 'fengniao' ? $ret['data']['deductionFee'] : $cancelCostCent; // 由于蜂鸟平台返回的扣费不一样造成 if (!$hdo->save()) { Yii::error('保存配送订单失败: ' . json_encode($hdo->errors)); util::fail('保存配送订单失败'); } $Order->status = 2; //$Order->deliveryId = ''; //$Order->sendTip = 0; //零售xhOrder表没这个字段 if (!$Order->save()) { Yii::error('保存批发订单失败: ' . json_encode($Order->errors)); util::fail('保存批发订单失败'); } util::success($ret['data'], "success"); } util::fail('失败:'.$ret['msg']); } /** * 获取订单取消原因 */ public function actionCancelReason() { $post = Yii::$app->request->post(); $hdOrderId = $post['hdOrderId']; $platform = $post['platform']; $hdo = HdDeliveryOrderClass::getByCondition(['mainId' => $this->mainId, 'hdOrderId' => $hdOrderId, 'orderStatus!=' => -1], true); if (!empty($hdo)) { $orderId = $hdo->orderId; //$platform = $gdo->deliveryId; } else { util::fail('未找到对应订单: ' . $hdOrderId); } $ds = new DispatchService($this->mainId, $platform); $ret = $ds->getCancelReasonList($orderId); if ($ret['code'] == 0) { util::success($ret['data']); } else { Yii::error('获取订单取消原因:' . json_encode($ret)); util::fail($ret['msg']); } } public function actionAddress() { $post = Yii::$app->request->post(); $adminId = $this->adminId; util::checkRepeatCommit($adminId, 4); $orderId = intval($post['orderId']); $order = OrderClass::getById($orderId, false, 'fullAddress, long, lat'); $shop = ShopClass::getById($this->shopId, false, 'fullAddress, long, lat'); $ret = [ "sender" => [ 'name' => '门店', 'address' => $shop['fullAddress'], 'long' => $shop['long'], 'lat' => $shop['lat'], ], "receiver" => [ 'name' => '客户', 'address' => $order['fullAddress'], 'long' => $order['long'], 'lat' => $order['lat'], ], ]; util::success($ret, "success"); } public function actionCancelAuth() { // 有平台有对应的取消授权接口,有的没有。 // 有的就对接下,然后再删除数据。没有的直接删除数据就行。 $platform = Yii::$app->request->get('platform'); $delivery = DeliveryAuthTokenClass::getByCondition(['mainId' => $this->mainId, 'platform' => $platform]); if ($delivery) { if ($platform == 'shansong') { $auth = new \common\components\delivery\platform\shansong\Auth(); $result = $auth->cancelAuthorization($delivery['accessToken']); if ($result['success']) { // 授权已取消 } else { if ($result['message'] == '商户未授权,请授权后再次尝试') { Yii::info($this->mainId . '--商户未授权,请授权后再次尝试'); } else { util::fail('取消授权失败:' . $result['message']); } } } } else { util::fail('取消授权失败,数据未找到'); } $ret = DeliveryAuthTokenClass::deleteByCondition(['mainId' => $this->mainId, 'platform' => $platform]); if ($ret > 0) { util::success(['message' => '取消授权成功']); } else { util::fail('取消授权失败'); } } public function actionGetAuthUrl() { $platform = Yii::$app->request->get('platformId'); $Auth = new \common\components\delivery\services\AuthService(); $mainId = $this->mainId; switch ($platform) { case 'shansong': $Auth->shansongAuth($mainId); break; case 'huolala': $Auth->huolalaAuth($mainId); break; case 'fengniao': $Auth->fengniaoAuth($mainId); break; case 'dada': $Auth->dadaAuth($mainId); break; case 'shunfeng': $Auth->shunfengAuth($mainId); break; case 'didi': break; default: util::error(-1, $platform . '不存在'); break; } } }