erp-backend/app/Console/Commands/PullOrdersCommand.php
2026-04-01 17:07:04 +08:00

145 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Services\OrderPullService;
use App\Models\ShopAuth;
use App\Models\PullRecord;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class PullOrdersCommand extends Command
{
protected $signature = 'orders:pull {platform} {--limit=200 : 单次最大拉取数量} {--shop= : 指定店铺ID}';
protected $description = '拉取指定平台的订单(定时定量)';
protected $orderPullService;
public function __construct(OrderPullService $orderPullService)
{
parent::__construct();
$this->orderPullService = $orderPullService;
}
public function handle()
{
$platform = $this->argument('platform');
$limit = (int) $this->option('limit');
$shopId = $this->option('shop');
// 限制最大单次拉取量
$limit = min($limit, 500);
$this->info("开始拉取 {$platform} 平台订单,限制数量: {$limit}");
// 获取店铺列表
$query = ShopAuth::where('platform', $platform)->where('status', 'valid');
if ($shopId) {
$query->where('id', $shopId);
}
$shops = $query->get();
if ($shops->isEmpty()) {
$this->warn("没有找到已授权的 {$platform} 店铺");
return 0;
}
$totalPulled = 0;
$totalQueued = 0;
foreach ($shops as $shop) {
$this->info("正在处理店铺 [{$shop->shop_name}] (ID: {$shop->id})...");
// 获取上次拉取结束时间
$lastRecord = PullRecord::where([
'platform_type' => $platform,
'platform_shop_id' => $shop->id,
'pull_status' => 1
])->orderBy('end_time', 'desc')->first();
$startTime = $lastRecord
? Carbon::parse($lastRecord->end_time)->subMinutes(5) // 从结束时间前5分钟开始避免漏单
: Carbon::now()->subHours(3);
$endTime = Carbon::now();
// 检查是否在间隔时间内
if ($lastRecord) {
$secondsSinceLastPull = Carbon::now()->diffInSeconds($lastRecord->end_time);
if ($secondsSinceLastPull < OrderPullService::PULL_INTERVAL) {
$waitSeconds = OrderPullService::PULL_INTERVAL - $secondsSinceLastPull;
$this->info("距离上次拉取不足" . OrderPullService::PULL_INTERVAL . "秒,等待 {$waitSeconds} 秒...");
sleep($waitSeconds);
}
}
try {
$result = $this->orderPullService->pullOrders(
$platform,
(string) $shop->id,
$startTime->toDateTimeString(),
$endTime->toDateTimeString(),
$limit
);
// 记录拉取
PullRecord::create([
'platform_type' => $platform,
'platform_shop_id' => $shop->id,
'start_time' => $startTime,
'end_time' => $endTime,
'pulled_count' => $result['count'],
'pull_status' => 1,
]);
$totalPulled += $result['total_received'];
$totalQueued += $result['count'];
$msg = "拉取完成: 收到 {$result['total_received']} 订单,入队 {$result['count']}";
if ($result['has_more']) {
$msg .= ",还有更多订单待处理";
}
$this->info($msg);
Log::info("订单拉取完成", [
'platform' => $platform,
'shop_id' => $shop->id,
'received' => $result['total_received'],
'queued' => $result['count'],
'has_more' => $result['has_more'],
]);
} catch (\Exception $e) {
$this->error("拉取失败:" . $e->getMessage());
PullRecord::create([
'platform_type' => $platform,
'platform_shop_id' => $shop->id,
'start_time' => $startTime,
'end_time' => $endTime,
'pulled_count' => 0,
'pull_status' => 2,
'error_msg' => $e->getMessage()
]);
Log::error("订单拉取失败", [
'platform' => $platform,
'shop_id' => $shop->id,
'error' => $e->getMessage(),
]);
}
// 平台间隔,避免频率过高
$this->info("等待 3 秒...");
sleep(3);
}
$this->info("=== 拉取汇总 ===");
$this->info("平台: {$platform}");
$this->info("收到订单: {$totalPulled}");
$this->info("入队处理: {$totalQueued}");
return 0;
}
}