CaiWuXiTong/app/Business/KukaPostingBase/KukaPostingBasePageData.php
chenxi bde661a119 feat: 接入顾家过账基础数据 (#1049)
feat: 接入顾家过账基础数据 (#1049)
2026-11-10 17:08:41 +08:00

132 lines
5.3 KiB
PHP

<?php
namespace App\Business\KukaPostingBase;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Http\Request;
use Throwable;
class KukaPostingBasePageData
{
public function __construct(private readonly KukaPostingBaseRepository $repository)
{
}
/**
* @return array{
* directory: array<string, mixed>,
* rows: mixed,
* filters: array<string, mixed>,
* periods: list<string>,
* statuses: list<string>,
* stores: list<string>,
* import: ?array<string, mixed>,
* summary: array<string, mixed>,
* 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,
];
}
}