$this->companyPage($currentPage, $perPage), 'store-management/basic-information' => $this->storePage($currentPage, $perPage), 'trademark-management/information' => $this->trademarkPage($currentPage, $perPage), default => ['data' => [], 'total' => 0], }; return new LengthAwarePaginator( array_map(static fn (array $row) => (object) $row, $payload['data']), (int) $payload['total'], $perPage, $currentPage, [ 'path' => request()->url(), 'query' => request()->query(), ], ); } /** * 将已登记的经营分析副本库查询还原成不经过页面缓存的固定只读查询。 * * 生产后台刷新器使用这个入口生成共享快照;页面仍然只能通过 * UpstreamQueryCache 读取快照,不能绕过缓存直接访问上游。 * * @return array{data: array>, total: int} */ public function snapshot(string $scope, array $parameters): array { $page = max((int) ($parameters['page'] ?? 1), 1); $perPage = min(max((int) ($parameters['perPage'] ?? 50), 1), 100); $query = new UpstreamReadOnlyQuery(self::SOURCE); return match ($scope) { 'company-information.read' => $this->companySnapshot($query, $page, $perPage), 'store-information.read' => $this->storeSnapshot($query, $page, $perPage), 'trademark-information.read' => $this->trademarkSnapshot($query, $page, $perPage), default => throw new InvalidArgumentException('未知的经营分析副本库快照类型:' . $scope), }; } private function companyPage(int $page, int $perPage): array { return $this->page( 'company-information.read', $page, $perPage, fn () => $this->snapshot('company-information.read', [ 'page' => $page, 'perPage' => $perPage, ]), ); } private function companySnapshot(UpstreamReadOnlyQuery $query, int $page, int $perPage): array { $offset = ($page - 1) * $perPage; $rows = $query->select(<< array_map(fn (array $row) => $this->mapCompany($row), $rows), 'total' => (int) $query->scalar('SELECT COUNT(*) FROM rpt.fys_companyInfo'), ]; } private function storePage(int $page, int $perPage): array { return $this->page( 'store-information.read', $page, $perPage, fn () => $this->snapshot('store-information.read', [ 'page' => $page, 'perPage' => $perPage, ]), ); } private function storeSnapshot(UpstreamReadOnlyQuery $query, int $page, int $perPage): array { $offset = ($page - 1) * $perPage; $rows = $query->select(<< array_map(fn (array $row) => $this->mapStore($row), $rows), 'total' => (int) $query->scalar('SELECT COUNT(*) FROM rpt.fys_shopInfo'), ]; } private function trademarkPage(int $page, int $perPage): array { return $this->page( 'trademark-information.read', $page, $perPage, fn () => $this->snapshot('trademark-information.read', [ 'page' => $page, 'perPage' => $perPage, ]), ); } private function trademarkSnapshot(UpstreamReadOnlyQuery $query, int $page, int $perPage): array { $offset = ($page - 1) * $perPage; $rows = $query->select(<< array_map(fn (array $row) => $this->mapTrademark($row), $rows), 'total' => (int) $query->scalar('SELECT COUNT(*) FROM rpt.fys_TrademarkInfo WHERE isDelete = 0'), ]; } private function page(string $scope, int $page, int $perPage, callable $resolver): array { if ($this->mirror->ready($scope)) { return $this->normalize($scope, $this->mirror->paginate($scope, $page, $perPage)); } $cache = $this->caches->forSource(self::SOURCE); return $cache->remember($scope, compact('page', 'perPage'), function () use ($resolver) { return $resolver(new UpstreamReadOnlyQuery(self::SOURCE)); }); } /** @param array{data: array>, total: int} $payload */ private function normalize(string $scope, array $payload): array { $mapper = match ($scope) { 'company-information.read' => fn (array $row): array => $this->mapCompany($row), 'store-information.read' => fn (array $row): array => $this->mapStore($row), 'trademark-information.read' => fn (array $row): array => $this->mapTrademark($row), default => throw new InvalidArgumentException('未知的经营分析副本库资料类型:' . $scope), }; return [ 'data' => array_map($mapper, $payload['data']), 'total' => (int) $payload['total'], ]; } private function mapCompany(array $row): array { $row = $this->toUtf8($row); $row['establishment_date'] = $this->date($row['establishment_date'] ?? null); $row['company_status'] = match ((string) ($row['company_status'] ?? '')) { '0' => '正常', '1' => '已注销', default => $row['company_status'] ?? null, }; return $row; } private function mapStore(array $row): array { $row = $this->toUtf8($row); $row['opened_at'] = $this->date($row['opened_at'] ?? null); $row['store_status'] = match ((string) ($row['store_status'] ?? '')) { '0' => '正常', '3' => '关闭中', '6' => '已关闭', default => $row['store_status'] ?? null, }; return $row; } private function mapTrademark(array $row): array { $row = $this->toUtf8($row); $row['registration_date'] = $this->date($row['registration_date'] ?? null); $row['expiry_date'] = $this->date($row['expiry_date'] ?? null); $row['trademark_status'] = match ((string) ($row['trademark_status'] ?? '')) { '0' => '未启用', '1' => '有效', default => $row['trademark_status'] ?? null, }; return $row; } private function toUtf8(array $row): array { foreach ($row as &$value) { if (is_string($value) && ! mb_check_encoding($value, 'UTF-8')) { $value = mb_convert_encoding($value, 'UTF-8', 'GB18030'); } } unset($value); return $row; } private function date($value): ?string { if ($value === null || $value === '') { return null; } return substr((string) $value, 0, 10); } }