文件
xionggeshop/addons/shopro_huifu/command/SplitRetry.php
可乐加冰 2e1e17ba02 ```
feat(shopro_huifu): 增强分账重试命令功能

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

105 行
3.7 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace addons\shopro_huifu\command;
use addons\shopro\library\split\Config;
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')
->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;
}
$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;
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;
}
}