-
1.在店铺管理中, 点击下载
-
2.编写Store控制器, 用于下载订单, 并将下载结果传输到MQ中
<?php
namespace app\admin\controller;
use app\admin\model\Order;
use app\admin\model\OrderItems;
use app\common\controller\Backend;
use app\admin\model\Store as StoreModel;
use SellingPartnerApi\Api\CatalogItemsV0Api;
use SellingPartnerApi\Configuration;
use SellingPartnerApi\Endpoint;
use SellingPartnerApi\Api\SellersV1Api as SellersApi;
use SellingPartnerApi\Api\OrdersV0Api;
use SellingPartnerApi\Api\TokensV20210301Api;
use SellingPartnerApi\Model\TokensV20210301\CreateRestrictedDataTokenRequest;
use app\common\service\RabbitMQService;
// 店铺管理
class Store extends Backend
{
protected $model = null;
protected $preExcludeFields = ['id', 'create_time', 'update_time'];
protected $quickSearchField = ['id', 'title'];
protected $limit = 10;
public function initialize()
{
parent::initialize();
$this->model = new \app\admin\model\Store;
}
/**
* 下载订单
*/
public function getOrder()
{
$store_id = request()->get('store_id');
$storeModel = new StoreModel();
$store = $storeModel->find($store_id)->toArray();
if ($store['type'] != 2 && $store['type'] != 3) {
dd("非亚马逊账号");
}
$conf = [
'access_key' => $store['spapi_amazon_access_key'],
'access_secret' => $store['spapi_amazon_access_secret'],
'role_arn' => $store['spapi_amazon_role_arn'],
'refresh_token' => $store['spapi_amazon_refresh_token'],
'client_id' => $store['spapi_amazon_client_id'],
'client_secret' => $store['spapi_amazon_client_secret'],
'endpoint' => $store['spapi_amazon_endpoint'],
'marketplaceId' => $store['api_marketplaceid'],
];
switch ($conf['endpoint']) {
case 'NA':
$endpoint = Endpoint::NA;
break;
case 'EU':
$endpoint = Endpoint::EU;
break;
case 'FE':
$endpoint = Endpoint::FE;
break;
}
$connect = new Configuration([
"lwaClientId" => $conf['client_id'],
"lwaClientSecret" => $conf['client_secret'],
"lwaRefreshToken" => $conf['refresh_token'],
"awsAccessKeyId" => $conf['access_key'],
"awsSecretAccessKey" => $conf['access_secret'],
"endpoint" => $endpoint,
"roleArn" => $conf['role_arn'],
]);
if ($store['last_time']) {
$stime = $store['last_time'];
} else {
$stime = date('Y-m-d H:i:s', strtotime("-15 days"));
}
$this->downloadOrder($connect, $store, $stime);
dd("下载完成");
}
// 下载订单, 并放到队列中
public function downloadOrder($connect, $store, $stime)
{
$apiInstance = new OrdersV0Api($connect);
// $apiInstance = new \SellingPartnerApi\Api\OrdersApi($connect);
$format = "Y-m-d\TH:i:s.\\0\\0\\0\\Z";
$created_after = gmdate($format, strtotime($stime));
$data_elements = null;
if ($store['type'] == 3) {
if ($store['is_pii']) $data_elements = ['buyerInfo', 'shippingAddress'];
$fulfillment_channels = 'MFN';
} else {
$fulfillment_channels = 'AFN';
}
$result = $apiInstance->getOrders([$store['api_marketplaceid']], $created_after, null, null, null, null, $fulfillment_channels, null, null, null, $this->limit, null, null, null, null, null, null, $data_elements);
$result = $result['payload']['orders'];
$list = [];
$code = uniqid();
$time = date("Y-m-d H:i:s");
foreach ($result as $key=>$item) {
$orderData = $this->objectToArray($item); // 订单对象转数组
$orderData = $this->formatOrder(end($orderData)); // 格式化订单数组
$orderItem = $apiInstance->getOrderItems($item['amazon_order_id']);
$orderItem = $this->objectToArray($orderItem['payload']['order_items']);
foreach ($orderItem as $vo) {
$orderData['order_items'] = $this->formatOrder(end($vo));
}
// 将其他信息保存到数组中
$orderData['info'] = [
'store_id' => $store['id'],
'store_name' => $store['title'],
'code' => $code,
'type' => $fulfillment_channels,
'download_time' => $time
];
// $list[] = $orderData;
// 直接推送到队列中, 不查询数据库
$rabbitMQService = new RabbitMQService();
$rabbitMQService->sendMessage(json_encode($orderData), 'order');
}
}
/**
* 特殊的对象转数组方法
*/
function objectToArray($obj) {
$obj = (array)$obj;
$result = [];
foreach ($obj as $key => $value) {
if (gettype($value) == 'object' || gettype($value) == 'array') {
$result[$key] = $this->objectToArray($value); // 递归调用
} else {
$result[$key] = $value;
}
}
return $result;
}
// 格式化订单结果(包括订单和订单商品)
function formatOrder($items, $test = 0) {
$list = [];
foreach ($items as $key=>$item) {
if ($test && preg_match('/container/', $key)) {
return $item;
}
if (is_array($item)) {
$list[$key] = $this->formatOrder($item, 1);
} else {
if (preg_match('/container/', $key)) {
$list[$key] = end($item);
} else {
$list[$key] = $item;
}
}
}
return $list;
}
// 将null改为空白
public function formatNull($array, $replacement = '')
{
foreach ($array as &$value) {
if (is_array($value)) {
$value = $this->formatNull($value, $replacement);
} elseif ($value === null) {
$value = $replacement;
}
}
return $array;
}
// 检查插入的数据中, 是否有数组, 如果有, 设为空白
public function checkItems($data)
{
foreach ($data as &$item) {
if (is_array($item)) {
$item = '';
}
}
return $data;
}
}
- 3.在MQ消费者中读取队列, 进行订单入库
<?php
declare (strict_types = 1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use app\common\service\RabbitMQService;
use app\admin\model\Order;
use app\admin\model\OrderItems;
use app\admin\model\Store;
class GetMqOrder extends Command
{
private $command = 'get_mq_order';
public $queueOrder = 'order';
public $queueOrderFail = 'order_fail';
protected function configure()
{
$this->setName($this->command)->setDescription('从MQ中获取订单');
}
protected function execute(Input $input, Output $output)
{
$output->writeln('开始获取订单');
$rabbitMQService = new RabbitMQService();
$callback = function ($msg) {
$this->log("您有新的订单");
$result = json_decode($msg->getBody(), true);
if (is_array($result)) {
$res = $this->saveOrder($result);
if ($res !== true) {
$this->resend($result);
}
} else {
$this->resend($result);
}
};
$rabbitMQService->consumeQueue($callback, $this->queueOrder);
}
/**
* 保存订单
*/
protected function saveOrder($order)
{
// 保存到数据库中
$orderModel = new Order();
$itemModel = new OrderItems();
$storeModel = new Store();
$isExists = $orderModel->where('amazon_order_id', $order['amazon_order_id'])->count();
if ($isExists) {
$this->log("订单已存在: {$order['amazon_order_id']}");
return true;
}
$time = date("Y-m-d H:i:s");
// 创建要插入的数据数组
$insertData = [];
$insertData['store_id'] = $order['info']['store_id'];
$insertData['store_name'] = $order['info']['store_name'];
$insertData['code'] = $order['info']['code'];
$insertData['type'] = $order['info']['type'];
$insertData['download_time'] = $order['info']['download_time'];
$insertData['amazon_order_id'] = $order['amazon_order_id'];
$insertData['seller_order_id'] = $order['seller_order_id'];
$insertData['purchase_date'] = $order['purchase_date'];
$insertData['last_update_date'] = $order['last_update_date'];
$insertData['order_status'] = $order['order_status'];
$insertData['fulfillment_channel'] = $order['fulfillment_channel'];
$insertData['sales_channel'] = $order['sales_channel'];
$insertData['order_channel'] = $order['order_channel'];
$insertData['ship_service_level'] = $order['ship_service_level'];
$insertData['order_total_currency_code'] = $order['order_total']['currency_code'];
$insertData['order_total_amount'] = $order['order_total']['amount'];
$insertData['number_of_items_shipped'] = $order['number_of_items_shipped'];
$insertData['number_of_items_unshipped'] = $order['number_of_items_unshipped'];
$insertData['payment_execution_detail'] = $order['payment_execution_detail'];
$insertData['payment_method'] = $order['payment_method'];
$insertData['payment_method_details'] = implode(', ', $order['payment_method_details']);
$insertData['marketplace_id'] = $order['marketplace_id'];
$insertData['shipment_service_level_category'] = $order['shipment_service_level_category'];
$insertData['easy_ship_shipment_status'] = $order['easy_ship_shipment_status'];
$insertData['cba_displayable_shipping_label'] = $order['cba_displayable_shipping_label'];
$insertData['order_type'] = $order['order_type'];
$insertData['earliest_ship_date'] = $order['earliest_ship_date'];
$insertData['latest_ship_date'] = $order['latest_ship_date'];
$insertData['earliest_delivery_date'] = $order['earliest_delivery_date'];
$insertData['latest_delivery_date'] = $order['latest_delivery_date'];
$insertData['is_business_order'] = $order['is_business_order'];
$insertData['is_prime'] = $order['is_prime'];
$insertData['is_premium_order'] = $order['is_premium_order'];
$insertData['is_global_express_enabled'] = $order['is_global_express_enabled'];
$insertData['replaced_order_id'] = $order['replaced_order_id'];
$insertData['is_replacement_order'] = $order['is_replacement_order'];
$insertData['promise_response_due_date'] = $order['promise_response_due_date'];
$insertData['is_estimated_ship_date_set'] = $order['is_estimated_ship_date_set'];
$insertData['is_sold_by_ab'] = $order['is_sold_by_ab'];
$insertData['is_iba'] = $order['is_iba'];
$insertData['default_ship_from_location_address'] = $order['default_ship_from_location_address'];
$insertData['buyer_invoice_preference'] = $order['buyer_invoice_preference'];
$insertData['buyer_tax_information'] = $order['buyer_tax_information'];
$insertData['fulfillment_instruction'] = $order['fulfillment_instruction'];
$insertData['is_ispu'] = $order['is_ispu'];
$insertData['is_access_point_order'] = $order['is_access_point_order'];
$insertData['marketplace_tax_info'] = $order['marketplace_tax_info'];
$insertData['seller_display_name'] = $order['seller_display_name'];
$insertData['shipping_address_name'] = $order['shipping_address']['name'];
$insertData['shipping_address_line1'] = $order['shipping_address']['address_line1'];
$insertData['shipping_address_line2'] = $order['shipping_address']['address_line2'];
$insertData['shipping_address_line3'] = $order['shipping_address']['address_line3'];
$insertData['shipping_address_city'] = $order['shipping_address']['city'];
$insertData['shipping_address_county'] = $order['shipping_address']['county'];
$insertData['shipping_address_district'] = $order['shipping_address']['district'];
$insertData['shipping_address_state_or_region'] = $order['shipping_address']['state_or_region'];
$insertData['shipping_address_municipality'] = $order['shipping_address']['municipality'];
$insertData['shipping_address_postal_code'] = $order['shipping_address']['postal_code'];
$insertData['shipping_address_country_code'] = $order['shipping_address']['country_code'];
$insertData['shipping_address_phone'] = $order['shipping_address']['phone'];
$insertData['shipping_address_type'] = $order['shipping_address']['address_type'];
$insertData['buyer_email'] = $order['buyer_info']['buyer_email'];
$insertData['buyer_name'] = $order['buyer_info']['buyer_name'];
$insertData['buyer_county'] = $order['buyer_info']['buyer_county'];
$insertData['buyer_tax_info'] = $order['buyer_info']['buyer_tax_info'];
$insertData['purchase_order_number'] = $order['buyer_info']['purchase_order_number'];
$insertData['automated_shipping_settings'] = $order['automated_shipping_settings'];
$insertData['has_regulated_items'] = $order['has_regulated_items'];
$insertData['electronic_invoice_status'] = $order['electronic_invoice_status'];
$insertData['item_approval_types'] = $order['item_approval_types'];
$insertData['item_approval_status'] = $order['item_approval_status'];
$orderId = $orderModel->create($insertData);
// 插入订单商品
if ($orderId->id) {
$this->log("订单入库成功:" .$order['amazon_order_id']);
$items = $order['order_items'];
$items = $this->formatNull($items);
$data = [];
$data['order_id'] = $orderId->id;
$data['order_sn'] = $order['amazon_order_id']; // 来自订单
$data['asin'] = $items['asin'];
$data['seller_sku'] = $items['seller_sku'];
$data['order_item_id'] = $items['order_item_id'];
$data['title'] = $items['title'];
$data['quantity_ordered'] = $items['quantity_ordered'];
$data['quantity_shipped'] = $items['quantity_shipped'];
$data['product_info_number_of_items'] = $items['product_info']['number_of_items'];
$data['points_granted'] = $items['points_granted'];
$data['item_price_currency_code'] = $items['item_price']['currency_code'];
$data['item_price_amount'] = $items['item_price']['amount'];
$data['shipping_price_currency_code'] = $data['shipping_price_amount'] = '';
if ($items['shipping_price']) {
$data['shipping_price_currency_code'] = $items['shipping_price']['currency_code'];
$data['shipping_price_amount'] = $items['shipping_price']['amount'];
}
$data['item_tax_currency_code'] = $items['item_tax']['currency_code'];
$data['item_tax_amount'] = $items['item_tax']['amount'];
$data['shipping_tax_currency_code'] = $data['shipping_tax_amount'] = '';
if ($items['shipping_tax']) {
$data['shipping_tax_currency_code'] = $items['shipping_tax']['currency_code'];
$data['shipping_tax_amount'] = $items['shipping_tax']['amount'];
}
$data['shipping_discount_currency_code'] = $data['shipping_discount_amount'] = '';
if ($items['shipping_discount']) {
$data['shipping_discount_currency_code'] = $items['shipping_discount']['currency_code'];
$data['shipping_discount_amount'] = $items['shipping_discount']['amount'];
}
$data['shipping_discount_tax_currency_code'] = $data['shipping_discount_tax_amount'] = '';
if ($items['shipping_discount_tax']) {
$data['shipping_discount_tax_currency_code'] = $items['shipping_discount_tax']['currency_code'];
$data['shipping_discount_tax_amount'] = $items['shipping_discount_tax']['amount'];
}
$data['promotion_discount_currency_code'] = $items['promotion_discount']['currency_code'];
$data['promotion_discount_amount'] = $items['promotion_discount']['amount'];
$data['promotion_discount_tax_currency_code'] = $items['promotion_discount_tax']['currency_code'];
$data['promotion_discount_tax_amount'] = $items['promotion_discount_tax']['amount'];
$data['promotion_ids'] = '';
if ($data['promotion_ids']) {
$data['promotion_ids'] = implode(',', $items['promotion_ids']);
}
$data['cod_fee'] = $items['cod_fee'];
$data['cod_fee_discount'] = $items['cod_fee_discount'];
$data['is_gift'] = $items['is_gift'];
$data['condition_note'] = $items['condition_note'];
$data['condition_id'] = $items['condition_id'];
$data['condition_subtype_id'] = $items['condition_subtype_id'];
$data['scheduled_delivery_start_date'] = $items['scheduled_delivery_start_date'];
$data['scheduled_delivery_end_date'] = $items['scheduled_delivery_end_date'];
$data['price_designation'] = $items['price_designation'];
$data['tax_collection'] = $items['tax_collection'];
$data['serial_number_required'] = $items['serial_number_required'];
$data['is_transparency'] = $items['is_transparency'];
$data['ioss_number'] = $items['ioss_number'];
$data['store_chain_store_id'] = $items['store_chain_store_id'];
$data['deemed_reseller_category'] = $items['deemed_reseller_category'];
$data['buyer_info_buyer_customized_info'] = $items['buyer_info']['buyer_customized_info'];
$data['buyer_info_gift_wrap_price'] = $items['buyer_info']['gift_wrap_price'];
$data['buyer_info_gift_wrap_tax'] = $items['buyer_info']['gift_wrap_tax'];
$data['buyer_info_gift_message_text'] = $items['buyer_info']['gift_message_text'];
$data['buyer_info_gift_wrap_level'] = $items['buyer_info']['gift_wrap_level'];
$data['buyer_requested_cancel'] = $items['buyer_requested_cancel'];
$data['item_approval_context'] = $items['item_approval_context'];
$data['serial_numbers'] = $items['serial_numbers'];
$data['create_time'] = $time;
$data = $this->checkItems($data);
$itemId = $itemModel->create($data);
// 更新店铺的最后下载时间
$store = $storeModel::find($order['info']['store_id']);
$lastTime = date("Y-m-d H:i:s", strtotime($order['purchase_date'])); // 注意这里要转换时间格式
if ($lastTime > $store->last_time) {
$store->last_time = $lastTime; // 最后下载时间是采购时间
$store->save();
}
}
}
/**
* 处理失败的数据, 放回到失败队列中
*/
protected function resend($result)
{
$rabbitMQService = new RabbitMQService();
$rabbitMQService->sendMessage($result, $this->queueOrderFail);
}
// 将null改为空白
public function formatNull($array, $replacement = '')
{
foreach ($array as &$value) {
if (is_array($value)) {
$value = $this->formatNull($value, $replacement);
} elseif ($value === null) {
$value = $replacement;
}
}
return $array;
}
// 检查插入的数据中, 是否有数组, 如果有, 设为空白
public function checkItems($data)
{
foreach ($data as &$item) {
if (is_array($item)) {
$item = '';
}
}
return $data;
}
public function log($content)
{
echo "[" . date("Y-m-d H:i:s") . "] ". $content . "\n";
}
}