manghe/app/command/PostOrderRetry.php
2025-04-25 00:16:04 +08:00

150 lines
5.6 KiB
PHP
Raw Permalink 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
declare(strict_types=1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use app\common\server\RedisHelper;
/**
* 重试微信发货失败的订单
*/
class PostOrderRetry extends Command
{
//php think PostOrderRetry
protected function configure()
{
// 指令配置
$this->setName('PostOrderRetry')
->setDescription('重试微信发货失败的订单');
}
protected function execute(Input $input, Output $output)
{
$output->writeln('开始处理发货失败的订单...');
// 获取Redis实例
$redis = (new RedisHelper())->getRedis();
// 获取所有发货失败的订单键
$failedOrderKeys = $redis->keys('post_order:*');
if (empty($failedOrderKeys)) {
$output->writeln('没有发现发货失败的订单,任务结束');
return;
}
$output->writeln('发现' . count($failedOrderKeys) . '个发货失败的订单');
// 重试限制
$maxRetryCount = 10; // 最大重试次数
$retryInterval = 10; // 重试间隔(秒)
$nowTime = time();
// 处理每个失败的订单
foreach ($failedOrderKeys as $key) {
// 获取订单数据
$orderDataJson = $redis->get($key);
if (empty($orderDataJson)) {
continue;
}
$orderData = json_decode($orderDataJson, true);
if (!is_array($orderData)) {
// 数据格式错误,删除此键
$redis->del($key);
continue;
}
// 检查重试次数和时间间隔
if ($orderData['retry_count'] >= $maxRetryCount) {
// 超过最大重试次数,记录日志并删除
writelog('post_order_retry_log', json_encode([
'method' => 'post_order_retry_max_reached',
'order_num' => $orderData['order_num'],
'retry_count' => $orderData['retry_count'],
'time' => date('Y-m-d H:i:s')
]));
$redis->del($key);
$output->writeln("订单 {$orderData['order_num']} 超过最大重试次数({$maxRetryCount}),已移除");
continue;
}
// 检查是否达到重试间隔
if (($nowTime - $orderData['last_retry_time']) < $retryInterval) {
$output->writeln("订单 {$orderData['order_num']} 未达到重试间隔,跳过");
continue;
}
// 尝试重新发货
try {
$access_token = "";
$appid = $orderData['appid'];
//获取对应的小程序
$app = \app\common\helper\MiniprogramHelper::getMiniprogramConfigByAppid($appid);
$wx_secret = $app['app_secret'];
// 获取access_token - 优先使用微信服务器类获取
$wxServer = new \app\common\server\Wx($this->app);
$access_token = $wxServer->get_access_appid_token($appid, $wx_secret);
if (empty($access_token)) {
throw new \Exception("无法获取有效的access_token");
}
// 调用发货接口
$payController = new \app\api\controller\Pay();
$retryResult = $payController->post_order(
$orderData['openid'],
$access_token,
$orderData['order_num'],
$orderData['title'] ?? '订单发货'
);
// 记录重试日志
writelog('post_order_retry_log', json_encode([
'method' => 'post_order_retry_attempt',
'order_num' => $orderData['order_num'],
'retry_count' => $orderData['retry_count'] + 1,
'result' => $retryResult,
'time' => date('Y-m-d H:i:s')
]));
// 处理重试结果
if ($retryResult == 1) {
// 发货成功删除Redis中的记录
$redis->del($key);
$output->writeln("订单 {$orderData['order_num']} 重试发货成功,已从重试队列移除");
} else {
// 发货失败,更新重试信息
$orderData['retry_count'] += 1;
$orderData['last_retry_time'] = $nowTime;
$redis->set($key, json_encode($orderData));
$output->writeln("订单 {$orderData['order_num']}{$orderData['retry_count']} 次重试发货失败,将在下次重试");
}
} catch (\Exception $e) {
// 记录异常日志
writelog('post_order_retry_log', json_encode([
'method' => 'post_order_retry_exception',
'order_num' => $orderData['order_num'],
'error' => $e->getMessage(),
'time' => date('Y-m-d H:i:s')
]));
// 更新重试信息
$orderData['retry_count'] += 1;
$orderData['last_retry_time'] = $nowTime;
$orderData['last_error'] = $e->getMessage();
$redis->set($key, json_encode($orderData));
$output->writeln("订单 {$orderData['order_num']} 重试时发生异常:" . $e->getMessage());
}
}
$output->writeln('发货失败订单处理完成!');
}
}