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|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); } }