164 行
5.2 KiB
PHP
164 行
5.2 KiB
PHP
<?php
|
|
|
|
namespace addons\shopro_wechat_trade\library;
|
|
|
|
use addons\shopro\model\Order;
|
|
use addons\shopro\model\OrderItem;
|
|
use think\Db;
|
|
use think\Log;
|
|
|
|
class WxShippingService
|
|
{
|
|
protected $client;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->client = new WxTradeClient();
|
|
}
|
|
|
|
public function syncOrderShipping($orderId, $triggerItemId = 0)
|
|
{
|
|
if (!Bridge::isEnabled()) {
|
|
return false;
|
|
}
|
|
|
|
$order = Order::with('item')->where('id', $orderId)->find();
|
|
if (!$order || !Bridge::shouldHandleOrder($order)) {
|
|
return false;
|
|
}
|
|
|
|
$items = [];
|
|
if (!empty($order->item)) {
|
|
foreach ($order->item as $item) {
|
|
$items[] = is_object($item) && method_exists($item, 'toArray') ? $item->toArray() : (array) $item;
|
|
}
|
|
}
|
|
|
|
$triggerItem = null;
|
|
if ($triggerItemId) {
|
|
foreach ($items as $item) {
|
|
$itemArr = is_object($item) ? $item->toArray() : $item;
|
|
if (intval($itemArr['id']) === intval($triggerItemId)) {
|
|
$triggerItem = $itemArr;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$built = WxShippingPayload::buildUploadPayload($order, $items, $triggerItem);
|
|
$payload = $built['payload'];
|
|
$logId = SyncLogger::create($order, 'shipping', $payload, $triggerItemId, $built['meta']['delivery_mode']);
|
|
|
|
try {
|
|
$response = $this->client->postJson('/wxa/sec/order/upload_shipping_info', $payload);
|
|
$this->client->callOrThrow($response, '上传发货信息');
|
|
SyncLogger::markSuccess($logId, $response, $payload);
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
$response = isset($response) && is_array($response) ? $response : [];
|
|
SyncLogger::markFailed($logId, $e, $response, $payload);
|
|
Log::error('[shopro_wechat_trade] shipping sync fail order#' . $orderId . ': ' . $e->getMessage());
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function syncOrderConfirm($orderId)
|
|
{
|
|
if (!Bridge::isEnabled()) {
|
|
return false;
|
|
}
|
|
|
|
if (SyncLogger::hasSuccessfulConfirm($orderId)) {
|
|
return true;
|
|
}
|
|
|
|
$order = Order::with('item')->where('id', $orderId)->find();
|
|
if (!$order || !Bridge::shouldHandleOrder($order)) {
|
|
return false;
|
|
}
|
|
|
|
$pending = OrderItem::where('order_id', $orderId)
|
|
->where('dispatch_status', '<>', OrderItem::DISPATCH_STATUS_GETED)
|
|
->count();
|
|
if ($pending > 0) {
|
|
return false;
|
|
}
|
|
|
|
$payload = WxShippingPayload::buildConfirmPayload($order);
|
|
$logId = SyncLogger::create($order, 'confirm', $payload);
|
|
|
|
try {
|
|
$response = $this->client->postJson('/wxa/sec/order/notify_confirm_receive', $payload);
|
|
$this->client->callOrThrow($response, '同步确认收货');
|
|
SyncLogger::markSuccess($logId, $response, $payload);
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
$response = isset($response) && is_array($response) ? $response : [];
|
|
SyncLogger::markFailed($logId, $e, $response, $payload);
|
|
Log::error('[shopro_wechat_trade] confirm sync fail order#' . $orderId . ': ' . $e->getMessage());
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function backfillShippedOrders($limit = 50)
|
|
{
|
|
$rows = Db::name('shopro_order')
|
|
->alias('o')
|
|
->join('shopro_order_item oi', 'oi.order_id = o.id')
|
|
->where('o.platform', 'wxMiniProgram')
|
|
->where('o.pay_type', 'in', ['wechat', 'huifu_wechat'])
|
|
->where('o.status', '>', 0)
|
|
->where('oi.dispatch_status', '>=', OrderItem::DISPATCH_STATUS_SENDED)
|
|
->group('o.id')
|
|
->order('o.id', 'desc')
|
|
->limit($limit)
|
|
->column('o.id');
|
|
|
|
$count = 0;
|
|
foreach ($rows as $orderId) {
|
|
$hasSuccess = Db::name('shopro_wechat_trade_sync')
|
|
->where('order_id', $orderId)
|
|
->where('sync_type', 'shipping')
|
|
->where('status', 'success')
|
|
->find();
|
|
if ($hasSuccess) {
|
|
continue;
|
|
}
|
|
try {
|
|
$this->syncOrderShipping($orderId);
|
|
$count++;
|
|
} catch (\Exception $e) {
|
|
// logged
|
|
}
|
|
}
|
|
return $count;
|
|
}
|
|
|
|
public function retryFailed($limit = 50)
|
|
{
|
|
$now = time();
|
|
$rows = Db::name('shopro_wechat_trade_sync')
|
|
->where('status', 'pending')
|
|
->where('retry_count', '>', 0)
|
|
->where('next_retry_time', '<=', $now)
|
|
->order('id', 'asc')
|
|
->limit($limit)
|
|
->select();
|
|
|
|
$count = 0;
|
|
foreach ($rows as $row) {
|
|
try {
|
|
if ($row['sync_type'] === 'confirm') {
|
|
$this->syncOrderConfirm($row['order_id']);
|
|
} else {
|
|
$this->syncOrderShipping($row['order_id'], $row['order_item_id']);
|
|
}
|
|
$count++;
|
|
} catch (\Exception $e) {
|
|
// logged
|
|
}
|
|
}
|
|
return $count;
|
|
}
|
|
}
|