orders as $shopId => $order) { // 订单取消的情况暂不处理 $shop = $this->getShop($shopId); $faceSheet = new FaceSheet(); $faceSheet->setShop($shop); foreach ($order as $item) { [$sender, $orderInfo, $wpCode] = $this->prepareRequest($item, $shop); $waybill = $this->saveWayBill($item, $shop); if (empty($waybill->id)) { $resp = $faceSheet->getWayBill($sender, $orderInfo, $wpCode); if (isset($resp['pdd_waybill_get_response'])) { $data = $resp['pdd_waybill_get_response']['modules'][0]; $printData = json_decode($data['print_data'], true); $waybill->request_id = $resp['pdd_waybill_get_response']['request_id']; $waybill->encryptedData = $printData['encryptedData']; $waybill->signature = $printData['signature']; $waybill->templateUrl = $printData['templateUrl']; $waybill->ver = $printData['ver']; $waybill->waybill_code = $data['waybill_code']; $waybill->save(); // 返回待打印内容 $contents[$waybill->id] = [ 'addData' => [ 'sender' => $sender, ], 'encryptedData' => $printData['encryptedData'], 'signature' => $printData['signature'], 'templateUrl' => env('APP_URL') . '/ktt/' . $this->sfStdTemplate, 'ver' => $printData['ver'], 'userid' => $waybill->user_id, 'items' => $item['items'], 'documentID' => $waybill->id, 'order_id' => $item['id'], 'participate_no' => $waybill->participate_no, 'note' => $waybill->note, ]; } } else { $contents[$waybill->id] = [ 'addData' => [ 'sender' => $sender, ], 'encryptedData' => $waybill->encryptedData, 'signature' => $waybill->signature, 'templateUrl' => env('APP_URL') . '/ktt/' . $this->sfStdTemplate, 'ver' => $waybill->ver, 'userid' => $waybill->user_id, 'items' => json_decode($waybill->items, true), 'documentID' => $waybill->id, 'order_id' => $item['id'], 'participate_no' => $waybill->participate_no, 'note' => $waybill->note, ]; } } } return $contents; } public function getDocumentsAndOrderIds($contents) { // 打印单,根据商品排序 $items = []; foreach ($contents as $docId => $content) { foreach ($content['items'] as $item) { if ($item['is_single']) { $items[$item['external_sku_id']][] = $docId; } } } ksort($items); $documents = $orderIds = $hasIds = []; foreach ($items as $docIds) { $docIds = array_unique($docIds); $docIds = array_diff($docIds, $hasIds); $hasIds = array_merge($hasIds, $docIds); foreach ($docIds as $docId) { $orderIds[] = $contents[$docId]['order_id']; $documents[] = $contents[$docId]; } } return [$documents, $orderIds]; } private function saveWayBill($order, $shop) { $senderConfig = $shop->senders[0]; $waybill = Waybill::query()->firstOrNew( ['order_sn' => $order['order_sn']] ); $waybill->shop_id = $shop->shop_id; $waybill->object_id = $this->objectId; $waybill->sender_country = $senderConfig['country']; $waybill->sender_province = $senderConfig['province']; $waybill->sender_city = $senderConfig['city']; $waybill->sender_district = $senderConfig['district']; $waybill->sender_detail = $senderConfig['detail']; $waybill->sender_name = $senderConfig['name']; $waybill->sender_mobile = $senderConfig['mobile']; $waybill->recipient_province = $order['recipient_province']; $waybill->recipient_city = $order['recipient_city']; $waybill->recipient_district = $order['recipient_district']; $waybill->recipient_detail = $order['recipient_detail']; $waybill->recipient_name = $order['recipient_name']; $waybill->recipient_mobile = $order['recipient_mobile']; $waybill->user_id = $shop->owner_id; $waybill->wp_code = $senderConfig['wp_code']; $waybill->order_sn = $order['order_sn']; $waybill->order_id = $order['id']; $waybill->participate_no = $order['participate_no']; $waybill->note = $order['note']; $waybill->items = json_encode($order['items'], 256); return $waybill; } private function prepareRequest($order, $shop) { $senderConfig = $shop->senders[0]; $sender = [ 'address' => [ 'city' => $senderConfig['city'], 'country' => $senderConfig['country'], 'detail' => $senderConfig['detail'], 'district' => $senderConfig['district'], 'province' => $senderConfig['province'], ], 'name' => $senderConfig['name'], 'mobile' => $senderConfig['mobile'], ]; $this->setObjectId(); $items = []; foreach ($order['items'] as $item) { if ($item['should_print']) { $items[] = [ 'name' => $item['name'], 'count' => $item['count'], ]; } } $orderInfo = [ 'object_id' => $this->objectId, 'order_info' => [ 'order_channels_type' => 'PDD', 'trade_order_list' => [$order['order_sn']], ], 'package_info' => [ 'items' => $items, ], 'recipient' => [ 'address' => [ 'city' => $order['recipient_city'], 'detail' => $order['recipient_detail'], 'district' => $order['recipient_district'], 'province' => $order['recipient_province'], ], 'name' => $order['recipient_name'], 'mobile' => $order['recipient_mobile'], ], 'template_url' => $this->sfStd, 'user_id' => $shop->owner_id, ]; return [$sender, $orderInfo, $senderConfig['wp_code']]; } public function setObjectId() { $this->objectId = date('YmdHis') . str_pad(mt_rand(1, 9999999), 7, '0', STR_PAD_LEFT); return $this; } public function setOrders($orders) { $orders = $orders->toArray(); // 取出所有组合商品编码 $combinationExternalIds = []; foreach ($orders as $order) { foreach ($order['items'] as $item) { if (false !== strpos($item['external_sku_id'], 'Z')) { $combinationExternalIds[] = $item['external_sku_id']; } } } // 获取组合商品详情 $combinations = []; if ($combinationExternalIds) { $goodsSkus = GoodsSku::query() ->select(['id', 'external_sku_id']) ->with([ 'combinationGoods:id,goods_sku_id,item_id,item_num', 'combinationGoods.goodsSkuItem:id,external_sku_id', ]) ->whereIn('external_sku_id', $combinationExternalIds) ->get() ->toArray(); foreach ($goodsSkus as $goodsSku) { foreach ($goodsSku['combination_goods'] as $item) { $combinations[$goodsSku['external_sku_id']][] = [ 'count' => $item['item_num'], 'external_sku_id' => $item['goods_sku_item']['external_sku_id'], ]; } } } // 订单拆分组合 foreach ($orders as $order) { $info = [ 'id' => $order['id'], 'order_sn' => $order['order_sn'], 'recipient_province' => $order['receiver_address_province'], 'recipient_city' => $order['receiver_address_city'], 'recipient_district' => $order['receiver_address_district'], 'recipient_detail' => $order['receiver_address_detail'], 'recipient_name' => $order['receiver_name'], 'recipient_mobile' => $order['receiver_mobile'], 'participate_no' => $order['is_supplier'] ? $order['participate_no'] : $order['supply_participate_no'], 'note' => $order['business_note'] ? $order['business_note'] . ',' . $order['buyer_memo'] : $order['buyer_memo'], 'items' => [] ]; foreach ($order['items'] as $item) { $count = $item['goods_number'] - $item['already_cancel_number']; if (isset($combinations[$item['external_sku_id']])) { $info['items'][] = [ 'is_single' => false, 'should_print' => true, 'name' => $item['goods_name'], 'count' => $count, 'external_sku_id' => $item['external_sku_id'], ]; foreach ($combinations[$item['external_sku_id']] as $combinationItem) { $info['items'][] = [ 'is_single' => true, 'should_print' => false, 'count' => $count * $combinationItem['count'], 'external_sku_id' => $combinationItem['external_sku_id'], ]; } } else { $info['items'][] = [ 'is_single' => true, 'should_print' => true, 'name' => $item['goods_name'], 'count' => $count, 'external_sku_id' => $item['external_sku_id'], ]; } } $this->orders[$order['shop_id']][] = $info; } return $this; } private function getShop($shopId) { return ShopShip::query() ->select(['id', 'shop_id', 'access_token', 'owner_id']) ->where('shop_id', $shopId) ->with([ 'senders' => function ($query) { $query->orderBy('sort')->first(); } ]) ->first(); } }