getTable()) && $this->types->ready(); } catch (QueryException) { return false; } } /** * @param array $filters * @return array{ready:bool, rows:Collection, summary:array, options:array} */ public function pageData(array $filters): array { if (! $this->ready()) { return [ 'ready' => false, 'rows' => collect(), 'summary' => ['total' => 0, 'active' => 0, 'inactive' => 0, 'couriers' => 0], 'options' => $this->emptyOptions(), ]; } try { $all = CourierSurchargeQuote::query() ->orderByDesc('effective_at') ->orderByDesc('id') ->get(); } catch (QueryException) { return [ 'ready' => false, 'rows' => collect(), 'summary' => ['total' => 0, 'active' => 0, 'inactive' => 0, 'couriers' => 0], 'options' => $this->emptyOptions(), ]; } $filtered = $all->filter(function (CourierSurchargeQuote $quote) use ($filters): bool { foreach (['courier', 'scope', 'reconciler', 'mode'] as $key) { if (($filters[$key] ?? '') !== '' && (string) $quote->{$key} !== $filters[$key]) { return false; } } if (($filters['type'] ?? '') !== '' && ! in_array($filters['type'], (array) $quote->types, true)) { return false; } if (($filters['status'] ?? '') !== '' && $quote->statusLabel() !== $filters['status']) { return false; } $keyword = trim((string) ($filters['keyword'] ?? '')); if ($keyword !== '') { $searchable = implode('|', [ $quote->courier, $quote->scope, $quote->reconciler, $quote->typeLabel(), $quote->mode, $quote->standard, $quote->condition, (string) $quote->remark, ]); if (! str_contains($searchable, $keyword)) { return false; } } return true; })->values(); $typeRecords = $this->types->all(); $activeTypeNames = $typeRecords ->where('status', CourierSurchargeType::STATUS_ACTIVE) ->pluck('name') ->values(); return [ 'ready' => true, 'rows' => $filtered->map(fn (CourierSurchargeQuote $quote): array => $this->present($quote)), 'summary' => [ 'total' => $filtered->count(), 'active' => $filtered->where('status', CourierSurchargeQuote::STATUS_ACTIVE)->count(), 'inactive' => $filtered->where('status', CourierSurchargeQuote::STATUS_INACTIVE)->count(), 'couriers' => $filtered->pluck('courier')->unique()->count(), ], 'options' => [ 'couriers' => $all->pluck('courier')->filter()->unique()->sort()->values(), 'types' => $activeTypeNames, 'filter_types' => $typeRecords->pluck('name')->values(), 'type_records' => $typeRecords->map(fn ($type): array => [ 'id' => $type->id, 'name' => $type->name, 'status' => $type->status, 'status_label' => $type->statusLabel(), ])->values(), 'modes' => collect(self::MODES), 'scopes' => self::SCOPES, 'reconcilers' => $all->pluck('reconciler')->filter()->unique()->sort()->values(), 'statuses' => ['已启用', '已停用'], ], ]; } /** @return list */ public function validTypeNames(): array { return $this->types->validNames(); } /** @return list */ public function activeTypeNames(): array { return $this->types->activeNames(); } /** @param array $data */ public function create(array $data, int $userId): CourierSurchargeQuote { return CourierSurchargeQuote::query()->create($this->attributes($data, $userId) + [ 'status' => CourierSurchargeQuote::STATUS_ACTIVE, 'created_by' => $userId, ]); } /** @param array $data */ public function update(CourierSurchargeQuote $quote, array $data, int $userId): CourierSurchargeQuote { $quote->update($this->attributes($data, $userId)); return $quote->fresh(); } public function setStatus(CourierSurchargeQuote $quote, string $status, int $userId): CourierSurchargeQuote { abort_unless(in_array($status, [CourierSurchargeQuote::STATUS_ACTIVE, CourierSurchargeQuote::STATUS_INACTIVE], true), 422, '报价规则状态不合法。'); $quote->forceFill(['status' => $status, 'updated_by' => $userId])->save(); return $quote->fresh(); } /** @param array $data */ private function attributes(array $data, int $userId): array { return [ 'company_id' => company_id(), 'courier' => trim((string) $data['courier']), 'scope' => trim((string) $data['scope']), 'reconciler' => trim((string) $data['reconciler']), 'types' => array_values(array_unique(array_map('strval', $data['types']))), 'mode' => trim((string) $data['mode']), 'standard' => trim((string) $data['standard']), 'condition' => trim((string) $data['condition']), 'effective_at' => $data['effective_at'], 'remark' => trim((string) ($data['remark'] ?? '')) ?: null, 'updated_by' => $userId, ]; } /** @return array */ private function present(CourierSurchargeQuote $quote): array { return [ 'id' => 'SUR-' . str_pad((string) $quote->id, 3, '0', STR_PAD_LEFT), 'db_id' => $quote->id, 'courier' => $quote->courier, 'scope' => $quote->scope, 'reconciler' => $quote->reconciler, 'types' => array_values((array) $quote->types), 'type' => $quote->typeLabel(), 'mode' => $quote->mode, 'standard' => $quote->standard, 'condition' => $quote->condition, 'effective_at' => optional($quote->effective_at)->format('Y-m-d'), 'status_code' => $quote->status, 'status' => $quote->statusLabel(), 'remark' => $quote->remark, ]; } /** @return array */ private function emptyOptions(): array { return [ 'couriers' => collect(), 'types' => collect(self::TYPES), 'filter_types' => collect(self::TYPES), 'type_records' => collect(), 'modes' => collect(self::MODES), 'scopes' => self::SCOPES, 'reconcilers' => collect(), 'statuses' => ['已启用', '已停用'], ]; } }