master
parent
918321b0fb
commit
9494e822fa
@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Helpers\ResponseCode;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\CompanyQccAccount;
|
||||||
|
use App\Models\OperateLog;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Database\QueryException;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class QccEnterpriseAccountController extends CommonController
|
||||||
|
{
|
||||||
|
public function candidates(Request $request)
|
||||||
|
{
|
||||||
|
$keyword = trim((string) $request->input('keyword', ''));
|
||||||
|
$status = $request->input('status');
|
||||||
|
$pageSize = min(max((int) $request->input('page_size', 20), 1), 100);
|
||||||
|
$query = Company::query()->select('id', 'company_name', 'credit_code', 'updated_at')->with('qccAccount');
|
||||||
|
if ($keyword !== '') {
|
||||||
|
$query->where(function ($subQuery) use ($keyword) {
|
||||||
|
$subQuery->where('company_name', 'like', '%' . $keyword . '%')
|
||||||
|
->orWhere('credit_code', 'like', '%' . $keyword . '%');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ($status === 'none') {
|
||||||
|
$query->doesntHave('qccAccount');
|
||||||
|
} elseif (in_array($status, [CompanyQccAccount::STATUS_SELECTED, CompanyQccAccount::STATUS_OCCUPIED, CompanyQccAccount::STATUS_UNKNOWN], true)) {
|
||||||
|
$query->whereHas('qccAccount', fn($relation) => $relation->where('status', $status));
|
||||||
|
}
|
||||||
|
return $this->success($query->orderByDesc('id')->paginate($pageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$status = $request->input('status');
|
||||||
|
$pageSize = min(max((int) $request->input('page_size', 20), 1), 100);
|
||||||
|
$query = CompanyQccAccount::query()->with('company:id,company_name,credit_code');
|
||||||
|
if (in_array($status, [CompanyQccAccount::STATUS_SELECTED, CompanyQccAccount::STATUS_OCCUPIED, CompanyQccAccount::STATUS_UNKNOWN], true)) {
|
||||||
|
$query->where('status', $status);
|
||||||
|
}
|
||||||
|
return $this->success($query->orderByDesc('id')->paginate($pageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function select(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), ['company_ids' => 'required|array|min:1', 'company_ids.*' => 'integer|distinct']);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
||||||
|
}
|
||||||
|
$companyIds = $request->input('company_ids');
|
||||||
|
$companies = Company::query()->whereIn('id', $companyIds)->get()->keyBy('id');
|
||||||
|
foreach ($companyIds as $companyId) {
|
||||||
|
$company = $companies->get($companyId);
|
||||||
|
if (!$company || empty(trim((string) $company->credit_code))) {
|
||||||
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '存在不存在或缺少统一社会信用代码的企业']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::transaction(function () use ($companyIds) {
|
||||||
|
$existingCompanyIds = CompanyQccAccount::query()->whereIn('company_id', $companyIds)->lockForUpdate()->pluck('company_id');
|
||||||
|
if ($existingCompanyIds->isNotEmpty()) {
|
||||||
|
throw new RuntimeException('存在已纳入企业户标注的企业');
|
||||||
|
}
|
||||||
|
foreach ($companyIds as $companyId) {
|
||||||
|
CompanyQccAccount::query()->create([
|
||||||
|
'company_id' => $companyId,
|
||||||
|
'status' => CompanyQccAccount::STATUS_SELECTED,
|
||||||
|
'selected_by' => $this->getUserId(),
|
||||||
|
'selected_at' => now(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (RuntimeException|QueryException $exception) {
|
||||||
|
return $this->fail([ResponseCode::ERROR_BUSINESS, $exception->getMessage()]);
|
||||||
|
}
|
||||||
|
$this->log('纳入企查查企业户候选池', implode(',', $companyIds));
|
||||||
|
return $this->success('已纳入候选池');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cancel(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), ['id' => 'required|integer']);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$companyId = DB::transaction(function () use ($request) {
|
||||||
|
$account = CompanyQccAccount::query()->whereKey($request->input('id'))->lockForUpdate()->first();
|
||||||
|
if (!$account) {
|
||||||
|
throw new RuntimeException('企业户关系不存在');
|
||||||
|
}
|
||||||
|
if ($account->status !== CompanyQccAccount::STATUS_SELECTED) {
|
||||||
|
throw new RuntimeException('仅候选状态可以取消');
|
||||||
|
}
|
||||||
|
$companyId = $account->company_id;
|
||||||
|
$account->delete();
|
||||||
|
return $companyId;
|
||||||
|
});
|
||||||
|
} catch (RuntimeException $exception) {
|
||||||
|
return $this->fail([ResponseCode::ERROR_BUSINESS, $exception->getMessage()]);
|
||||||
|
}
|
||||||
|
$this->log('取消企查查企业户候选关系', (string) $companyId);
|
||||||
|
return $this->success('已取消候选关系');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unknownConfirm(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'id' => 'required|integer',
|
||||||
|
'decision' => 'required|in:retry,occupied',
|
||||||
|
'evidence' => 'required|string|max:2000',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
||||||
|
}
|
||||||
|
$decision = $request->input('decision');
|
||||||
|
$evidence = trim($request->input('evidence'));
|
||||||
|
try {
|
||||||
|
$account = DB::transaction(function () use ($request, $decision, $evidence) {
|
||||||
|
$account = CompanyQccAccount::query()->whereKey($request->input('id'))->lockForUpdate()->first();
|
||||||
|
if (!$account || $account->status !== CompanyQccAccount::STATUS_UNKNOWN) {
|
||||||
|
throw new RuntimeException('仅未知状态可以人工确认');
|
||||||
|
}
|
||||||
|
if ($decision === 'occupied') {
|
||||||
|
$account->update([
|
||||||
|
'status' => CompanyQccAccount::STATUS_OCCUPIED,
|
||||||
|
'first_success_at' => now(),
|
||||||
|
'first_success_source' => 'manual-confirmation',
|
||||||
|
'first_success_ref' => $evidence,
|
||||||
|
'unknown_note' => $evidence,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$account->update(['status' => CompanyQccAccount::STATUS_SELECTED, 'unknown_note' => $evidence]);
|
||||||
|
}
|
||||||
|
return $account->fresh();
|
||||||
|
});
|
||||||
|
} catch (RuntimeException $exception) {
|
||||||
|
return $this->fail([ResponseCode::ERROR_BUSINESS, $exception->getMessage()]);
|
||||||
|
}
|
||||||
|
$this->log('人工确认企查查企业户未知状态:' . $decision, $evidence);
|
||||||
|
return $this->success($account);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function log(string $name, string $remark = ''): void
|
||||||
|
{
|
||||||
|
$admin = $this->getUser();
|
||||||
|
if ($admin) {
|
||||||
|
OperateLog::addLogs($admin, $name, $remark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class CompanyQccAccount extends CommonModel
|
||||||
|
{
|
||||||
|
public const STATUS_SELECTED = 'selected';
|
||||||
|
public const STATUS_OCCUPIED = 'occupied';
|
||||||
|
public const STATUS_UNKNOWN = 'unknown';
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'selected_at' => 'datetime:Y-m-d H:i:s',
|
||||||
|
'first_success_at' => 'datetime:Y-m-d H:i:s',
|
||||||
|
'created_at' => 'datetime:Y-m-d H:i:s',
|
||||||
|
'updated_at' => 'datetime:Y-m-d H:i:s',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function company()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Company::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isCallable(): bool
|
||||||
|
{
|
||||||
|
return in_array($this->status, [self::STATUS_SELECTED, self::STATUS_OCCUPIED], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
<?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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('company_qcc_accounts', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('company_id')->unique()->comment('企业ID');
|
||||||
|
$table->string('status', 20)->index()->comment('selected/occupied/unknown');
|
||||||
|
$table->unsignedBigInteger('selected_by')->nullable()->comment('选择操作人');
|
||||||
|
$table->dateTime('selected_at')->comment('纳入候选池时间');
|
||||||
|
$table->dateTime('first_success_at')->nullable()->comment('首次调用成功时间');
|
||||||
|
$table->string('first_success_source')->nullable()->comment('首次成功来源');
|
||||||
|
$table->string('first_success_ref')->nullable()->comment('首次成功请求引用');
|
||||||
|
$table->text('unknown_note')->nullable()->comment('未知原因或人工核验说明');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreign('company_id')->references('id')->on('companies')->restrictOnDelete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('company_qcc_accounts');
|
||||||
|
}
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,189 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit\Services;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\CompanyQccAccount;
|
||||||
|
use App\Services\QccCallService;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use RuntimeException;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class QccCallServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
config([
|
||||||
|
'database.default' => 'sqlite',
|
||||||
|
'database.connections.sqlite.database' => ':memory:',
|
||||||
|
'audit.enabled' => false,
|
||||||
|
]);
|
||||||
|
DB::purge('sqlite');
|
||||||
|
|
||||||
|
Schema::create('companies', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('company_name')->nullable();
|
||||||
|
$table->string('credit_code')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
Schema::create('company_qcc_accounts', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('company_id')->unique();
|
||||||
|
$table->string('status', 20);
|
||||||
|
$table->unsignedBigInteger('selected_by')->nullable();
|
||||||
|
$table->dateTime('selected_at');
|
||||||
|
$table->dateTime('first_success_at')->nullable();
|
||||||
|
$table->string('first_success_source')->nullable();
|
||||||
|
$table->string('first_success_ref')->nullable();
|
||||||
|
$table->text('unknown_note')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('company_qcc_accounts');
|
||||||
|
Schema::dropIfExists('companies');
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_first_success_marks_candidate_occupied_only_once(): void
|
||||||
|
{
|
||||||
|
$company = $this->company();
|
||||||
|
$account = $this->selectedAccount($company);
|
||||||
|
$service = new QccCallService();
|
||||||
|
|
||||||
|
$service->recordSuccess($company->id, 'enterprise-profile', 'request-first');
|
||||||
|
$firstSuccessAt = $account->fresh()->first_success_at;
|
||||||
|
|
||||||
|
$service->recordSuccess($company->id, 'risk-check', 'request-second');
|
||||||
|
$account = $account->fresh();
|
||||||
|
|
||||||
|
$this->assertSame(CompanyQccAccount::STATUS_OCCUPIED, $account->status);
|
||||||
|
$this->assertSame('enterprise-profile', $account->first_success_source);
|
||||||
|
$this->assertSame('request-first', $account->first_success_ref);
|
||||||
|
$this->assertTrue($firstSuccessAt->equalTo($account->first_success_at));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_unknown_candidate_blocks_follow_up_calls(): void
|
||||||
|
{
|
||||||
|
$company = $this->company();
|
||||||
|
$account = $this->selectedAccount($company);
|
||||||
|
$service = new QccCallService();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$service->call($company, 'enterprise-profile', 'request-timeout', function () {
|
||||||
|
throw new RuntimeException('timeout');
|
||||||
|
}, fn($result) => $result === true);
|
||||||
|
$this->fail('Expected timeout exception was not thrown.');
|
||||||
|
} catch (RuntimeException $exception) {
|
||||||
|
$this->assertSame('timeout', $exception->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSame(CompanyQccAccount::STATUS_UNKNOWN, $account->fresh()->status);
|
||||||
|
$this->expectException(RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('待人工确认');
|
||||||
|
$service->call($company, 'enterprise-profile', 'request-retry', fn() => true, fn($result) => $result === true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_later_timeout_does_not_downgrade_occupied_account(): void
|
||||||
|
{
|
||||||
|
$company = $this->company();
|
||||||
|
$account = $this->selectedAccount($company, CompanyQccAccount::STATUS_OCCUPIED);
|
||||||
|
$service = new QccCallService();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$service->call($company, 'enterprise-profile', 'request-timeout', function () {
|
||||||
|
throw new RuntimeException('timeout');
|
||||||
|
}, fn($result) => $result === true);
|
||||||
|
$this->fail('Expected timeout exception was not thrown.');
|
||||||
|
} catch (RuntimeException $exception) {
|
||||||
|
$this->assertSame('timeout', $exception->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSame(CompanyQccAccount::STATUS_OCCUPIED, $account->fresh()->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_indeterminate_response_marks_selected_account_unknown_but_explicit_failure_does_not(): void
|
||||||
|
{
|
||||||
|
$company = $this->company();
|
||||||
|
$account = $this->selectedAccount($company);
|
||||||
|
$service = new QccCallService();
|
||||||
|
|
||||||
|
$service->call(
|
||||||
|
$company,
|
||||||
|
'enterprise-profile',
|
||||||
|
'request-business-failed',
|
||||||
|
fn() => ['code' => 400],
|
||||||
|
fn($result) => $result['code'] === 200,
|
||||||
|
fn($result) => !array_key_exists('code', $result)
|
||||||
|
);
|
||||||
|
$this->assertSame(CompanyQccAccount::STATUS_SELECTED, $account->fresh()->status);
|
||||||
|
|
||||||
|
$service->call(
|
||||||
|
$company,
|
||||||
|
'enterprise-profile',
|
||||||
|
'request-unparseable',
|
||||||
|
fn() => [],
|
||||||
|
fn($result) => ($result['code'] ?? null) === 200,
|
||||||
|
fn($result) => !array_key_exists('code', $result) ? '元禾响应缺少业务状态码' : false
|
||||||
|
);
|
||||||
|
$account = $account->fresh();
|
||||||
|
$this->assertSame(CompanyQccAccount::STATUS_UNKNOWN, $account->status);
|
||||||
|
$this->assertSame('元禾响应缺少业务状态码', $account->unknown_note);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_result_classifier_exception_marks_selected_account_unknown(): void
|
||||||
|
{
|
||||||
|
$company = $this->company();
|
||||||
|
$account = $this->selectedAccount($company);
|
||||||
|
$service = new QccCallService();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$service->call(
|
||||||
|
$company,
|
||||||
|
'enterprise-profile',
|
||||||
|
'request-classifier-error',
|
||||||
|
fn() => [],
|
||||||
|
function () {
|
||||||
|
throw new RuntimeException('响应字段不完整');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$this->fail('Expected classifier exception was not thrown.');
|
||||||
|
} catch (RuntimeException $exception) {
|
||||||
|
$this->assertSame('响应字段不完整', $exception->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$account = $account->fresh();
|
||||||
|
$this->assertSame(CompanyQccAccount::STATUS_UNKNOWN, $account->status);
|
||||||
|
$this->assertStringContainsString('调用结果判定异常', $account->unknown_note);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function company(): Company
|
||||||
|
{
|
||||||
|
$id = DB::table('companies')->insertGetId([
|
||||||
|
'company_name' => '测试企业',
|
||||||
|
'credit_code' => '91320100TEST00001',
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
return Company::findOrFail($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function selectedAccount(Company $company, string $status = CompanyQccAccount::STATUS_SELECTED): CompanyQccAccount
|
||||||
|
{
|
||||||
|
return CompanyQccAccount::create([
|
||||||
|
'company_id' => $company->id,
|
||||||
|
'status' => $status,
|
||||||
|
'selected_at' => now(),
|
||||||
|
'first_success_at' => $status === CompanyQccAccount::STATUS_OCCUPIED ? now()->subMinute() : null,
|
||||||
|
'first_success_source' => $status === CompanyQccAccount::STATUS_OCCUPIED ? 'seed' : null,
|
||||||
|
'first_success_ref' => $status === CompanyQccAccount::STATUS_OCCUPIED ? 'seed-ref' : null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue