120 lines
4.0 KiB
PHP
120 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use App\Enums\OrderedSongStatus;
|
|
|
|
/**
|
|
* @OA\Schema(
|
|
* schema="OrderedSong",
|
|
* type="object",
|
|
* @OA\Property(property="id", type="integer", example=123),
|
|
* @OA\Property(property="room_session_id", type="integer", example=1),
|
|
* @OA\Property(property="from_by", type="string", example="remote"),
|
|
* @OA\Property(property="order_number", type="integer", example=1),
|
|
* @OA\Property(property="song_id", type="integer", example=5),
|
|
* @OA\Property(property="song_name", type="string", example="歌名"),
|
|
* @OA\Property(property="artist_name", type="string", example="歌手名稱"),
|
|
* @OA\Property(property="status", ref="#/components/schemas/OrderedSongStatus"),
|
|
* @OA\Property(property="ordered_at", type="string", format="date-time", example="2025-08-18T14:00:00Z"),
|
|
* @OA\Property(property="started_at", type="string", format="date-time", nullable=true, example="2025-08-18T14:05:00Z"),
|
|
* @OA\Property(property="finished_at", type="string", format="date-time", nullable=true, example="2025-08-18T14:10:00Z"),
|
|
* )
|
|
* @OA\Schema(
|
|
* schema="OrderedSongWithPartialSong",
|
|
* allOf={
|
|
* @OA\Schema(ref="#/components/schemas/OrderedSong"),
|
|
* @OA\Schema(
|
|
* @OA\Property(
|
|
* property="song",
|
|
* type="object",
|
|
* nullable=true,
|
|
* @OA\Property(property="id", type="integer", example=5),
|
|
* @OA\Property(property="name", type="string", example="歌名"),
|
|
* @OA\Property(property="filename", type="string", example="song123.mp4"),
|
|
* @OA\Property(property="db_change", type="integer", example=-2),
|
|
* @OA\Property(property="vocal", type="boolean", example=true),
|
|
* @OA\Property(property="situation", type="string", example="party")
|
|
* )
|
|
* )
|
|
* }
|
|
* )
|
|
*/
|
|
class OrderedSong extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
public $timestamps = false;
|
|
|
|
protected $fillable = [
|
|
'room_session_id',
|
|
'from_by',
|
|
'order_number',
|
|
'song_id',
|
|
'song_name',
|
|
'artist_name',
|
|
'status',
|
|
'ordered_at',
|
|
'started_at',
|
|
'finished_at',
|
|
|
|
];
|
|
|
|
protected $casts = [
|
|
'ordered_at' => 'datetime',
|
|
'started_at' => 'datetime',
|
|
'finished_at' => 'datetime',
|
|
'status' => \App\Enums\OrderedSongStatus::class,
|
|
];
|
|
|
|
|
|
public function session()
|
|
{
|
|
return $this->belongsTo(RoomSession::class, 'room_session_id');
|
|
}
|
|
|
|
public function song()
|
|
{
|
|
return $this->belongsTo(Song::class);
|
|
}
|
|
public function scopeWithPartialSong($query)
|
|
{
|
|
return $query->with([
|
|
'song' => function ($q) {
|
|
$q->select('id', 'name','filename','db_change','vocal','situation'); // 精簡版
|
|
}
|
|
]);
|
|
}
|
|
public function scopeForSession($query, $roomSessionId)
|
|
{
|
|
return $query->where('room_session_id', $roomSessionId);
|
|
}
|
|
|
|
public function scopePlaying($query)
|
|
{
|
|
return $query->where('status', OrderedSongStatus::Playing);
|
|
}
|
|
|
|
public function scopeNextSong($query)
|
|
{
|
|
return $query->whereIn('status', [OrderedSongStatus::InsertPlayback, OrderedSongStatus::NotPlayed])
|
|
->orderByRaw("FIELD(status, ?, ?)", [
|
|
OrderedSongStatus::InsertPlayback->value,
|
|
OrderedSongStatus::NotPlayed->value,
|
|
])
|
|
->orderByRaw("CASE WHEN status=? THEN ordered_at END DESC", [OrderedSongStatus::InsertPlayback->value])
|
|
->orderByRaw("CASE WHEN status=? THEN ordered_at END ASC", [OrderedSongStatus::NotPlayed->value]);
|
|
}
|
|
|
|
public function scopeFinished($query)
|
|
{
|
|
return $query->whereIn('status', [
|
|
OrderedSongStatus::Played,
|
|
OrderedSongStatus::Skipped,
|
|
OrderedSongStatus::NoFile,
|
|
])->orderByDesc('finished_at');
|
|
}
|
|
}
|