CaiWuXiTong/app/Console/Commands/SyncJushuitanCostPriceHistory.php

74 lines
2.8 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 Illuminate\Support\Facades\Log;
use Modules\EcommerceFinance\Repositories\JushuitanCostPriceHistoryMirrorRepository;
use Modules\EcommerceFinance\Services\JushuitanCostPriceHistorySynchronizer;
use Throwable;
class SyncJushuitanCostPriceHistory extends Command
{
protected $signature = 'business-mirror:sync-jushuitan-cost-price-history
{--full : 强制启动或继续首次全量同步}
{--page-size= : 聚水潭接口每页读取条数,最大 2000}
{--max-pages= : 本轮最多读取页数,0 表示直到完成}';
protected $description = '按时间窗和页码同步聚水潭商品操作日志中的采购价变更到共享业务镜像';
public function handle(
JushuitanCostPriceHistoryMirrorRepository $mirror,
JushuitanCostPriceHistorySynchronizer $synchronizer,
): int {
if (! (bool) config('upstream_mirrors.refresh_enabled', false) && ! $this->option('full')) {
return self::SUCCESS;
}
try {
$state = $mirror->state();
$full = $this->shouldRunFull($state);
$result = $synchronizer->sync(
$full,
$this->option('page-size') === null ? null : (int) $this->option('page-size'),
$this->option('max-pages') === null ? null : (int) $this->option('max-pages'),
);
} catch (Throwable $exception) {
Log::error('聚水潭历史成本价镜像同步失败。', ['exception' => $exception::class]);
$this->error('聚水潭成本价历史同步失败,已保留上一版共享数据。');
return self::FAILURE;
}
if ($result['status'] === 'requires_full_sync') {
$this->warn('聚水潭成本价历史尚未完成首次全量同步,请在凭据和备份确认后显式使用 --full。');
return self::SUCCESS;
}
$this->info(sprintf(
'聚水潭成本价操作日志%s:%s,本轮 %d 页,累计扫描 %d 条操作日志、同步 %d 条采购价变更。',
$result['mode'] === 'full' ? '全量同步' : '增量同步',
$result['status'] === 'succeeded' ? '完成' : '进行中',
$result['pages'],
$result['source_rows'],
$result['rows'],
));
return self::SUCCESS;
}
/** @param array<string,mixed>|null $state */
private function shouldRunFull(?array $state): bool
{
if ((bool) $this->option('full')) {
return true;
}
// 显式全量中断后由日常任务续传同一固定时间窗,完成前不激活半份数据。
return is_array($state)
&& ($state['run_mode'] ?? null) === 'full'
&& in_array($state['status'] ?? null, ['running', 'failed'], true);
}
}