'operations_replica.rpt.fys_companyInfo', 'store-information.read' => 'operations_replica.rpt.fys_shopInfo', 'trademark-information.read' => 'operations_replica.rpt.fys_TrademarkInfo', ]; private readonly ConnectionInterface $connection; public function __construct( private readonly BusinessMirrorDatasetRegistry $datasets, private readonly GenericBusinessMirrorRepository $mirror, ) { $this->connection = $mirror->connection(); } public function ready(string $scope): bool { return $this->mirror->ready($this->dataset($scope)); } /** @return array{data: array>, total: int} */ public function paginate(string $scope, int $page, int $perPage): array { if (! $this->ready($scope)) { throw new RuntimeException('business_mirror_dataset_not_ready'); } $page = max($page, 1); $perPage = min(max($perPage, 1), 100); return match ($scope) { 'company-information.read' => $this->companies($page, $perPage), 'store-information.read' => $this->stores($page, $perPage), 'trademark-information.read' => $this->trademarks($page, $perPage), default => throw new InvalidArgumentException('未知的业务资料镜像范围:' . $scope), }; } /** @return array{data: array>, total: int} */ private function companies(int $page, int $perPage): array { $query = $this->connection->table('ops_fys_company_info') ->selectRaw(<<<'SQL' Id AS id, unifiedSocialCreditCode AS unified_social_credit_code, businessLicenseName AS company_name, registeredCapital AS subscribed_capital, businessLicenseType AS company_type, IncorporationDate AS establishment_date, legalRepresentative AS legal_representative, registeredAddress AS registered_address, businessScope AS business_scope, accountSerialNumber AS basic_deposit_account_number, companyStatus AS company_status, financialManager AS financial_officer, supervisor AS supervisor, taxCategoryAndType AS taxpayer_category, NULL AS shareholders SQL); return $this->page($query, $page, $perPage, 'Id'); } /** @return array{data: array>, total: int} */ private function stores(int $page, int $perPage): array { $latestCompanies = $this->connection->table('ops_fys_company_info') ->selectRaw('unifiedSocialCreditCode, MAX(Id) AS latest_id') ->whereNotNull('unifiedSocialCreditCode') ->where('unifiedSocialCreditCode', '<>', '') ->groupBy('unifiedSocialCreditCode'); $query = $this->connection->table('ops_fys_shop_info AS s') ->leftJoinSub($latestCompanies, 'company_keys', function ($join): void { $join->on('company_keys.unifiedSocialCreditCode', '=', 's.unifiedSocialCreditCode'); }) ->leftJoin('ops_fys_company_info AS c', 'c.Id', '=', 'company_keys.latest_id') ->selectRaw(<<<'SQL' s.Id AS id, s.openTime AS opened_at, s.erpShopName AS erp_store_name, s.unifiedSocialCreditCode AS unified_social_credit_code, c.businessLicenseName AS company_name, s.trademarkNumber AS trademark_number, NULL AS trademark_name, s.platform AS platform, s.responsibleDepartment AS profit_center, s.shopHead AS store_manager, s.shopState AS store_status, s.shopType AS store_type, s.channelType AS channel_mode SQL); return $this->page($query, $page, $perPage, 's.Id'); } /** @return array{data: array>, total: int} */ private function trademarks(int $page, int $perPage): array { $query = $this->connection->table('ops_fys_trademark_info') ->where('isDelete', 0) ->selectRaw(<<<'SQL' Id AS id, trademarkName AS trademark_name, internationalClassification AS trademark_type, trademarkStatus AS trademark_status, registrationDate AS registration_date, termOfValidity AS expiry_date, remark AS notes SQL); return $this->page($query, $page, $perPage, 'Id'); } /** @return array{data: array>, total: int} */ private function page($query, int $page, int $perPage, string $orderColumn): array { $total = (clone $query)->count(); $rows = $query->orderByDesc($orderColumn) ->forPage($page, $perPage) ->get() ->map(static fn (object $row): array => (array) $row) ->all(); return ['data' => $rows, 'total' => $total]; } private function dataset(string $scope): BusinessMirrorDataset { $key = self::DATASETS[$scope] ?? null; if ($key === null) { throw new InvalidArgumentException('未知的业务资料镜像范围:' . $scope); } return $this->datasets->get($key); } }