145 lines
5.0 KiB
PHP
145 lines
5.0 KiB
PHP
<?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;
|
||
}
|
||
}
|