| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- <?php
- declare(strict_types=1);
- namespace app\miniapi\service;
- use app\miniapi\http\Fields;
- use app\miniapi\http\Pagination;
- use app\miniapi\exception\ApiException;
- use plugin\saiadmin\app\model\water\WaterPackage;
- use plugin\saiadmin\app\model\water\WaterSku;
- final class Catalog
- {
- public function query()
- {
- return WaterPackage::query()->with('sku')->where('status', 1)->whereIn('sku_id', WaterSku::query()->where('status', 1)->select('id'));
- }
- public function present($package): array
- {
- $sku = $package->sku;
- return [
- 'id' => (int) $package->id,
- 'name' => $package->name,
- 'sku_id' => (int) $package->sku_id,
- 'sku_name' => $sku?->name,
- 'liters' => $sku ? (float) $sku->liters : null,
- 'buckets' => (int) $package->buckets,
- 'price_cents' => (int) $package->price_cents,
- 'unit_price_cents' => (int) round($package->price_cents / max(1, $package->buckets)),
- 'category' => null,
- 'valid_months' => null,
- 'includes_device' => null,
- ];
- }
- public function listing(array $input): array
- {
- $page = new Pagination($input);
- $query = $this->query();
- $keyword = Fields::text($input, 'keyword', 120, false);
- Fields::choice($input, 'category', ['all'], 'all');
- if ($keyword !== '') {
- $query->where('name', 'like', '%' . $keyword . '%');
- }
- $total = (clone $query)->count();
- return $page->result($query->orderByDesc('id')->offset($page->offset())->limit($page->pageSize)->get()->map($this->present(...))->all(), $total)
- + [
- 'categories' => [[
- 'value' => 'all',
- 'label' => '全部',
- ]],
- 'capabilities' => ['category_filter' => false],
- ];
- }
- public function detail(int $id): array
- {
- $package = $this->query()->find($id);
- if (!$package) {
- throw new ApiException(40401, '套餐不存在或已下架', 404);
- }
- return $this->present($package);
- }
- /** Lock the complete set before SKU rows, so creating a checkout has one coherent snapshot. */
- public function lockedDetails(array $ids): array
- {
- $packages = WaterPackage::query()->whereIn('id', $ids)->orderBy('id')->lockForUpdate()->get();
- $skus = WaterSku::query()->whereIn('id', $packages->pluck('sku_id')->unique()->all())
- ->orderBy('id')->lockForUpdate()->get()->keyBy('id');
- $result = [];
- foreach ($packages as $package) {
- $sku = $skus->get($package->sku_id);
- if ((int) $package->status !== 1 || !$sku || (int) $sku->status !== 1) {
- throw new ApiException(40401, '套餐不存在或已下架', 404);
- }
- $package->setRelation('sku', $sku);
- $result[(int) $package->id] = $this->present($package);
- }
- if (count($result) !== count($ids)) {
- throw new ApiException(40401, '套餐不存在或已下架', 404);
- }
- return $result;
- }
- }
|