db->beginTransaction(); try { $data = Yii::$app->request->post(); if (empty($data['deliveryGoods'])) { throw new Exception('缺少发货商品信息'); } $delivery->load($data); $delivery->order_id = $order->id; if (!$delivery->save()) { throw new Exception('保存物流信息失败'); } /*发货商品数据*/ $orderStatus = self::saveDeliveryGoods($data['deliveryGoods'], $delivery->id); $order->status = $orderStatus; if (!$order->save()) { throw new Exception('order shipping_status update false'); } if ($orderStatus == Order::STATUS_SHIPMENT_PORTION || Delivery::find()->where(['!=', 'id', $delivery->id])->andWhere(['order_id' => $delivery->order_id])->one()) { $delivery->type = Delivery::TYPE_SHIPMENT_PORTION; } else { $delivery->type = Delivery::TYPE_SHIPMENT_ALL; } if (!$delivery->save()) { throw new Exception('保存物流信息失败'); } $transaction->commit(); return ['status' => true]; } catch (Exception $e) { $transaction->rollBack(); return ['status' => false, 'info' => $e->getMessage()]; } } /** * @param $deliveryGoods * @param $delivery_id * @return int * @throws Exception * 保存发货商品信息 */ private static function saveDeliveryGoods($deliveryGoods, $delivery_id) { $status = Order::STATUS_SHIPMENT_ALL; foreach ($deliveryGoods as $id => $goodsCount) { if ($goodsCount < 0) { throw new Exception('操作异常,发货数量不能小于0'); } elseif ($goodsCount == 0) { continue; } $orderGoods = OrderGoods::findOne($id); /*如果是发货数量不是全部,订单状态为部分发货*/ $deliveryGoodsCount = DeliveryGoods::find()->where(['order_goods_id' => $id])->sum('goods_count'); if (($deliveryGoodsCount + $goodsCount) < $orderGoods->goods_count) { //如果已发货数量未达到order_goods里的数量 $status = Order::STATUS_SHIPMENT_PORTION; } elseif (($deliveryGoodsCount + $goodsCount) > $orderGoods->goods_count) { throw new Exception('操作异常,现发货数量超过之前缺少的发货数量'); } $model = new DeliveryGoods(); $model->delivery_id = $delivery_id; $model->order_goods_id = $orderGoods->id; $model->goods_id = $orderGoods->goods_id; $model->goods_name = $orderGoods->goods_name; $model->goods_count = $goodsCount; if (!$model->save()) { throw new Exception('delivery_goods save false'); } } return $status; } /** * @param $order_id * @return array * 查询订单发货商品信息 */ public static function deliveryGoodsInfo($order_id) { $delivery = Delivery::findAll(['order_id' => $order_id]); /*如果该订单是首次发货*/ if ($delivery) { /*获取订单已发的商品和未发的商品*/ return self::getDeliveryGoodsInfo($delivery); } else { $unShippedGoods = OrderGoods::find()->where(['order_id' => $order_id])->all(); return ['unShipped' => $unShippedGoods]; } } /** * @param $delivery * @return array * 获取订单已发的商品和未发的商品 */ public static function getDeliveryGoodsInfo($delivery) { $data = []; $deliveryIds = []; foreach ($delivery as $k => $value) { $deliveryIds[] = $value->id; $orderGoodsIds = DeliveryGoods::find() ->select('order_goods_id') ->where(['delivery_id' => $value->id]) ->andWhere(['>', 'goods_count', 0]) ->column(); $value->deliveryGoods = OrderGoods::findAll($orderGoodsIds); } $data['shipped'] = $delivery; $deliveryGoodsData = []; $deliveryGoods = DeliveryGoods::find() ->select(['order_goods_id', 'goods_count']) ->where(['delivery_id' => $deliveryIds]) ->andWhere(['>', 'goods_count', 0]) ->all(); foreach ($deliveryGoods as $k => $value) { $orderGoods = $value->order_goods_id; if (isset($deliveryGoodsData[$orderGoods])) { $deliveryGoodsData[$orderGoods] += $value->goods_count; } else { $deliveryGoodsData[$orderGoods] = $value->goods_count; } } foreach ($deliveryGoodsData as $k => $value) { //键名为order_goods_id,键值为对应的已发货数量 $orderGoods = OrderGoods::findOne($k); //通过orderGoods_id找到订单商品 if ($value < $orderGoods->goods_count) { //如果已发货数量未达到order_goods里的数量 $orderGoods->lack_number = $orderGoods->goods_count - $value; $data['unShipped'][] = $orderGoods; } } return $data; } /** * @param $orderId * @return array|mixed * @throws NotFoundHttpException * 查询物流接口 */ public static function queryLogistics($orderId) { $delivery = Delivery::findOne(['order_id' => $orderId]); if (!$delivery) { throw new NotFoundHttpException('发货信息未找到'); } $cache = Yii::$app->cache; if ($cache->exists($delivery->shipping_id)) { return $cache->get($delivery->shipping_id); } $logisticsParams = self::createLogisticsParam($delivery); //创建参数(包括签名的处理) $url = self::LOGISTICS_URL . '?' . $logisticsParams; $result = Json::decode(file_get_contents($url), false); if (isset($result->showapi_res_body)) { $cache->set($delivery->shipping_id, $result->showapi_res_body, 7200); //设置缓存2个小时 return $result->showapi_res_body; } else { return []; } } /** * @param Delivery $delivery * @return string * 查询物流 创建参数(包括签名的处理) */ private static function createLogisticsParam($delivery) { $params = [ 'showapi_appid' => Yii::$app->params['logistics_config']['logistics_appid'], 'com' => $delivery->shipping_name , //物流单位 'nu' => $delivery->invoice_sn, //运单号 //添加其他参数 ]; $paraStr = ""; $signStr = ""; ksort($params); foreach ($params as $key => $val) { if ($key != '' && $val != '') { $signStr .= $key.$val; $paraStr .= $key . '=' . urlencode($val) . '&'; } } $signStr .= Yii::$app->params['logistics_config']['logistics_secret']; //排好序的参数加上secret,进行md5,将md5后的值作为参数,便于服务器的效验 $sign = strtolower(md5($signStr)); $paraStr .= 'showapi_sign=' . $sign; return $paraStr; } }