*/ public const SNAPSHOT_KEYS = [ 'name', 'venue_type', 'venue_types', 'unit_name', 'district', 'ticket_type', 'appointment_type', 'open_mode', 'open_time', 'reservation_notice', 'ticket_content', 'booking_method', 'visit_form', 'consultation_hours', 'address', 'contact_phone', 'lat', 'lng', 'cover_image', 'gallery_media', 'detail_html', 'live_people_count', 'sort', 'is_active', ]; protected $casts = [ 'is_active' => 'boolean', 'gallery_media' => 'array', 'venue_types' => 'array', 'lat' => 'float', 'lng' => 'float', 'sort' => 'integer', 'live_people_count' => 'integer', 'last_approved_snapshot' => 'array', ]; /** * H5 仅展示已启用且审核通过的场馆(待审核、已退回均不展示)。 */ public function scopeVisibleOnH5(Builder $query): Builder { return $query ->where('is_active', true) ->where('audit_status', self::AUDIT_APPROVED); } /** * @return array|null */ public function toH5Payload(): ?array { if ($this->audit_status !== self::AUDIT_APPROVED || ! $this->is_active) { return null; } return $this->toArray(); } /** * 场馆管理员修改「已通过」记录前,保存用于 H5 继续展示的旧数据。 * * @return array */ public function buildAuditSnapshot(): array { $out = []; foreach (self::SNAPSHOT_KEYS as $k) { $out[$k] = $this->getAttribute($k); } return $out; } protected static function booted(): void { static::saving(function (Venue $v) { $types = $v->venue_types; if (is_array($types) && count($types)) { $clean = array_values(array_filter(array_map('strval', $types), fn ($s) => $s !== '')); $v->venue_types = $clean; $v->venue_type = $clean[0] ?? null; } elseif (! empty($v->venue_type)) { $v->venue_types = [$v->venue_type]; } else { $v->venue_type = null; $v->venue_types = null; } }); } public function activities(): HasMany { return $this->hasMany(Activity::class); } public function admins(): BelongsToMany { return $this->belongsToMany(User::class, 'user_venue')->withTimestamps(); } public function reservations(): HasMany { return $this->hasMany(Reservation::class); } }