'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,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; } }