now = ($now ?? new \DateTimeImmutable())->setTimezone(new \DateTimeZone('Asia/Shanghai'))->format('Y-m-d H:i:s'); } private function present(array $row): array { foreach (['id', 'sort', 'status'] as $field) $row[$field] = (int)$row[$field]; $row['delivery_status'] = ContentPolicy::status($row, $this->now); $row['status_label'] = ContentPolicy::LABELS[$row['delivery_status']]; return $row; } private function packages(): array { return WaterPackage::query()->alias('p')->join('sa_water_sku as s', 's.id', '=', 'p.sku_id') ->where('p.status', 1)->where('s.status', 1)->orderByDesc('p.id')->limit(3) ->get(['p.id', 'p.name', 'p.buckets', 'p.price_cents', 's.name as sku_name']) ->map(function ($row) { $data = $row->toArray(); foreach (['id', 'buckets', 'price_cents'] as $field) $data[$field] = (int)$data[$field]; return $data; })->all(); } public function dashboard(array $input): array { $keyword = ContentInput::text($input, 'keyword', 120); $status = ContentInput::text($input, 'status', 20); if ($status !== '' && !isset(ContentPolicy::LABELS[$status])) throw new ApiException('投放状态不正确'); $page = ContentInput::integer($input, 'page', 1, 1, 1000000); $limit = ContentInput::integer($input, 'limit', 8, 1, 100); return WaterModel::transaction(function () use ($keyword, $status, $page, $limit) { $query = ContentPolicy::filter(WaterContent::query(), $status, $this->now); if ($keyword !== '') $query->matching('title|region', '%'.$keyword.'%'); $list = $query->orderByDesc('sort')->orderByDesc('id')->pageResult($page, $limit); $list['data'] = array_map($this->present(...), $list['data']); $summary = ['total' => WaterContent::query()->count()]; foreach (ContentPolicy::LABELS as $key => $label) { $summary[$key] = ContentPolicy::filter(WaterContent::query(), $key, $this->now)->count(); } return ['list' => $list, 'summary' => $summary, 'packages' => $this->packages(), 'updated_at' => $this->now]; }); } public function preview(array $input): array { $purchase = ContentInput::text($input, 'purchase_status', 20, 'new'); if (!in_array($purchase, ['new', 'purchased'], true)) throw new ApiException('预览购水状态不正确'); $admin = ContentInput::integer($input, 'is_enterprise_admin', 0, 0, 1); $region = ContentInput::text($input, 'region', 80); if ($region === '全国') $region = ''; $audiences = ['all', $purchase]; if ($admin) $audiences[] = 'enterprise_admin'; return WaterModel::transaction(function () use ($purchase, $admin, $region, $audiences) { $query = ContentPolicy::filter(WaterContent::query(), 'active', $this->now) ->whereIn('audience', $audiences) ->where(fn ($q) => $q->whereNull('region')->orWhere('region', '')->orWhere('region', '全国')->orWhere('region', $region)); $total = (clone $query)->count(); $rows = $query->orderByDesc('sort')->orderByDesc('id')->limit(20)->get()->toArray(); return ['banners' => array_map($this->present(...), $rows), 'total' => $total, 'packages' => $this->packages(), 'context' => ['purchase_status' => $purchase, 'is_enterprise_admin' => $admin, 'region' => $region], 'updated_at' => $this->now]; }); } }