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