diff --git a/app/Livewire/Admin/BranchForm.php b/app/Livewire/Admin/BranchForm.php index 980b7e2..911bd2d 100644 --- a/app/Livewire/Admin/BranchForm.php +++ b/app/Livewire/Admin/BranchForm.php @@ -9,12 +9,13 @@ use Livewire\Component; use WireUi\Traits\WireUiActions; use App\Models\Branch; +use App\Models\Room; class BranchForm extends Component { use WireUiActions; - protected $listeners = ['openModal','closeModal', 'deleteArtist']; + protected $listeners = ['openModal','closeModal', 'deleteBranch']; public bool $canCreate; public bool $canEdit; @@ -27,6 +28,7 @@ class BranchForm extends Component 'name' =>'', 'external_ip' =>'', 'enable' => true, + 'roomNotes' =>'' ]; @@ -70,7 +72,29 @@ class BranchForm extends Component } } else { if ($this->canCreate) { - $branch = Branch::create($this->fields); + $branch = Branch::create([ + 'name' => $this->fields['name'], + 'external_ip' => $this->fields['external_ip'], + 'enable' => $this->fields['enable'], + ]); + + // 解析 roomNotes + $roomLines = explode("\n", trim($this->fields['roomNotes'])); + $rooms = []; + + foreach ($roomLines as $line) { + [$floor, $roomList] = explode(';', $line); + $roomNames = array_map('trim', explode(',', $roomList)); + + foreach ($roomNames as $roomName) { + $rooms[] = new Room([ + 'name' => $roomName, + ]); + } + } + + // 儲存所有 Room + $branch->rooms()->saveMany($rooms); $this->notification()->send([ 'icon' => 'success', 'title' => '成功', @@ -83,7 +107,7 @@ class BranchForm extends Component $this->dispatch('pg:eventRefresh-branch-table'); } - public function deleteArtist($id) + public function deleteBranch($id) { if ($this->canDelect) { Branch::findOrFail($id)->delete(); diff --git a/app/Livewire/Admin/BranchTable.php b/app/Livewire/Admin/BranchTable.php index e09e442..a5d2a0a 100644 --- a/app/Livewire/Admin/BranchTable.php +++ b/app/Livewire/Admin/BranchTable.php @@ -183,6 +183,11 @@ final class BranchTable extends PowerGridComponent public function actions(Branch $row): array { $actions = []; + $actions[] = Button::add('room-settings') + ->slot('包廂設定') + ->icon('solid-cog') + ->class('inline-flex items-center gap-1 px-3 py-1 rounded bg-amber-200 text-black') + ->dispatchTo('admin.room-grid', 'openModal', ['branch_id' => $row->id]); if ($this->canEdit) { $actions[] =Button::add('edit') ->slot(__('branches.edit')) diff --git a/app/Livewire/Admin/RoomDetailModal.php b/app/Livewire/Admin/RoomDetailModal.php new file mode 100644 index 0000000..a7472fc --- /dev/null +++ b/app/Livewire/Admin/RoomDetailModal.php @@ -0,0 +1,28 @@ +room = Room::find($roomId); + $this->showModal = true; + } + + public function render() + { + return view('livewire.admin.room-detail-modal'); + } +} diff --git a/app/Livewire/Admin/RoomGrid.php b/app/Livewire/Admin/RoomGrid.php new file mode 100644 index 0000000..a367958 --- /dev/null +++ b/app/Livewire/Admin/RoomGrid.php @@ -0,0 +1,35 @@ + '$refresh' + + public bool $showModal = false; + public $branchName=""; + public Collection $rooms; + + public function mount() + { + $this->rooms = new Collection(); + } + public function openModal($branch_id = null) + { + $this->branchName=Branch::where('id',$branch_id)->first()->name; + $this->rooms = Room::where('branch_id',$branch_id)->get(); + $this->showModal = true; + } + + public function render() + { + return view('livewire.admin.room-grid'); + } +} diff --git a/app/Models/Artist.php b/app/Models/Artist.php index 554c107..c0b2f7d 100644 --- a/app/Models/Artist.php +++ b/app/Models/Artist.php @@ -37,7 +37,7 @@ class Artist extends Model protected static function booted() { // 無論是 creating 或 updating,都執行這段共用的邏輯 - static::saving(function ($artist) { + static::saving(function (Artist $artist) { $simplified=ChineseNameConverter::convertToSimplified($artist->name);// 繁體轉簡體 $artist->simplified = $simplified; $artist->phonetic_abbr = ChineseNameConverter::getKTVZhuyinAbbr($simplified);// 注音符號 @@ -47,6 +47,11 @@ class Artist extends Model $firstChar = $chars[0] ?? null; $artist->strokes_abbr=( $firstChar && preg_match('/\p{Han}/u', $firstChar) ) ? ChineseStrokesConverter::getStrokes($firstChar) : 0; }); + + static::deleting(function (Artist $artist) { + // 解除與歌曲的多對多關聯 + $artist->songs()->detach(); + }); } } diff --git a/app/Models/Branch.php b/app/Models/Branch.php index de0c80e..59cc2d4 100644 --- a/app/Models/Branch.php +++ b/app/Models/Branch.php @@ -25,4 +25,10 @@ class Branch extends Model ->withPivot('counts') ->withTimestamps(); } + protected static function booted() + { + static::deleting(function (Branch $branch) { + $branch->rooms()->delete(); + }); + } } diff --git a/app/Models/Room.php b/app/Models/Room.php index 53aea8f..42ca611 100644 --- a/app/Models/Room.php +++ b/app/Models/Room.php @@ -11,11 +11,41 @@ class Room extends Model /** @use HasFactory<\Database\Factories\ArtistFactory> */ use HasFactory, LogsModelActivity; + protected $fillable = [ + 'name', + 'internal_ip', + 'port', + 'status', + 'started_at', + 'ended_at', + ]; + protected $casts = [ + 'name' => 'string', + 'internal_ip' =>'string', + 'port' => 'int', + 'status' => \App\Enums\RoomStatus::class, 'started_at' => 'datetime', 'ended_at' => 'datetime', + ]; + public function str_started_at(){ + $str ="Not Set"; + if($this->started_at !=null){ + $str = $this->started_at; + } + return $str; + } + + public function str_ended_at(){ + $str ="Not Set"; + if($this->ended_at !=null){ + $str = $this->ended_at; + } + return $str; + } + public function branch() { return $this->belongsTo(Branch::class); } diff --git a/app/Models/Song.php b/app/Models/Song.php index 83dda1e..27f85c1 100644 --- a/app/Models/Song.php +++ b/app/Models/Song.php @@ -71,7 +71,7 @@ class Song extends Model protected static function booted() { // 無論是 creating 或 updating,都執行這段共用的邏輯 - static::saving(function ($song) { + static::saving(function (Song $song) { $simplified=ChineseNameConverter::convertToSimplified($song->name);// 繁體轉簡體 $song->simplified = $simplified; $song->phonetic_abbr = ChineseNameConverter::getKTVZhuyinAbbr($simplified);// 注音符號 @@ -83,5 +83,12 @@ class Song extends Model $song->strokes_abbr=($firstChar && preg_match('/\p{Han}/u', $firstChar)) ? ChineseStrokesConverter::getStrokes($firstChar) : 0; $song->song_number = mb_strlen($song->name, 'UTF-8'); }); + static::deleting(function (Song $song) { + // Detach 關聯資料 + $song->artists()->detach(); + $song->categories()->detach(); + $song->branches()->detach(); + $song->users()->detach(); + }); } } diff --git a/database/migrations/2025_05_06_055307_create_rooms_table.php b/database/migrations/2025_05_06_055307_create_rooms_table.php index 195946e..5cbc491 100644 --- a/database/migrations/2025_05_06_055307_create_rooms_table.php +++ b/database/migrations/2025_05_06_055307_create_rooms_table.php @@ -15,10 +15,10 @@ return new class extends Migration $table->id(); $table->foreignId('branch_id')->constrained()->onDelete('cascade')->comment('關聯分店'); $table->string('name')->comment('包廂名稱'); - $table->string('internal_ip')->comment('內部 IP'); - $table->unsignedSmallInteger('port')->comment('通訊 Port'); - $table->enum('status', ['active', 'closed', 'error', 'maintenance'])->comment('狀態'); // :啟用中 / 已結束 - $table->dateTime('started_at')->comment('開始時間'); // + $table->string('internal_ip')->nullable()->comment('內部 IP'); + $table->unsignedSmallInteger('port')->nullable()->comment('通訊 Port'); + $table->enum('status', ['active', 'closed', 'error', 'maintenance'])->default('error')->comment('狀態'); // :啟用中 / 已結束 + $table->dateTime('started_at')->nullable()->comment('開始時間'); // $table->dateTime('ended_at')->nullable()->comment('結束時間'); // $table->timestamps(); }); diff --git a/resources/lang/zh-tw/enums.php b/resources/lang/zh-tw/enums.php index 64cf780..46d6eab 100644 --- a/resources/lang/zh-tw/enums.php +++ b/resources/lang/zh-tw/enums.php @@ -23,4 +23,9 @@ return [ 'user.status.Active' => '正常', 'user.status.Suspended' => '停權', 'user.status.Deleting' => '刪除中', + + 'room.status.Active' => '已占用', + 'room.status.Closed' => '可用', + 'room.status.Error' => '異常', + 'room.status.Maintenance' => '維修', ]; \ No newline at end of file diff --git a/resources/views/components/room-card.blade.php b/resources/views/components/room-card.blade.php new file mode 100644 index 0000000..8ee409e --- /dev/null +++ b/resources/views/components/room-card.blade.php @@ -0,0 +1,20 @@ +@php + use App\Enums\RoomStatus; + $statusColors = [ + RoomStatus::Active->value => 'green-600', + RoomStatus::Closed->value => 'gray-600', + RoomStatus::Error->value => 'red-600', + RoomStatus::Maintenance->value => 'yellow-600', + ]; +@endphp + +