151 lines
5.3 KiB
PHP
151 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Business;
|
|
|
|
use Carbon\CarbonImmutable;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Modules\EcommerceFinance\Services\SupplierDingTalkNotifier;
|
|
use Modules\EcommerceFinance\Services\SupplierSummaryConfirmation;
|
|
use Modules\EcommerceFinance\Services\SupplierSummaryShareLink;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Throwable;
|
|
|
|
/**
|
|
* 钉钉群推送的厂家货款确认页,无需厂家登录。
|
|
*/
|
|
class SupplierSummaryConfirmationShare extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly SupplierSummaryConfirmation $confirmations,
|
|
private readonly SupplierSummaryShareLink $shareLinks,
|
|
private readonly SupplierDingTalkNotifier $notifier,
|
|
) {
|
|
}
|
|
|
|
public function show(Request $request, string $token): Response
|
|
{
|
|
$target = $this->resolveRecord($request, $token);
|
|
$expiresAt = $this->expiresAt($request);
|
|
|
|
return response()
|
|
->view('business.pages.supplier-reconciliation.summary-confirmation-share', [
|
|
'supplier' => $target['supplier'],
|
|
'month' => $target['month'],
|
|
'monthLabel' => $this->displayMonth($target['month']),
|
|
'qty' => (float) ($target['record']['qty'] ?? 0),
|
|
'amount' => (float) ($target['record']['amount'] ?? 0),
|
|
'status' => (string) ($target['record']['status'] ?? ''),
|
|
'confirmedAt' => (string) ($target['record']['confirmed_at'] ?? ''),
|
|
'expiresAt' => $expiresAt,
|
|
'confirmUrl' => $this->shareLinks->signedRoute(
|
|
'signed.supplier-summary-confirmations.confirm',
|
|
$token,
|
|
$target['companyId'],
|
|
$expiresAt,
|
|
),
|
|
])
|
|
->withHeaders([
|
|
'Cache-Control' => 'private, no-store, max-age=0',
|
|
'X-Robots-Tag' => 'noindex, nofollow, noarchive',
|
|
'Referrer-Policy' => 'no-referrer',
|
|
]);
|
|
}
|
|
|
|
public function confirm(Request $request, string $token): RedirectResponse
|
|
{
|
|
$target = $this->resolveRecord($request, $token);
|
|
if (($target['record']['status'] ?? '') === SupplierSummaryConfirmation::STATUS_CONFIRMED) {
|
|
return $this->redirectToPage($request, $token, $target)
|
|
->with('success', '本期货款已经确认,无需重复操作。');
|
|
}
|
|
|
|
$result = $this->confirmations->confirm(
|
|
$target['request_id'],
|
|
$target['companyId'],
|
|
null,
|
|
'',
|
|
'manufacturer_link',
|
|
);
|
|
|
|
if ($result['newly_confirmed']) {
|
|
try {
|
|
$this->notifier->sendSummaryConfirmationReceipt($result['record']);
|
|
} catch (Throwable $exception) {
|
|
report($exception);
|
|
}
|
|
}
|
|
|
|
return $this->redirectToPage($request, $token, $target)
|
|
->with(
|
|
'success',
|
|
$result['newly_confirmed']
|
|
? '已确认本期货款,财务系统已实时更新。'
|
|
: '本期货款已经确认,无需重复操作。',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* supplier:string,
|
|
* month:string,
|
|
* push_basis:string,
|
|
* request_id:string,
|
|
* companyId:int,
|
|
* record:array<string,mixed>
|
|
* }
|
|
*/
|
|
private function resolveRecord(Request $request, string $token): array
|
|
{
|
|
$companyId = (int) ($request->route('company_id') ?: company_id() ?: 1);
|
|
$payload = $this->shareLinks->resolveToken($token, $companyId);
|
|
abort_if($payload === null, 404, '该货款确认链接无效或已过期。');
|
|
|
|
$record = $this->confirmations->find($payload['request_id'], $companyId);
|
|
abort_if($record === null, 404, '该货款确认记录不存在,请联系财务重新发送。');
|
|
abort_unless(
|
|
trim((string) ($record['supplier'] ?? '')) === $payload['supplier']
|
|
&& trim((string) ($record['month'] ?? '')) === $payload['month']
|
|
&& trim((string) ($record['push_basis'] ?? '')) === $payload['push_basis'],
|
|
404,
|
|
'该货款确认记录与链接不一致。',
|
|
);
|
|
|
|
return [
|
|
...$payload,
|
|
'companyId' => $companyId,
|
|
'record' => $record,
|
|
];
|
|
}
|
|
|
|
/** @param array<string,mixed> $target */
|
|
private function redirectToPage(Request $request, string $token, array $target): RedirectResponse
|
|
{
|
|
$pageUrl = $this->shareLinks->signedRoute(
|
|
'signed.supplier-summary-confirmations.show',
|
|
$token,
|
|
$target['companyId'],
|
|
$this->expiresAt($request),
|
|
);
|
|
|
|
return redirect()->to($pageUrl);
|
|
}
|
|
|
|
private function expiresAt(Request $request): CarbonImmutable
|
|
{
|
|
$expires = (int) $request->query('expires', 0);
|
|
|
|
return $expires > 0
|
|
? CarbonImmutable::createFromTimestamp($expires)
|
|
: now()->addDays(SupplierSummaryShareLink::TTL_DAYS);
|
|
}
|
|
|
|
private function displayMonth(string $month): string
|
|
{
|
|
[$year, $monthNumber] = explode('-', $month, 2);
|
|
|
|
return (int) $year . '年' . (int) $monthNumber . '月';
|
|
}
|
|
}
|