|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
|
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
|
|
|
|
|
|
class Venue extends Model
|
|
|
|
|
{
|
|
|
|
|
use HasFactory;
|
|
|
|
|
|
|
|
|
|
protected $fillable = [
|
|
|
|
|
'name',
|
|
|
|
|
'venue_type',
|
|
|
|
|
'venue_types',
|
|
|
|
|
'unit_name',
|
|
|
|
|
'district',
|
|
|
|
|
'ticket_type',
|
|
|
|
|
'appointment_type',
|
|
|
|
|
'open_mode',
|
|
|
|
|
'open_time',
|
|
|
|
|
'reservation_notice',
|
|
|
|
|
'study_courses',
|
|
|
|
|
'address',
|
|
|
|
|
'contact_phone',
|
|
|
|
|
'lat',
|
|
|
|
|
'lng',
|
|
|
|
|
'cover_image',
|
|
|
|
|
'gallery_media',
|
|
|
|
|
'detail_html',
|
|
|
|
|
'live_people_count',
|
|
|
|
|
'sort',
|
|
|
|
|
'is_active',
|
|
|
|
|
'audit_status',
|
|
|
|
|
'audit_remark',
|
|
|
|
|
'last_approved_snapshot',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
public const AUDIT_APPROVED = 'approved';
|
|
|
|
|
|
|
|
|
|
public const AUDIT_PENDING = 'pending';
|
|
|
|
|
|
|
|
|
|
public const AUDIT_REJECTED = 'rejected';
|
|
|
|
|
|
|
|
|
|
/** @var list<string> */
|
|
|
|
|
public const SNAPSHOT_KEYS = [
|
|
|
|
|
'name', 'venue_type', 'venue_types', 'unit_name', 'district', 'ticket_type',
|
|
|
|
|
'appointment_type', 'open_mode', 'open_time', 'reservation_notice', 'study_courses',
|
|
|
|
|
'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<string, mixed>|null
|
|
|
|
|
*/
|
|
|
|
|
public function toH5Payload(): ?array
|
|
|
|
|
{
|
|
|
|
|
if ($this->audit_status !== self::AUDIT_APPROVED || ! $this->is_active) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->toArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 场馆管理员修改「已通过」记录前,保存用于 H5 继续展示的旧数据。
|
|
|
|
|
*
|
|
|
|
|
* @return array<string, mixed>
|
|
|
|
|
*/
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|