, * rows: mixed, * filters: array, * periods: list, * statuses: list, * stores: list, * import: ?array, * summary: array, * error: ?string * } */ public function build(Request $request, int $companyId): array { $stores = array_values((array) config('kuka_posting.stores', [])); $fields = array_values((array) config('kuka_posting.fields', [])); $available = $this->repository->available(); $periods = $available ? $this->repository->periods($companyId) : []; $latest = $available ? $this->repository->latestImport($companyId) : null; $period = trim((string) $request->query('period', '')); if (preg_match('/^\d{4}-(0[1-9]|1[0-2])$/', $period) !== 1) { $period = (string) ($latest->period ?? ($periods[0] ?? now()->format('Y-m'))); } $storeName = trim((string) $request->query('store_name', '')); if ($storeName !== '' && ! in_array($storeName, $stores, true)) { $storeName = ''; } $status = mb_substr(trim((string) $request->query('status', '')), 0, 64); $keyword = mb_substr(trim((string) $request->query('keyword', '')), 0, 120); $perPage = (int) $request->integer('per_page', 50); if (! in_array($perPage, [50, 100, 200], true)) { $perPage = 50; } $page = max(1, (int) $request->integer('page', 1)); $filters = [ 'period' => $period, 'store_name' => $storeName, 'status' => $status, 'keyword' => $keyword, 'per_page' => $perPage, ]; $error = $available ? null : '顾家过账基础数据镜像尚未建立,请先执行数据库迁移。'; try { $rows = $available ? $this->repository->paginate($companyId, $period, $filters, $page, $perPage) : new LengthAwarePaginator([], 0, $perPage, $page, [ 'path' => $request->url(), 'query' => $request->query(), ]); $rows->setCollection($rows->getCollection()->map(function (object $row): object { $values = json_decode((string) $row->source_values, true); if (! is_array($values)) { $values = []; } $values['_row_id'] = $row->id; return (object) $values; })); $statuses = $available ? $this->repository->statuses($companyId, $period) : []; } catch (Throwable $exception) { report($exception); $statuses = []; $error = '顾家过账基础数据暂时无法读取,请稍后重试;这不代表业务数据为 0。'; $rows = new LengthAwarePaginator([], 0, $perPage, $page, [ 'path' => $request->url(), 'query' => $request->query(), ]); } $import = $available ? $this->repository->importFor($companyId, $period) : null; $importData = null; if ($import !== null) { $storeCounts = json_decode((string) ($import->store_counts ?? ''), true); $importData = [ 'period' => (string) $import->period, 'row_count' => (int) $import->row_count, 'store_count' => (int) $import->store_count, 'order_count' => (int) $import->order_count, 'store_counts' => is_array($storeCounts) ? $storeCounts : [], 'file_name' => (string) $import->file_name, 'file_sha256' => (string) $import->file_sha256, 'source_sheet' => (string) $import->source_sheet, 'completed_at' => (string) $import->completed_at, ]; } return [ 'directory' => [ 'icon' => 'dataset', 'status' => $importData === null ? '尚未导入' : '聚水潭原始明细', 'description' => '聚水潭“销售主题分析(新版)· 商品利润 · 明细(订单商品)”原始导出。仅保留指定 12 家店铺的 ' . $period . ' 数据。', 'empty' => '该账期还没有导入顾家过账基础数据。', 'fields' => $fields, ], 'rows' => $rows, 'filters' => $filters, 'periods' => $periods, 'statuses' => $statuses, 'stores' => $stores, 'import' => $importData, 'summary' => [ 'filtered_rows' => $rows->total(), 'rows' => (int) ($importData['row_count'] ?? 0), 'stores' => (int) ($importData['store_count'] ?? 0), 'orders' => (int) ($importData['order_count'] ?? 0), 'completed_at' => $importData['completed_at'] ?? null, ], 'error' => $error, ]; } }