150 lines
5.6 KiB
PHP
150 lines
5.6 KiB
PHP
<?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('发货失败订单处理完成!');
|
||
}
|
||
} |