feat(shopro_huifu): 增强分账重试命令功能

- 添加 --sn 参数支持指定订单号重试,多个订单号用逗号分隔
- 添加 --force 参数支持忽略重试时间限制立即重试
- 支持订单号模糊匹配(前缀匹配)
- 改进命令执行逻辑,区分批量重试和指定订单重试
- 优化输出信息,显示重试结果统计(成功/失败数量)
- 当未找到可重试记录时提供操作建议
- 改进错误处理和返回码机制
```
这个提交包含在:
可乐加冰
2026-10-08 15:19:29 +08:00
父节点 a4f307f4ce
当前提交 2e1e17ba02

查看文件

@@ -7,13 +7,18 @@ use addons\shopro\model\split\SplitOrder;
use addons\shopro_huifu\library\HuifuSplitService;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Db;
class SplitRetry extends Command
{
protected function configure()
{
$this->setName('shopro_huifu:split-retry')->setDescription('Retry failed Huifu split confirm orders');
$this->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)
@@ -21,20 +26,79 @@ class SplitRetry extends Command
$config = new Config();
if (!$config->isEnable()) {
$output->writeln('Split disabled.');
return;
return 1;
}
$rows = SplitOrder::where('channel', 'huifu')
->where('status', 4)
->where('retry_count', '<', $config->getRetryMax())
->where('next_retry_time', '<=', time())
->limit(20)
->select();
$force = (bool) $input->getOption('force');
$snOpt = trim((string) $input->getOption('sn'));
$service = new HuifuSplitService();
foreach ($rows as $row) {
$service->retry($row['id']);
$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;
}
$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();
}
$output->writeln('Huifu split retry finished.');
if (!$rows) {
$output->writeln('无可重试记录。若刚 confirm 成功,可等 5–30 分钟或加 --force;指定单号:--sn=订单号 --force');
return 0;
}
$ok = 0;
$fail = 0;
foreach ($rows as $row) {
$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;
}
}