setName('shopro_huifu:split-retry') ->addOption('sn', null, Option::VALUE_OPTIONAL, '指定订单号重试,多个用逗号分隔') ->addOption('force', null, Option::VALUE_NONE, '忽略 next_retry_time,立即重试') ->setDescription('Retry failed Huifu split confirm orders'); } protected function execute(Input $input, Output $output) { $config = new Config(); if (!$config->isEnable()) { $output->writeln('Split disabled.'); return 1; } $force = (bool) $input->getOption('force'); $snOpt = trim((string) $input->getOption('sn')); $service = new HuifuSplitService(); $rows = []; if ($snOpt !== '') { foreach (preg_split('/[\s,,]+/', $snOpt) as $sn) { $sn = trim($sn); if ($sn === '') { continue; } $order = Db::name('shopro_order')->where('order_sn', $sn)->find(); if (!$order && strlen($sn) < 24) { $order = Db::name('shopro_order')->where('order_sn', 'like', $sn . '%')->order('id', 'desc')->find(); } if (!$order) { $output->writeln("[SKIP] 订单不存在: {$sn}"); continue; } $split = SplitOrder::where('order_id', $order['id']) ->where('channel', 'huifu') ->order('id', 'desc') ->find(); if (!$split) { $output->writeln("[SKIP] 无汇付分账记录: {$sn}"); continue; } if ((int) $split['status'] === 2) { $output->writeln("[OK] 已分账成功: {$sn}"); continue; } if ((int) $split['status'] === SplitCloseService::STATUS_CLOSED || (new SplitCloseService())->isClosed((int) $order['id'])) { $output->writeln("[SKIP] 已线下结案: {$sn}"); continue; } $rows[] = $split; } } else { $query = SplitOrder::where('channel', 'huifu') ->where('status', 4) ->where('retry_count', '<', $config->getRetryMax()); if (!$force) { $query->where('next_retry_time', '<=', time()); } $rows = $query->limit(20)->select(); } if (!$rows) { $output->writeln('无可重试记录。若刚 confirm 成功,可等 5–30 分钟或加 --force;指定单号:--sn=订单号 --force'); return 0; } $ok = 0; $fail = 0; $closeService = new SplitCloseService(); foreach ($rows as $row) { if ((int) $row['status'] === SplitCloseService::STATUS_CLOSED || $closeService->isClosed((int) $row['order_id'])) { $output->writeln('[SKIP] 已线下结案 order_sn=' . ($row['order_sn'] ?? '')); continue; } $output->writeln('retry split#' . $row['id'] . ' order_sn=' . ($row['order_sn'] ?? '')); $result = $service->retry($row['id']); if ($result) { $output->writeln(' [OK]'); $ok++; } else { $latest = SplitOrder::where('order_id', $row['order_id']) ->where('channel', 'huifu') ->order('id', 'desc') ->find(); $hint = $latest && !empty($latest['wx_result']) ? mb_substr((string) $latest['wx_result'], 0, 200) : '仍失败,见后台分账详情'; $output->writeln(' [FAIL] ' . $hint); $fail++; } } $output->writeln("完成:成功 {$ok},失败 {$fail}"); return $fail > 0 ? 1 : 0; } }