162 lines
5.9 KiB
PHP
162 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\View;
|
|
|
|
use Illuminate\Pagination\Paginator;
|
|
use Illuminate\Support\Collection;
|
|
use Modules\EcommerceFinance\Repositories\OrderDataRepository;
|
|
use Modules\EcommerceFinance\Repositories\OrderDataMirrorRepository;
|
|
use Modules\EcommerceFinance\Services\UpstreamQueryCacheFactory;
|
|
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
|
use Throwable;
|
|
|
|
class OrderDataPageData
|
|
{
|
|
private const SOURCE = 'operations_replica';
|
|
|
|
public function __construct(
|
|
private readonly OrderDataRepository $orders,
|
|
private readonly UpstreamQueryCacheFactory $caches,
|
|
private readonly ?OrderDataMirrorRepository $mirrorOrders = null,
|
|
) {
|
|
}
|
|
|
|
public function afterSales(): array
|
|
{
|
|
$filters = [
|
|
'from' => $this->date(request('from')) ?: now()->subDays(6)->toDateString(),
|
|
'to' => $this->date(request('to')) ?: now()->toDateString(),
|
|
'order_no' => $this->text(request('order_no')),
|
|
'shop_name' => $this->text(request('shop_name')),
|
|
'sku_id' => $this->text(request('sku_id')),
|
|
];
|
|
[$page, $limit] = $this->pageSettings();
|
|
|
|
try {
|
|
$mirror = $this->mirrorOrders ?? app(OrderDataMirrorRepository::class);
|
|
if ($mirror->ready()) {
|
|
$result = $mirror->afterSales($filters, $page, $limit);
|
|
|
|
return [
|
|
'orderDataRows' => $this->paginator((array) ($result['rows'] ?? []), $page, $limit),
|
|
'orderDataFilters' => $filters,
|
|
'orderDataStatus' => ['X-Caiwu-Data-Status' => 'mirror'],
|
|
'orderDataError' => null,
|
|
];
|
|
}
|
|
|
|
$cache = $this->caches->forSource(self::SOURCE);
|
|
$result = $cache->remember(
|
|
'order-data.after-sales.list',
|
|
compact('filters', 'page', 'limit'),
|
|
fn () => $this->orders->afterSales($filters, $page, $limit),
|
|
);
|
|
|
|
return [
|
|
'orderDataRows' => $this->paginator((array) ($result['rows'] ?? []), $page, $limit),
|
|
'orderDataFilters' => $filters,
|
|
'orderDataStatus' => $cache->responseHeaders(),
|
|
'orderDataError' => null,
|
|
];
|
|
} catch (ServiceUnavailableHttpException $exception) {
|
|
return $this->failed($filters, $page, $limit, $exception->getMessage());
|
|
} catch (Throwable $exception) {
|
|
report($exception);
|
|
|
|
return $this->failed($filters, $page, $limit, '订单售后费用数据暂时无法读取,请稍后重试。');
|
|
}
|
|
}
|
|
|
|
public function promotionExpenses(): array
|
|
{
|
|
$filters = [
|
|
'date' => $this->date(request('date')),
|
|
'shop_name' => $this->text(request('shop_name')),
|
|
'sku_id' => $this->text(request('sku_id')),
|
|
];
|
|
[$page, $limit] = $this->pageSettings();
|
|
|
|
try {
|
|
$mirror = $this->mirrorOrders ?? app(OrderDataMirrorRepository::class);
|
|
if ($mirror->promotionReady()) {
|
|
$result = $mirror->promotionExpenses($filters, $page, $limit);
|
|
|
|
return [
|
|
'orderDataRows' => $this->paginator((array) ($result['rows'] ?? []), $page, $limit),
|
|
'orderDataFilters' => array_replace($filters, ['date' => $result['date'] ?? $filters['date']]),
|
|
'orderDataStatus' => ['X-Caiwu-Data-Status' => 'mirror'],
|
|
'orderDataError' => null,
|
|
];
|
|
}
|
|
|
|
$cache = $this->caches->forSource(self::SOURCE);
|
|
$result = $cache->remember(
|
|
'order-data.promotion.list',
|
|
compact('filters', 'page', 'limit'),
|
|
fn () => $this->orders->promotionExpenses($filters, $page, $limit),
|
|
);
|
|
|
|
return [
|
|
'orderDataRows' => $this->paginator((array) ($result['rows'] ?? []), $page, $limit),
|
|
'orderDataFilters' => array_replace($filters, ['date' => $result['date'] ?? $filters['date']]),
|
|
'orderDataStatus' => $cache->responseHeaders(),
|
|
'orderDataError' => null,
|
|
];
|
|
} catch (ServiceUnavailableHttpException $exception) {
|
|
return $this->failed($filters, $page, $limit, $exception->getMessage());
|
|
} catch (Throwable $exception) {
|
|
report($exception);
|
|
|
|
return $this->failed($filters, $page, $limit, '商品推广费用数据暂时无法读取,请稍后重试。');
|
|
}
|
|
}
|
|
|
|
private function failed(array $filters, int $page, int $limit, string $message): array
|
|
{
|
|
return [
|
|
'orderDataRows' => $this->paginator([], $page, $limit),
|
|
'orderDataFilters' => $filters,
|
|
'orderDataStatus' => [],
|
|
'orderDataError' => $message,
|
|
];
|
|
}
|
|
|
|
private function paginator(array $rows, int $page, int $limit): Paginator
|
|
{
|
|
return new Paginator(
|
|
Collection::make($rows)->map(static fn (array $row): object => (object) $row),
|
|
$limit,
|
|
$page,
|
|
[
|
|
'path' => request()->url(),
|
|
'query' => request()->except('page'),
|
|
],
|
|
);
|
|
}
|
|
|
|
/** @return array{0:int,1:int} */
|
|
private function pageSettings(): array
|
|
{
|
|
return [
|
|
max((int) request('page', 1), 1),
|
|
min(max((int) setting('default.list_limit', 25), 1), 100),
|
|
];
|
|
}
|
|
|
|
private function text(mixed $value): string
|
|
{
|
|
return mb_substr(trim((string) $value), 0, 100);
|
|
}
|
|
|
|
private function date(mixed $value): string
|
|
{
|
|
$value = trim((string) $value);
|
|
|
|
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value, $matches) !== 1) {
|
|
return '';
|
|
}
|
|
|
|
return checkdate((int) $matches[2], (int) $matches[3], (int) $matches[1]) ? $value : '';
|
|
}
|
|
}
|