CaiWuXiTong/modules/EcommerceFinance/View/OrderProfitPageData.php

160 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Modules\EcommerceFinance\View;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
use Modules\EcommerceFinance\Repositories\OrderProfitRepository;
use Throwable;
class OrderProfitPageData
{
public function __construct(private readonly OrderProfitRepository $repository)
{
}
public function page(): array
{
return ['view' => 'business.pages.order-data.order-profit'] + $this->data();
}
public function data(?array $input = null, ?int $page = null, ?int $limit = null): array
{
$filters = $this->filters($input);
$page = max($page ?? (int) request('page', 1), 1);
$limit = min(max($limit ?? (int) setting('default.list_limit', 25), 1), 100);
$rows = $this->paginator([], $filters, $page, $limit);
$error = null;
$status = $this->repository->status();
$hasFilters = $this->hasFilters($filters);
if ($hasFilters && ($status['ready'] ?? false)) {
try {
$result = $this->repository->paginate($filters, $page, $limit);
$rows = $this->paginator(
(array) ($result['rows'] ?? []),
$filters,
$page,
$limit,
(bool) ($result['has_more'] ?? false),
);
} catch (Throwable $exception) {
report($exception);
$error = '订单利润数据暂时无法读取,请稍后重试。';
}
} elseif ($hasFilters && ! ($status['ready'] ?? false)) {
$error = '订单利润共享镜像尚未完成首次同步。';
}
return [
'orderProfitRows' => $rows,
'orderProfitFilters' => $filters,
'orderProfitShopOptions' => $this->repository->shopNames(),
'orderProfitStatus' => $status,
'orderProfitError' => $error,
'orderProfitHasFilters' => $hasFilters,
];
}
/** @return array{from:string,to:string,order_no:string,shop_name:string,shop_names:array<int,string>,sku_id:string} */
private function filters(?array $input): array
{
$input ??= request()->query();
$shops = [];
$rawShops = $input['shop_name'] ?? $input['shop_names'] ?? [];
foreach ((array) $rawShops as $shop) {
$shop = trim((string) $shop);
if ($shop !== '') {
$shops[$shop] = true;
}
if (count($shops) >= 50) {
break;
}
}
$orderNo = $this->batchText($input['order_no'] ?? null);
$sku = $this->batchText($input['sku_id'] ?? null);
$hasOtherFilters = $orderNo !== '' || $sku !== '' || $shops !== [];
$datesWereSubmitted = array_key_exists('from', $input) || array_key_exists('to', $input);
$reset = ! empty($input['reset']);
$from = $this->date($input['from'] ?? null);
$to = $this->date($input['to'] ?? null);
if (! $datesWereSubmitted && ! $reset && ! $hasOtherFilters) {
$from = now()->subDays(6)->toDateString();
$to = now()->toDateString();
}
return [
'from' => $from,
'to' => $to,
'order_no' => $orderNo,
'shop_name' => implode("\n", array_keys($shops)),
'shop_names' => array_keys($shops),
'sku_id' => $sku,
];
}
private function date(mixed $value): string
{
$value = trim((string) $value);
if ($value === '') {
return '';
}
$timestamp = strtotime($value);
return $timestamp === false ? '' : date('Y-m-d', $timestamp);
}
private function batchText(mixed $value): string
{
$values = is_array($value) ? $value : preg_split('/[\r\n,,;;]+/u', (string) $value);
$items = [];
foreach ((array) $values as $item) {
$item = trim((string) $item);
if ($item !== '') {
$items[$item] = true;
}
if (count($items) >= 100) {
break;
}
}
return implode("\n", array_keys($items));
}
private function hasFilters(array $filters): bool
{
return trim((string) $filters['order_no']) !== ''
|| trim((string) $filters['shop_name']) !== ''
|| trim((string) $filters['sku_id']) !== ''
|| $filters['from'] !== ''
|| $filters['to'] !== '';
}
private function paginator(
array $rows,
array $filters,
int $page,
int $limit,
?bool $hasMore = null,
): Paginator {
$paginator = new Paginator(
Collection::make($rows)->map(static fn (array $row): object => (object) $row),
$limit,
$page,
[
'path' => request()->url(),
'query' => request()->except('page'),
],
);
if ($hasMore !== null) {
$paginator->hasMorePagesWhen($hasMore);
}
return $paginator;
}
}