CaiWuXiTong/app/Console/Commands/SyncJushuitanCostPriceHistory.php
limeng 8f150080c5 修正聚水潭成本价历史凭据边界与未同步状态 (#186)
保留完整成本价历史方案,区分经典接口凭据与新开放平台凭据;首次同步未完成时显示待同步,不误报 0 条。

验证:33 passed,260 assertions。
2026-09-15 11:39:09 +08:00

78 lines
3.2 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= : 聚水潭接口每页读取条数,最大 50}
{--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(match ($exception->getMessage()) {
'jushuitan_classic_api_credentials_missing' => '聚水潭经典开放接口凭据未配置,请配置 partnerid、partnerkey 和 token。',
'jushuitan_classic_api_partner_id_invalid' => '聚水潭经典开放接口 partnerid 无效,请核对同一应用的 partnerid、partnerkey 和 token。',
default => '聚水潭成本价历史同步失败,已保留上一版共享数据。',
});
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);
}
}