79 lines
2.5 KiB
PHP
79 lines
2.5 KiB
PHP
<?php
|
||
|
||
namespace Modules\EcommerceFinance\Services;
|
||
|
||
use DateTimeInterface;
|
||
use Illuminate\Support\Facades\Crypt;
|
||
use Illuminate\Support\Facades\URL;
|
||
use Throwable;
|
||
|
||
/**
|
||
* 厂家退货明细的临时免登录链接。
|
||
*
|
||
* 厂家、月份和公司使用加密令牌承载,再由 Laravel 签名绑定 URL,避免通过
|
||
* 修改链接参数查看其他厂家数据。
|
||
*/
|
||
class SupplierReturnShareLink
|
||
{
|
||
public const TTL_DAYS = 30;
|
||
|
||
public function pageUrl(int $companyId, string $supplier, string $month): string
|
||
{
|
||
return $this->signedRoute(
|
||
'signed.supplier-returns.show',
|
||
$this->token($companyId, $supplier, $month),
|
||
$companyId,
|
||
now()->addDays(self::TTL_DAYS),
|
||
);
|
||
}
|
||
|
||
public function signedRoute(
|
||
string $routeName,
|
||
string $token,
|
||
int $companyId,
|
||
?DateTimeInterface $expires = null,
|
||
): string {
|
||
return URL::temporarySignedRoute($routeName, $expires ?? now()->addDays(self::TTL_DAYS), [
|
||
'company_id' => $companyId,
|
||
'token' => $token,
|
||
]);
|
||
}
|
||
|
||
/** @return array{supplier:string,month:string}|null */
|
||
public function resolveToken(string $token, int $companyId): ?array
|
||
{
|
||
try {
|
||
$padding = (4 - strlen($token) % 4) % 4;
|
||
$encoded = strtr($token . str_repeat('=', $padding), '-_', '+/');
|
||
$encrypted = base64_decode($encoded, true);
|
||
if ($encrypted === false) {
|
||
return null;
|
||
}
|
||
|
||
$payload = json_decode(Crypt::decryptString($encrypted), true, flags: JSON_THROW_ON_ERROR);
|
||
} catch (Throwable) {
|
||
return null;
|
||
}
|
||
|
||
$supplier = is_array($payload) ? trim((string) ($payload['supplier'] ?? '')) : '';
|
||
$month = is_array($payload) ? trim((string) ($payload['month'] ?? '')) : '';
|
||
$payloadCompanyId = is_array($payload) ? (int) ($payload['company_id'] ?? 0) : 0;
|
||
if ($supplier === '' || $payloadCompanyId !== $companyId || preg_match('/^\d{4}-\d{2}$/', $month) !== 1) {
|
||
return null;
|
||
}
|
||
|
||
return ['supplier' => $supplier, 'month' => $month];
|
||
}
|
||
|
||
private function token(int $companyId, string $supplier, string $month): string
|
||
{
|
||
$payload = json_encode([
|
||
'company_id' => $companyId,
|
||
'supplier' => $supplier,
|
||
'month' => $month,
|
||
], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
|
||
|
||
return rtrim(strtr(base64_encode(Crypt::encryptString($payload)), '+/', '-_'), '=');
|
||
}
|
||
}
|