112 lines
4.3 KiB
PHP
112 lines
4.3 KiB
PHP
<?php
|
||
|
||
namespace Modules\EcommerceFinance\View;
|
||
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Pagination\LengthAwarePaginator;
|
||
use Modules\EcommerceFinance\Repositories\DingProcessDetailMirrorRepository;
|
||
use Throwable;
|
||
|
||
class ProcessDetailsPageData
|
||
{
|
||
public const PER_PAGE_OPTIONS = [50, 100, 200];
|
||
|
||
public const DEFAULT_PER_PAGE = 50;
|
||
|
||
public function __construct(
|
||
private readonly DingProcessDetailMirrorRepository $repository,
|
||
) {}
|
||
|
||
public static function normalizePerPage(mixed $value): int
|
||
{
|
||
$perPage = (int) $value;
|
||
|
||
return in_array($perPage, self::PER_PAGE_OPTIONS, true)
|
||
? $perPage
|
||
: self::DEFAULT_PER_PAGE;
|
||
}
|
||
|
||
/** @return array<string,mixed> */
|
||
public function page(Request $request): array
|
||
{
|
||
$filters = $this->filters($request);
|
||
$page = max((int) $request->query('page', 1), 1);
|
||
$perPage = self::normalizePerPage($request->query('per_page'));
|
||
|
||
try {
|
||
$result = $this->repository->paginate($filters, $page, $perPage);
|
||
$options = $this->repository->filterOptions();
|
||
|
||
return [
|
||
'processRows' => new LengthAwarePaginator(
|
||
$result['data'],
|
||
$result['total'],
|
||
$perPage,
|
||
$page,
|
||
['path' => $request->url(), 'query' => $request->except('page')],
|
||
),
|
||
'filters' => $filters,
|
||
'summary' => $result['summary'],
|
||
'documentTypes' => $options['document_types'],
|
||
'statuses' => $options['statuses'],
|
||
'paymentStates' => $options['payment_states'],
|
||
'mirrorStatus' => $result['status'],
|
||
'mirrorSyncedAt' => $result['last_synced_at'],
|
||
'mirrorStale' => $result['sync_stale'] ?? false,
|
||
'mirrorStaleAfterMinutes' => $result['sync_stale_after_minutes'] ?? 15,
|
||
'scope' => $result['scope'],
|
||
'error' => null,
|
||
];
|
||
} catch (Throwable $exception) {
|
||
report($exception);
|
||
|
||
return [
|
||
'processRows' => new LengthAwarePaginator([], 0, $perPage, $page, [
|
||
'path' => $request->url(),
|
||
'query' => $request->except('page'),
|
||
]),
|
||
'filters' => $filters,
|
||
'summary' => [
|
||
'rows' => 0,
|
||
'approvals' => 0,
|
||
'amount_total' => 0.0,
|
||
'bank_amount_total' => 0.0,
|
||
],
|
||
'documentTypes' => [],
|
||
'statuses' => [],
|
||
'paymentStates' => [],
|
||
'mirrorStatus' => 'unavailable',
|
||
'mirrorSyncedAt' => null,
|
||
'mirrorStale' => false,
|
||
'mirrorStaleAfterMinutes' => 15,
|
||
'scope' => $this->repository->scope(),
|
||
'error' => 'OA流程镜像尚未完成导入,请稍后重试。',
|
||
];
|
||
}
|
||
}
|
||
|
||
/** @return array<string,string> */
|
||
private function filters(Request $request): array
|
||
{
|
||
$paidDate = trim((string) $request->query('paid_date', ''));
|
||
$status = trim((string) $request->query('status', ''));
|
||
$paidDateValid = preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $paidDate, $dateParts) === 1
|
||
&& checkdate((int) $dateParts[2], (int) $dateParts[3], (int) $dateParts[1]);
|
||
$paymentState = trim((string) $request->query('payment_state', ''));
|
||
if (! in_array($paymentState, DingProcessDetailMirrorRepository::PAYMENT_STATES, true)
|
||
&& $paymentState !== DingProcessDetailMirrorRepository::LEGACY_PAYMENT_STATE) {
|
||
$paymentState = '';
|
||
}
|
||
|
||
return [
|
||
'paid_date' => $paidDateValid ? $paidDate : '',
|
||
'document_type' => mb_substr(trim((string) $request->query('document_type', '')), 0, 100),
|
||
'status' => mb_substr($status, 0, 20),
|
||
'payment_state' => $paymentState,
|
||
'business_id' => mb_substr(trim((string) $request->query('business_id', '')), 0, 32),
|
||
'originator_name' => mb_substr(trim((string) $request->query('originator_name', '')), 0, 100),
|
||
'keyword' => mb_substr(trim((string) $request->query('keyword', '')), 0, 100),
|
||
];
|
||
}
|
||
}
|