110 lines
5.0 KiB
PHP
110 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Business;
|
|
|
|
use App\Models\Business\CourierQuoteSignature;
|
|
use App\Models\Business\CourierQuoteVersion;
|
|
use App\Services\Esign\EsignClient;
|
|
use App\Support\CourierQuoteSignatureService;
|
|
use App\Utilities\SystemAccess;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class CourierQuoteSignatures extends Controller
|
|
{
|
|
public function __construct(private readonly CourierQuoteSignatureService $service)
|
|
{
|
|
}
|
|
|
|
public function prepare(Request $request, CourierQuoteVersion $quoteVersion): RedirectResponse
|
|
{
|
|
$this->ensureCanManage();
|
|
abort_unless($quoteVersion->status === 'approved', 422, '只有已审核报价版本可以生成签署文件。');
|
|
$data = $request->validate([
|
|
'signature_date' => ['required', 'date'],
|
|
]);
|
|
$signature = $this->service->prepareVersion($quoteVersion, user_id(), $data['signature_date']);
|
|
|
|
return redirect()->route('business.courier-quote-changes.show', $quoteVersion->source_change_id)
|
|
->with('success', "{$quoteVersion->version_code} 的签署 PDF 已生成,文件校验值已固定。")
|
|
->with('signature_id', $signature->id);
|
|
}
|
|
|
|
public function send(Request $request, CourierQuoteSignature $quoteSignature): RedirectResponse
|
|
{
|
|
$this->ensureCanManage();
|
|
abort_unless($quoteSignature->version?->status === 'approved', 422, '只有已审核报价版本可以发起签署。');
|
|
abort_unless(EsignClient::configured(), 422, 'E 签宝沙箱尚未配置 App ID 或 AppSecret。');
|
|
$data = $request->validate([
|
|
'organization_name' => ['required', 'string', 'min:2', 'max:255'],
|
|
'operator_name' => ['required', 'string', 'min:2', 'max:100'],
|
|
'operator_account' => ['required', 'string', 'max:255'],
|
|
'notice_type' => ['required', 'in:1,2'],
|
|
'signature_date' => ['required', 'date'],
|
|
'expires_at' => ['required', 'date', 'after:now', 'before_or_equal:' . now()->addDays(90)->toDateTimeString()],
|
|
]);
|
|
$this->validateAccountForNotice($data['operator_account'], $data['notice_type']);
|
|
$quoteSignature = $this->service->prepareVersion(
|
|
$quoteSignature->version,
|
|
user_id(),
|
|
$data['signature_date'],
|
|
);
|
|
$signature = $this->service->send($quoteSignature, $data, user_id());
|
|
$environment = $signature->environment === 'sandbox' ? '沙箱' : '正式环境';
|
|
|
|
return redirect()->route('business.courier-quote-changes.show', $signature->version->source_change_id)
|
|
->with('success', "{$signature->version->version_code} 已推送到 E 签宝{$environment},等待快递公司签署。");
|
|
}
|
|
|
|
public function synchronize(CourierQuoteSignature $quoteSignature): RedirectResponse
|
|
{
|
|
$this->ensureCanManage();
|
|
$signature = $this->service->synchronize($quoteSignature, user_id());
|
|
$message = $signature->status === CourierQuoteSignature::STATUS_ARCHIVED
|
|
? '签署完成,签署 PDF 和完成证书已私有归档。'
|
|
: "已同步 E 签宝状态:{$signature->statusLabel()}。";
|
|
|
|
return redirect()->route('business.courier-quote-changes.show', $signature->version->source_change_id)
|
|
->with('success', $message);
|
|
}
|
|
|
|
public function download(CourierQuoteSignature $quoteSignature, string $kind): StreamedResponse
|
|
{
|
|
[$path, $suffix] = match ($kind) {
|
|
'source' => [$quoteSignature->source_pdf_path, '报价签署原文'],
|
|
'signed' => [$quoteSignature->signed_pdf_path, '已签署报价'],
|
|
'certificate' => [$quoteSignature->certificate_path, '签署完成证书'],
|
|
default => abort(404),
|
|
};
|
|
|
|
abort_if(blank($path) || ! \Storage::disk('uploads')->exists($path), 404, '归档文件不存在。');
|
|
$fileName = $quoteSignature->version->version_code . '-' . $suffix . '.pdf';
|
|
|
|
return \Storage::disk('uploads')->download($path, $fileName, ['Content-Type' => 'application/pdf']);
|
|
}
|
|
|
|
private function validateAccountForNotice(string $account, string $noticeType): void
|
|
{
|
|
$valid = $noticeType === '1'
|
|
? preg_match('/^1\d{10}$/', $account) === 1
|
|
: filter_var($account, FILTER_VALIDATE_EMAIL) !== false;
|
|
|
|
if (! $valid) {
|
|
$message = $noticeType === '1' ? '短信通知必须填写 11 位手机号。' : '邮件通知必须填写有效邮箱。';
|
|
throw ValidationException::withMessages(['operator_account' => $message]);
|
|
}
|
|
}
|
|
|
|
private function ensureCanManage(): void
|
|
{
|
|
abort_unless(
|
|
in_array(SystemAccess::roleName(user()), [SystemAccess::SUPER_ADMIN, SystemAccess::ADMIN], true),
|
|
403,
|
|
'当前账号没有报价签署管理权限。',
|
|
);
|
|
}
|
|
}
|