You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.5 KiB
97 lines
3.5 KiB
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Company;
|
|
use App\Models\CompanyQccAccount;
|
|
use Illuminate\Support\Facades\DB;
|
|
use RuntimeException;
|
|
use Throwable;
|
|
|
|
/**
|
|
* 所有企查查(或经元禾穿透)调用的统一状态入口。
|
|
* 实际调用由 $operation 传入;调用方必须区分明确成功、明确失败与结果不确定。
|
|
*/
|
|
class QccCallService
|
|
{
|
|
public function call(
|
|
Company $company,
|
|
string $source,
|
|
string $requestRef,
|
|
callable $operation,
|
|
callable $isSuccess,
|
|
?callable $isIndeterminate = null
|
|
)
|
|
{
|
|
$account = CompanyQccAccount::query()->where('company_id', $company->id)->first();
|
|
if (!$account) {
|
|
throw new RuntimeException('企业未纳入企查查企业户候选池');
|
|
}
|
|
if (!$account->isCallable()) {
|
|
throw new RuntimeException('企业户状态待人工确认,暂不能发起调用');
|
|
}
|
|
|
|
try {
|
|
$result = $operation();
|
|
} catch (Throwable $exception) {
|
|
$this->markUnknownWhenSelected($company->id, $exception->getMessage());
|
|
throw $exception;
|
|
}
|
|
|
|
try {
|
|
if ($isSuccess($result)) {
|
|
$this->recordSuccess($company->id, $source, $requestRef);
|
|
} elseif ($isIndeterminate) {
|
|
$indeterminate = $isIndeterminate($result);
|
|
if ($indeterminate) {
|
|
$reason = is_string($indeterminate) ? $indeterminate : '调用结果无法确认';
|
|
$this->markUnknownWhenSelected($company->id, $reason);
|
|
}
|
|
}
|
|
} catch (Throwable $exception) {
|
|
$this->markUnknownWhenSelected($company->id, '调用结果判定异常:' . $exception->getMessage());
|
|
throw $exception;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function recordSuccess(int $companyId, string $source, string $requestRef): CompanyQccAccount
|
|
{
|
|
return DB::transaction(function () use ($companyId, $source, $requestRef) {
|
|
$account = CompanyQccAccount::query()->where('company_id', $companyId)->lockForUpdate()->first();
|
|
if (!$account) {
|
|
throw new RuntimeException('企业未纳入企查查企业户候选池');
|
|
}
|
|
if ($account->status === CompanyQccAccount::STATUS_UNKNOWN) {
|
|
throw new RuntimeException('企业户状态待人工确认,不能确认调用成功');
|
|
}
|
|
if ($account->status === CompanyQccAccount::STATUS_SELECTED) {
|
|
$account->update([
|
|
'status' => CompanyQccAccount::STATUS_OCCUPIED,
|
|
'first_success_at' => now(),
|
|
'first_success_source' => $source,
|
|
'first_success_ref' => $requestRef,
|
|
'unknown_note' => null,
|
|
]);
|
|
}
|
|
return $account->fresh();
|
|
});
|
|
}
|
|
|
|
public function markUnknownWhenSelected(int $companyId, string $reason): ?CompanyQccAccount
|
|
{
|
|
return DB::transaction(function () use ($companyId, $reason) {
|
|
$account = CompanyQccAccount::query()->where('company_id', $companyId)->lockForUpdate()->first();
|
|
if (!$account || $account->status !== CompanyQccAccount::STATUS_SELECTED) {
|
|
return $account;
|
|
}
|
|
$account->update([
|
|
'status' => CompanyQccAccount::STATUS_UNKNOWN,
|
|
'unknown_note' => mb_substr($reason, 0, 2000),
|
|
]);
|
|
return $account->fresh();
|
|
});
|
|
}
|
|
}
|