56 lines
2.1 KiB
PHP
56 lines
2.1 KiB
PHP
<?php
|
||
|
||
namespace App\Support;
|
||
|
||
use App\Models\Business\CourierAgreementSignature;
|
||
use App\Services\Esign\EsignClient;
|
||
use Illuminate\Support\Facades\Storage;
|
||
use RuntimeException;
|
||
|
||
final class CourierAgreementFileArchive
|
||
{
|
||
public function sourcePath(CourierAgreementSignature $signature): string
|
||
{
|
||
$path = trim((string) $signature->source_pdf_path);
|
||
if ($path === '') {
|
||
throw new RuntimeException('该历史任务没有保存签署原文路径,无法下载。');
|
||
}
|
||
|
||
$disk = Storage::disk('uploads');
|
||
if ($disk->exists($path)) {
|
||
return $path;
|
||
}
|
||
|
||
if (blank($signature->esign_file_id)) {
|
||
throw new RuntimeException('本地历史文件缺失,且该任务未成功上传至 E 签宝,无法自动恢复。');
|
||
}
|
||
|
||
$expectedHash = strtolower(trim((string) $signature->source_pdf_sha256));
|
||
if (preg_match('/^[a-f0-9]{64}$/', $expectedHash) !== 1) {
|
||
throw new RuntimeException('本地历史文件缺失,且没有可用于校验的原文件摘要,已停止自动恢复。');
|
||
}
|
||
|
||
$bytes = app(EsignClient::class)->downloadUploadedPdf((string) $signature->esign_file_id);
|
||
if (! str_starts_with($bytes, '%PDF-')) {
|
||
throw new RuntimeException('E 签宝返回的历史原文件不是有效 PDF,已停止自动恢复。');
|
||
}
|
||
|
||
if (! hash_equals($expectedHash, hash('sha256', $bytes))) {
|
||
throw new RuntimeException('E 签宝历史原文件与系统留存摘要不一致,已停止自动恢复。');
|
||
}
|
||
|
||
if (! $disk->put($path, $bytes)) {
|
||
throw new RuntimeException('历史原文件无法写回私有业务存储。');
|
||
}
|
||
|
||
$storedBytes = $disk->get($path);
|
||
if (! str_starts_with($storedBytes, '%PDF-')
|
||
|| ! hash_equals($expectedHash, hash('sha256', $storedBytes))) {
|
||
$disk->delete($path);
|
||
throw new RuntimeException('历史原文件写回后校验失败,已移除不完整文件。');
|
||
}
|
||
|
||
return $path;
|
||
}
|
||
}
|