verify_portal_pin ?? '')); if ($pin === '' || ! preg_match('/^\d{6}$/', $pin)) { throw new \InvalidArgumentException('场馆抢票核销口令无效'); } $vid = (int) $venue->id; /** @var VerifyPortalCredential|null $cred */ $cred = VerifyPortalCredential::query() ->where('portal_kind', VerifyPortalCredential::KIND_TICKET_GRAB_VENUE) ->where('portal_id', $vid) ->where('username', self::CRED_USERNAME) ->first(); $attributes = [ 'venue_id' => $vid, 'password' => Hash::make($pin), 'password_plain_enc' => Crypt::encryptString($pin), 'note' => null, ]; if ($cred !== null) { $cred->forceFill($attributes)->save(); return $cred; } return VerifyPortalCredential::query()->create(array_merge([ 'portal_kind' => VerifyPortalCredential::KIND_TICKET_GRAB_VENUE, 'portal_id' => $vid, 'username' => self::CRED_USERNAME, ], $attributes)); } public static function ensure(Venue $venue): string { $venue->refresh(); $pinOut = trim((string) ($venue->verify_portal_pin ?? '')); if ($pinOut !== '' && preg_match('/^\d{6}$/', $pinOut)) { self::syncPinCredential($venue); return $pinOut; } DB::transaction(function () use ($venue): void { $fresh = Venue::query()->whereKey($venue->id)->lockForUpdate()->first(); if ($fresh === null) { return; } $p = trim((string) ($fresh->verify_portal_pin ?? '')); if ($p !== '' && preg_match('/^\d{6}$/', $p)) { return; } $fresh->forceFill(['verify_portal_pin' => PortalSixDigitPin::generateUnique()])->saveQuietly(); }); $venue->refresh(); $pinOut = trim((string) ($venue->verify_portal_pin ?? '')); self::syncPinCredential($venue); return $pinOut; } }