69 lines
2.8 KiB
PHP
69 lines
2.8 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use App\Exceptions\CourierOnboardingDingTalkException;
|
||
use App\Services\DingTalk\CourierOnboardingClient;
|
||
use App\Support\CourierOnboardingDingTalkProfiles;
|
||
use Illuminate\Console\Command;
|
||
use Illuminate\Support\Facades\Cache;
|
||
use Throwable;
|
||
|
||
class SyncCourierOnboardingDingTalkProfiles extends Command
|
||
{
|
||
protected $signature = 'courier-onboarding:sync-dingtalk-profiles {--limit=25 : 每轮最多查询数,最大50}';
|
||
|
||
protected $description = '查询已关联的入驻审批,通过后回传内部快递资料';
|
||
|
||
public function handle(CourierOnboardingDingTalkProfiles $profiles, CourierOnboardingClient $client): int
|
||
{
|
||
if (! config('courier_onboarding.dingtalk.enabled')) {
|
||
$this->info('入驻钉钉对接未启用。');
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
$limit = max(1, min(50, (int) $this->option('limit')));
|
||
$cursorKey = 'courier-onboarding:dingtalk-profile-cursor';
|
||
$cursor = (int) Cache::get($cursorKey, 0);
|
||
$query = $profiles->candidates();
|
||
$records = (clone $query)->where('id', '>', $cursor)->orderBy('id')->limit($limit)->get();
|
||
if ($records->isEmpty() && $cursor > 0) {
|
||
$records = $query->orderBy('id')->limit($limit)->get();
|
||
}
|
||
if ($records->isEmpty()) {
|
||
$this->info('没有需要同步的入驻审批。');
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
try {
|
||
$token = $client->accessToken();
|
||
} catch (CourierOnboardingDingTalkException $exception) {
|
||
$this->error($exception->getMessage());
|
||
|
||
return self::FAILURE;
|
||
}
|
||
$started = microtime(true);
|
||
$counts = ['synced' => 0, 'pending' => 0, 'closed' => 0, 'skipped' => 0, 'failed' => 0];
|
||
foreach ($records as $record) {
|
||
// 两分钟调度内最多执行90秒,单接口自带8秒超时。
|
||
if (microtime(true) - $started >= 90) {
|
||
break;
|
||
}
|
||
try {
|
||
$result = $profiles->synchronize($record->company_id, $record->id, $token);
|
||
$counts[$result]++;
|
||
} catch (Throwable $exception) {
|
||
$counts['failed']++;
|
||
$message = $exception instanceof CourierOnboardingDingTalkException
|
||
? $exception->getMessage() : '钉钉快递资料同步异常,请联系管理员核查。';
|
||
$profiles->recordFailure($record, $message);
|
||
}
|
||
// 每次从上次结束位置继续,避免前面的待审批单一直占满查询批次。
|
||
Cache::put($cursorKey, $record->id, now()->addDay());
|
||
}
|
||
$this->info('快递资料同步:' . json_encode($counts, JSON_UNESCAPED_UNICODE));
|
||
|
||
return $counts['failed'] > 0 ? self::FAILURE : self::SUCCESS;
|
||
}
|
||
}
|