|
|
|
|
@ -114,6 +114,11 @@ class NewsCollection
|
|
|
|
|
}
|
|
|
|
|
$batchId = $control->active_batch_id;
|
|
|
|
|
// A dead worker may already have called the provider. Do not silently repeat that request.
|
|
|
|
|
DB::table('company_qcc_accounts')->whereIn('company_id',
|
|
|
|
|
DB::table('company_news_tasks')->where('batch_id', $batchId)->where('status', 'processing')->select('company_id')
|
|
|
|
|
)->where('status', 'selected')->update([
|
|
|
|
|
'status' => 'unknown', 'unknown_note' => '执行进程中断,外部请求结果不确定;请人工确认', 'updated_at' => now(),
|
|
|
|
|
]);
|
|
|
|
|
DB::table('company_news_tasks')->where('batch_id', $batchId)->where('status', 'processing')->update([
|
|
|
|
|
'status' => 'failed', 'error' => '执行进程中断,外部请求结果不确定;请核查后手动重试',
|
|
|
|
|
'finished_at' => now(), 'updated_at' => now(),
|
|
|
|
|
@ -137,6 +142,8 @@ class NewsCollection
|
|
|
|
|
[$task, $token] = $claim;
|
|
|
|
|
$response = null;
|
|
|
|
|
$error = null;
|
|
|
|
|
$requestStarted = false;
|
|
|
|
|
$indeterminate = false;
|
|
|
|
|
try {
|
|
|
|
|
$company = Company::find($task->company_id);
|
|
|
|
|
if (!$company || !$company->qccAccount || !in_array($company->qccAccount->status, ['selected', 'occupied'], true)) {
|
|
|
|
|
@ -146,9 +153,11 @@ class NewsCollection
|
|
|
|
|
throw new RuntimeException('企业缺少统一社会信用代码');
|
|
|
|
|
}
|
|
|
|
|
// Fetch directly: occupation is recorded only for a successful response containing business data.
|
|
|
|
|
$requestStarted = true;
|
|
|
|
|
$response = app(YuanheRepository::class)->enterprisePackInfo([
|
|
|
|
|
'creditCode' => $company->credit_code, 'enterpriseName' => $company->company_name,
|
|
|
|
|
], 60);
|
|
|
|
|
$indeterminate = !isset($response['code']) || !is_scalar($response['code']) || trim((string) $response['code']) === '';
|
|
|
|
|
if (!in_array($response['code'] ?? null, [200, '200'], true)) {
|
|
|
|
|
throw new RuntimeException('元禾业务失败:'.mb_substr(json_encode($response['msg'] ?? $response['code'] ?? '缺少 code', JSON_UNESCAPED_UNICODE), 0, 1000));
|
|
|
|
|
}
|
|
|
|
|
@ -163,7 +172,12 @@ class NewsCollection
|
|
|
|
|
$error = mb_substr($e->getMessage(), 0, 2000);
|
|
|
|
|
}
|
|
|
|
|
// Provider success is independent from local news import success.
|
|
|
|
|
if ($this->hasBusinessData($response)) $this->markOccupied($task, $token);
|
|
|
|
|
if ($this->hasBusinessData($response)) {
|
|
|
|
|
$this->markOccupied($task, $token);
|
|
|
|
|
} elseif ($requestStarted && ($response === null || $indeterminate)) {
|
|
|
|
|
$error = $error ?: '外部请求结果不确定';
|
|
|
|
|
$this->markUnknown($task, $token, $error);
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
$this->persist($task, $token, $response, $error);
|
|
|
|
|
} catch (Throwable $e) {
|
|
|
|
|
@ -198,6 +212,17 @@ class NewsCollection
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function markUnknown(object $task, string $token, string $reason): void
|
|
|
|
|
{
|
|
|
|
|
DB::transaction(function () use ($task, $token, $reason) {
|
|
|
|
|
$control = DB::table('company_news_control')->where('id', 1)->lockForUpdate()->first();
|
|
|
|
|
if ($control->worker_token !== $token) return;
|
|
|
|
|
DB::table('company_qcc_accounts')->where('company_id', $task->company_id)
|
|
|
|
|
->where('status', 'selected')
|
|
|
|
|
->update(['status' => 'unknown', 'unknown_note' => mb_substr($reason, 0, 2000), 'updated_at' => now()]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function persist(object $task, string $token, ?array $response, ?string $error): void
|
|
|
|
|
{
|
|
|
|
|
DB::transaction(function () use ($task, $token, $response, $error) {
|
|
|
|
|
|