$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, 'afterSalesWorkOrders' => $this->afterSalesWorkOrders($filters), ]; } $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, 'afterSalesWorkOrders' => $this->afterSalesWorkOrders($filters), ]; } 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, 'afterSalesWorkOrders' => $this->emptyAfterSalesWorkOrders(), ]; } /** @param array $filters */ private function afterSalesWorkOrders(array $filters): array { if ($this->workOrderMirror === null) { return $this->emptyAfterSalesWorkOrders(); } try { return $this->workOrderMirror->paginateAfterSales( max((int) request('work_order_page', 1), 1), 10, $filters, ); } catch (Throwable) { return $this->emptyAfterSalesWorkOrders(); } } /** @return array{data:list>,total:int,page:int,per_page:int,last_page:int,ready:bool,sync_status:array} */ private function emptyAfterSalesWorkOrders(): array { return [ 'data' => [], 'total' => 0, 'page' => max((int) request('work_order_page', 1), 1), 'per_page' => 10, 'last_page' => 1, 'ready' => false, 'sync_status' => [ 'ready' => false, 'code' => 'unavailable', 'last_succeeded_at' => null, 'datasets' => [], ], ]; } 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 : ''; } }