3c38d085bd
is_verified 原本只有 Admin toggle 開關、無任何業務約束(稽核 P1-1)。 - DivingOffer 新增 visibleToPublic scope:provider_id null 或教練已驗證 - 公開 index/show 套用過濾,未驗證教練課程列表排除、詳情 404 - toggle-verified 後 flush diving_offers 快取標籤,切換立即生效 - 新增 provider-verification 規格(含已知限制註記)與 7 條可見性測試 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
84 lines
2.0 KiB
PHP
84 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class DivingOffer extends Model
|
|
{
|
|
public $timestamps = false;
|
|
|
|
protected $table = 'diving_offers';
|
|
|
|
protected $fillable = [
|
|
'provider_id',
|
|
'title',
|
|
'location',
|
|
'spot',
|
|
'rating',
|
|
'reviews',
|
|
'price',
|
|
'badges',
|
|
'description',
|
|
'tag',
|
|
'region',
|
|
'cover_image',
|
|
];
|
|
|
|
protected $casts = [
|
|
'badges' => 'array',
|
|
'rating' => 'float',
|
|
'price' => 'integer',
|
|
'reviews'=> 'integer',
|
|
];
|
|
|
|
protected static function booted(): void
|
|
{
|
|
static::deleting(function ($offer) {
|
|
Storage::disk('public')->deleteDirectory("offers/{$offer->id}");
|
|
});
|
|
}
|
|
|
|
public function getCoverImageUrlAttribute(): ?string
|
|
{
|
|
return $this->cover_image
|
|
? Storage::disk('public')->url($this->cover_image)
|
|
: null;
|
|
}
|
|
|
|
public function provider(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'provider_id');
|
|
}
|
|
|
|
/**
|
|
* 公開端點可見性:未驗證教練的課程不對外曝光。
|
|
* provider_id 為 null 的課程(平台自有資料)不受此限制。
|
|
*/
|
|
public function scopeVisibleToPublic(Builder $query): Builder
|
|
{
|
|
return $query->where(function (Builder $visible) {
|
|
$visible->whereNull('provider_id')
|
|
->orWhereHas('provider.providerProfile', fn (Builder $profile) => $profile->where('is_verified', true));
|
|
});
|
|
}
|
|
|
|
public function schedules()
|
|
{
|
|
return $this->hasMany(CourseSchedule::class, 'diving_offer_id');
|
|
}
|
|
|
|
public function courseImages()
|
|
{
|
|
return $this->hasMany(CourseImage::class)->orderBy('sort_order');
|
|
}
|
|
|
|
public function reviews()
|
|
{
|
|
return $this->hasMany(Review::class);
|
|
}
|
|
}
|