From 751c65bccf4c2831e72517499d21fee628c8e8fa Mon Sep 17 00:00:00 2001 From: "allen.yan" Date: Wed, 11 Jun 2025 17:37:31 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AA=BF=E6=95=B4=20=E5=8C=85=E5=BB=82?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E9=A0=81=20=E6=96=B0=E5=A2=9E=20=E5=8C=85?= =?UTF-8?q?=E5=BB=82=E8=A8=AD=E5=AE=9A=E9=A0=81=20=E5=88=AA=E9=99=A4=20?= =?UTF-8?q?=E5=88=86=E5=BA=97=E9=A0=81=E9=9D=A2=2020250611?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Enums/RoomType.php | 2 +- app/Livewire/Forms/BranchTable.php | 89 -------- .../Modals}/RoomDetailModal.php | 4 +- app/Livewire/Forms/RoomForm.php | 125 +++++++++++ .../RoomGrid.php => Forms/RoomGridForm.php} | 8 +- app/Livewire/Forms/RoomTable.php | 202 ++++++++++++++---- app/Models/Room.php | 13 +- resources/lang/zh-tw/enums.php | 1 + resources/lang/zh-tw/room.php | 7 - resources/lang/zh-tw/rooms.php | 29 +++ .../views/components/room-card-svr.blade.php | 2 +- .../views/components/room-card.blade.php | 4 +- .../views/livewire/admin/room-grids.blade.php | 2 +- .../views/livewire/admin/rooms.blade.php | 3 + .../modals}/room-detail-modal.blade.php | 0 .../views/livewire/forms/room-form.blade.php | 21 ++ .../room-grid-form.blade.php} | 2 +- .../livewire/header/admin/branch.blade.php | 2 - .../livewire/header/admin/room.blade.php | 13 +- 19 files changed, 365 insertions(+), 164 deletions(-) delete mode 100644 app/Livewire/Forms/BranchTable.php rename app/Livewire/{Admin => Forms/Modals}/RoomDetailModal.php (96%) create mode 100644 app/Livewire/Forms/RoomForm.php rename app/Livewire/{Admin/RoomGrid.php => Forms/RoomGridForm.php} (86%) delete mode 100644 resources/lang/zh-tw/room.php create mode 100644 resources/lang/zh-tw/rooms.php rename resources/views/livewire/{admin => forms/modals}/room-detail-modal.blade.php (100%) create mode 100644 resources/views/livewire/forms/room-form.blade.php rename resources/views/livewire/{admin/room-grid.blade.php => forms/room-grid-form.blade.php} (97%) delete mode 100644 resources/views/livewire/header/admin/branch.blade.php diff --git a/app/Enums/RoomType.php b/app/Enums/RoomType.php index e311fea..9e54578 100644 --- a/app/Enums/RoomType.php +++ b/app/Enums/RoomType.php @@ -23,7 +23,7 @@ enum RoomType: string { public function labels(): string { return match($this) { - self::Unset => __('enums.room.status.Unset'), + self::Unset => __('enums.Unset'), self::PC => "PC", self::SVR => "SVR", }; diff --git a/app/Livewire/Forms/BranchTable.php b/app/Livewire/Forms/BranchTable.php deleted file mode 100644 index a3766f5..0000000 --- a/app/Livewire/Forms/BranchTable.php +++ /dev/null @@ -1,89 +0,0 @@ - 'outside']); - } - - public function setUp(): array - { - $actions = []; - $header = PowerGrid::header() - ->withoutLoading() - ->showToggleColumns(); - $header->includeViewOnTop('livewire.header.admin.branch') ; - - $actions[]=$header; - $actions[]=PowerGrid::footer()->showPerPage()->showRecordCount(); - return $actions; - } - - public function datasource(): Builder - { - return Branch::query(); - } - - public function relationSearch(): array - { - return []; - } - - public function fields(): PowerGridFields - { - return PowerGrid::fields() - ->add('id') - ->add('name') - ->add('external_ip') - ->add('enable') - ->add('created_at_formatted', fn (Branch $model) => Carbon::parse($model->created_at)->format('d/m/Y H:i:s')); - } - - public function columns(): array - { - $column=[]; - $column[]=Column::make(__('branches.no'), 'id'); - $column[]=Column::make(__('branches.name'), 'name')->sortable()->searchable(); - $column[]=Column::make(__('branches.external_ip'), 'external_ip')->sortable()->searchable(); - $column[]=Column::make(__('branches.enable'), 'enable'); - $column[]=Column::make('Created at', 'created_at_formatted', 'created_at')->sortable()->hidden(true, false); - return $column; - } - - public function filters(): array - { - return [ - Filter::inputText('name')->placeholder(__('branches.name')), - Filter::inputText('external_ip')->placeholder(__('branches.external_ip')), - Filter::boolean('enable')->label('✅', '❌'), - Filter::datetimepicker('created_at'), - ]; - } -} diff --git a/app/Livewire/Admin/RoomDetailModal.php b/app/Livewire/Forms/Modals/RoomDetailModal.php similarity index 96% rename from app/Livewire/Admin/RoomDetailModal.php rename to app/Livewire/Forms/Modals/RoomDetailModal.php index 91e13ce..566e161 100644 --- a/app/Livewire/Admin/RoomDetailModal.php +++ b/app/Livewire/Forms/Modals/RoomDetailModal.php @@ -1,6 +1,6 @@ '', + 'type' =>'', + 'name' =>'' + ]; + + + public function mount() + { + $this->typeOptions = collect(RoomType::cases())->map(fn ($type) => [ + 'name' => $type->labels(), + 'value' => $type->value, + ])->toArray(); + $this->canCreate = Auth::user()?->can('room-edit') ?? false; + $this->canEdit = Auth::user()?->can('room-edit') ?? false; + $this->canDelect = Auth::user()?->can('room-delete') ?? false; + } + + public function openModal($id = null) + { + $this->resetFields(); + + if ($id) { + $room = Room::findOrFail($id); + $this->roomId = $room->id; + $this->fields = $room->only(array_keys($this->fields)); + } + + $this->showModal = true; + } + + public function closeModal() + { + $this->resetFields(); + $this->showModal = false; + } + + public function save() + { + $description ="無權修改"; + if ($this->roomId) { + if ($this->canEdit) { + $room = Room::findOrFail($this->roomId); + $room->update($this->fields); + $description='分店已更新'; + } + } else { + if ($this->canCreate) { + $room = Room::create([ + 'floor' => $this->fields['floor'], + 'type' => $this->fields['type'], + 'name' => $this->fields['name'], + ]); + $description='分店已新增'; + } + } + $this->notification()->send([ + 'icon' => 'success', + 'title' => '成功', + 'description' => $description, + ]); + $this->resetFields(); + $this->showModal = false; + $this->dispatch('pg:eventRefresh-room-table'); + } + + public function deleteBranch($id) + { + if ($this->canDelect) { + Room::findOrFail($id)->delete(); + $this->notification()->send([ + 'icon' => 'success', + 'title' => '成功', + 'description' => '分店已刪除', + ]); + + $this->dispatch('pg:eventRefresh-room-table'); + } + } + + public function resetFields() + { + foreach ($this->fields as $key => $value) { + if ($key == 'enable') { + $this->fields[$key] = true; + } else { + $this->fields[$key] = ''; + } + } + $this->branchId = null; + } + + public function render() + { + return view('livewire.forms.room-form'); + } +} diff --git a/app/Livewire/Admin/RoomGrid.php b/app/Livewire/Forms/RoomGridForm.php similarity index 86% rename from app/Livewire/Admin/RoomGrid.php rename to app/Livewire/Forms/RoomGridForm.php index 93331d8..03c87d6 100644 --- a/app/Livewire/Admin/RoomGrid.php +++ b/app/Livewire/Forms/RoomGridForm.php @@ -1,6 +1,6 @@ id)->get(); $floors = $rooms->pluck('floor')->unique()->sort()->values()->toArray(); } - - return view('livewire.admin.room-grid', [ + + return view('livewire.forms.room-grid-form', [ 'rooms' => $rooms, 'floors' => $floors, ]); diff --git a/app/Livewire/Forms/RoomTable.php b/app/Livewire/Forms/RoomTable.php index d831565..6a9c82a 100644 --- a/app/Livewire/Forms/RoomTable.php +++ b/app/Livewire/Forms/RoomTable.php @@ -3,7 +3,10 @@ namespace App\Livewire\Forms; use App\Models\Room; -use Illuminate\Support\Carbon; +use App\Enums\RoomType; + +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Blade; use Illuminate\Database\Eloquent\Builder; use PowerComponents\LivewirePowerGrid\Button; use PowerComponents\LivewirePowerGrid\Column; @@ -11,29 +14,63 @@ use PowerComponents\LivewirePowerGrid\Facades\Filter; use PowerComponents\LivewirePowerGrid\Facades\PowerGrid; use PowerComponents\LivewirePowerGrid\PowerGridFields; use PowerComponents\LivewirePowerGrid\PowerGridComponent; +use PowerComponents\LivewirePowerGrid\Traits\WithExport; +use PowerComponents\LivewirePowerGrid\Components\SetUp\Exportable; +use Livewire\Attributes\On; +use WireUi\Traits\WireUiActions; final class RoomTable extends PowerGridComponent { + use WithExport, WireUiActions; public string $tableName = 'room-table'; + public bool $canCreate; + public bool $canEdit; + public bool $canDownload; + public bool $canDelect; public bool $showFilters = false; public function boot(): void { config(['livewire-powergrid.filter' => 'outside']); + //權限設定 + $this->canCreate = Auth::user()?->can('room-edit') ?? false; + $this->canEdit = Auth::user()?->can('room-edit') ?? false; + $this->canDownload=Auth::user()?->can('room-delete') ?? false; + $this->canDelect = Auth::user()?->can('room-delete') ?? false; } public function setUp(): array { + if($this->canDownload || $this->canDelect){ + $this->showCheckBox(); + } $actions = []; + if($this->canDownload){ + $actions[]=PowerGrid::exportable(fileName: $this->tableName.'-file') + ->type(Exportable::TYPE_XLS, Exportable::TYPE_CSV); + } $header = PowerGrid::header() ->withoutLoading() ->showToggleColumns(); - $header->includeViewOnTop('livewire.header.admin.room'); - + if($this->canCreate){ + $header->includeViewOnTop('livewire.header.admin.room'); + } $actions[]=$header; $actions[]=PowerGrid::footer()->showPerPage()->showRecordCount(); return $actions; } + public function header(): array + { + $actions = []; + if ($this->canDelect) { + $actions[]=Button::add('bulk-delete') + ->slot('Bulk delete ()') + ->icon('solid-trash',['id' => 'my-custom-icon-id', 'class' => 'font-bold']) + ->class('inline-flex items-center gap-1 px-3 py-1 rounded ') + ->dispatch('bulkDelete.' . $this->tableName, []); + } + return $actions; + } public function datasource(): Builder { @@ -50,50 +87,58 @@ final class RoomTable extends PowerGridComponent return PowerGrid::fields() ->add('id') ->add('floor') - ->add('room_name',function (Room $model){ - return $model->type->labelPowergridFilter().$model->name; + ->add('type_str',function(Room $model){ + if ($this->canEdit) { + return Blade::render( + '', + [ + 'options' => RoomType::options(), + 'modelId' => intval($model->id), + 'fieldName'=>'type', + 'selected' => $model->type->value + ] + ); + } + return $model->type->labelPowergridFilter(); }) - ->add('is_online') + ->add('name') + ->add('internal_ip') + ->add('is_online', fn ($model) => $model->is_online===true ? '在線' : '斷線') ->add('status_str',function (Room $model){ return $model->status->labelPowergridFilter(); }) - ->add('started_at_formatted', fn (Room $model) => Carbon::parse($model->started_at)->format('Y/m/d H:i:s')) - ->add('ended_at_formatted', fn (Room $model) => Carbon::parse($model->ended_at)->format('Y/m/d H:i:s')) + ->add('str_started_at', fn (Room $model) => $model->str_started_at()) + ->add('str_ended_at', fn (Room $model) => $model->str_ended_at()) ->add('created_at'); } public function columns(): array { - return [ - Column::make('Id', 'id'), - Column::make('Floor', 'floor') - ->sortable() - ->searchable(), + $column=[]; + $column[]=Column::make(__('rooms.id'), 'id'); + $column[]=Column::make(__('rooms.floor'), 'floor')->sortable()->searchable()->editOnClick( + hasPermission: $this->canEdit, + dataField: 'floor', + fallback: 'N/A', + saveOnMouseOut: true + ); + $column[]=Column::make(__('rooms.type'), 'type_str','room.type')->sortable()->searchable(); + $column[]=Column::make(__('rooms.name'), 'name')->sortable()->searchable() + ->editOnClick( + hasPermission: $this->canEdit, + dataField: 'name', + fallback: 'N/A', + saveOnMouseOut: true + ); + $column[]=Column::make(__('rooms.isOnline'), 'internal_ip'); + $column[]=Column::make(__('rooms.isOnline'), 'is_online'); + $column[]=Column::make(__('rooms.status'), 'status_str','room.status')->sortable()->searchable()->hidden(true, false); + $column[]=Column::make(__('rooms.started_at'), 'str_started_at', 'started_at')->sortable()->hidden(true, false); + $column[]=Column::make(__('rooms.ended_at'), 'str_ended_at', 'ended_at')->sortable()->hidden(true, false); + $column[]=Column::make(__('rooms.created_at'), 'created_at')->sortable()->searchable(); + $column[]=Column::action('Action'); - Column::make('Name', 'room_name') - ->sortable() - ->searchable(), - - Column::make('Is online', 'is_online') - ->sortable() - ->searchable(), - - Column::make('Status', 'status_str') - ->sortable() - ->searchable(), - - Column::make('Started at', 'started_at_formatted', 'started_at') - ->sortable(), - - Column::make('Ended at', 'ended_at_formatted', 'ended_at') - ->sortable(), - - Column::make('Created at', 'created_at') - ->sortable() - ->searchable(), - - Column::action('Action') - ]; + return $column; } public function filters(): array @@ -101,24 +146,87 @@ final class RoomTable extends PowerGridComponent return [ Filter::datetimepicker('started_at'), Filter::datetimepicker('ended_at'), + Filter::boolean('is_online') + ->label('在線', '斷線'), ]; } - #[\Livewire\Attributes\On('edit')] - public function edit($rowId): void + #[On('bulkDelete.{tableName}')] + public function bulkDelete(): void { - $this->js('alert('.$rowId.')'); + if ($this->canDelect) { + $this->js('alert(window.pgBulkActions.get(\'' . $this->tableName . '\'))'); + if($this->checkboxValues){ + Branch::destroy($this->checkboxValues); + $this->js('window.pgBulkActions.clearAll()'); // clear the count on the interface. + } + } + } + #[On('categoryChanged')] + public function categoryChanged($value,$fieldName, $modelId): void + { + if ($fieldName == 'type' && $this->canEdit) { + $this->noUpdated($modelId,$fieldName,$value); + } + } + #[On('onUpdatedEditable')] + public function onUpdatedEditable($id, $field, $value): void + { + if($field === 'floor' && $this->canEdit){ + if (!is_numeric($value)) { + $this->notification()->send([ + 'icon' => 'error', + 'title' => '無效輸入', + 'description' => '樓層必須是數字', + ]); + return; + } + $this->noUpdated($id,$field,$value); + }else if ($field === 'name' && $this->canEdit) { + $this->noUpdated($id,$field,$value); + } + } + + private function noUpdated($id,$field,$value){ + dd($id,$field,$value); + $room = Room::find($id); + if ($room) { + $room->{$field} = $value; + $room->save(); // 明確觸發 saving + } + $this->notification()->send([ + 'icon' => 'success', + 'title' => $id.'.'.__('room.'.$field).':'.$value, + 'description' => '已經寫入', + ]); } public function actions(Room $row): array { - return [ - Button::add('edit') - ->slot('Edit: '.$row->id) - ->id() - ->class('pg-btn-white dark:ring-pg-primary-600 dark:border-pg-primary-600 dark:hover:bg-pg-primary-700 dark:ring-offset-pg-primary-800 dark:text-pg-primary-300 dark:bg-pg-primary-700') - ->dispatch('edit', ['rowId' => $row->id]) - ]; + $actions = []; + + if ($this->canEdit) { + $actions[] =Button::add('edit') + ->slot(__('rooms.edit')) + ->icon('solid-pencil-square') + ->class('inline-flex items-center gap-1 px-3 py-1 rounded ') + ->dispatchTo('forms.room-form', 'openModal', ['id' => $row->id]); + } + if($this->canDelect){ + $actions[] =Button::add('delete') + ->slot(__('rooms.delete')) + ->icon('solid-trash') + ->class('inline-flex items-center gap-1 px-3 py-1 rounded ') + ->dispatchTo('forms.room-form', 'deleteRoom', ['id' => $row->id]); + } + if ($row->type->value === 'pc') { + $actions[] = Button::add('room-settings') + ->slot('包廂設定') + ->icon('solid-cog') + ->class('inline-flex items-center gap-1 px-3 py-1 rounded ') + ->dispatchTo('forms.modals.room-detail-modal', 'openModal', ['roomId' => $row->id]); + } + return $actions; } /* diff --git a/app/Models/Room.php b/app/Models/Room.php index e36006b..ac1cab5 100644 --- a/app/Models/Room.php +++ b/app/Models/Room.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Support\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use App\Traits\LogsModelActivity; @@ -38,10 +39,10 @@ class Room extends Model 'ended_at', ]; - protected $hidden = [ - 'internal_ip', - 'port', - ]; + //protected $hidden = [ + // 'internal_ip', + // 'port', + //]; protected $casts = [ 'floor' => 'int', @@ -59,7 +60,7 @@ class Room extends Model public function str_started_at(){ $str ="Not Set"; if($this->started_at !=null){ - $str = $this->started_at; + Carbon::parse($this->started_at)->format('Y/m/d H:i:s'); } return $str; } @@ -67,7 +68,7 @@ class Room extends Model public function str_ended_at(){ $str ="Not Set"; if($this->ended_at !=null){ - $str = $this->ended_at; + Carbon::parse($this->ended_at)->format('Y/m/d H:i:s'); } return $str; } diff --git a/resources/lang/zh-tw/enums.php b/resources/lang/zh-tw/enums.php index 4d0af2f..c3ea150 100644 --- a/resources/lang/zh-tw/enums.php +++ b/resources/lang/zh-tw/enums.php @@ -1,6 +1,7 @@ '未定義', 'user.gender.Male' =>'男', 'user.gender.Female' =>'女', 'user.gender.Other' =>'其他', diff --git a/resources/lang/zh-tw/room.php b/resources/lang/zh-tw/room.php deleted file mode 100644 index 6e766fb..0000000 --- a/resources/lang/zh-tw/room.php +++ /dev/null @@ -1,7 +0,0 @@ - '正常', - 'error' => '維修', - -]; \ No newline at end of file diff --git a/resources/lang/zh-tw/rooms.php b/resources/lang/zh-tw/rooms.php new file mode 100644 index 0000000..154c4f2 --- /dev/null +++ b/resources/lang/zh-tw/rooms.php @@ -0,0 +1,29 @@ + '包廂列表', + 'CreateNew' => '新增包廂', + 'EditRoom' => '編輯包廂', + 'create' => '新增', + 'edit' => '編輯', + 'delete' => '刪除', + + 'id' =>'編號', + 'floor' =>'樓層', + 'type' =>'型別', + 'name' =>'名稱', + 'isOnline' =>'在線', + 'status' =>'狀態', + 'started_at' =>'開始於', + 'ended_at' =>'結束於', + 'created_at' =>'建立於', + 'active' => '正常', + 'error' => '維修', + + 'select_type' =>'選擇型別', + + 'actions' => '操作', + 'view' => '查看', + 'submit' => '提交', + 'cancel' => '取消', +]; \ No newline at end of file diff --git a/resources/views/components/room-card-svr.blade.php b/resources/views/components/room-card-svr.blade.php index 7e3bcb3..9fd91bf 100644 --- a/resources/views/components/room-card-svr.blade.php +++ b/resources/views/components/room-card-svr.blade.php @@ -8,6 +8,6 @@
- {{ $room->is_online ? __('room.active') : __('room.error') }} + {{ $room->is_online ? __('rooms.active') : __('rooms.error') }}
\ No newline at end of file diff --git a/resources/views/components/room-card.blade.php b/resources/views/components/room-card.blade.php index b520763..7e9ac81 100644 --- a/resources/views/components/room-card.blade.php +++ b/resources/views/components/room-card.blade.php @@ -8,7 +8,7 @@ @endphp
+ wire:click="$dispatchTo('forms.modals.room-detail-modal','openModal', { roomId: {{ $room->id }} })"> {{-- 房間名稱 + 線上狀態圓點 --}}
- {{ __('room.error') }} + {{ __('rooms.error') }}
@else
diff --git a/resources/views/livewire/admin/room-grids.blade.php b/resources/views/livewire/admin/room-grids.blade.php index e4891df..2b28e8a 100644 --- a/resources/views/livewire/admin/room-grids.blade.php +++ b/resources/views/livewire/admin/room-grids.blade.php @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/resources/views/livewire/admin/rooms.blade.php b/resources/views/livewire/admin/rooms.blade.php index 0521d58..547420c 100644 --- a/resources/views/livewire/admin/rooms.blade.php +++ b/resources/views/livewire/admin/rooms.blade.php @@ -1,4 +1,7 @@ + + + \ No newline at end of file diff --git a/resources/views/livewire/admin/room-detail-modal.blade.php b/resources/views/livewire/forms/modals/room-detail-modal.blade.php similarity index 100% rename from resources/views/livewire/admin/room-detail-modal.blade.php rename to resources/views/livewire/forms/modals/room-detail-modal.blade.php diff --git a/resources/views/livewire/forms/room-form.blade.php b/resources/views/livewire/forms/room-form.blade.php new file mode 100644 index 0000000..f2579a6 --- /dev/null +++ b/resources/views/livewire/forms/room-form.blade.php @@ -0,0 +1,21 @@ + +
+ + + +
+ +
+ + +
+
+
+ \ No newline at end of file diff --git a/resources/views/livewire/admin/room-grid.blade.php b/resources/views/livewire/forms/room-grid-form.blade.php similarity index 97% rename from resources/views/livewire/admin/room-grid.blade.php rename to resources/views/livewire/forms/room-grid-form.blade.php index a218376..5dd8f0b 100644 --- a/resources/views/livewire/admin/room-grid.blade.php +++ b/resources/views/livewire/forms/room-grid-form.blade.php @@ -46,5 +46,5 @@
- + \ No newline at end of file diff --git a/resources/views/livewire/header/admin/branch.blade.php b/resources/views/livewire/header/admin/branch.blade.php deleted file mode 100644 index 6d81f4b..0000000 --- a/resources/views/livewire/header/admin/branch.blade.php +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/resources/views/livewire/header/admin/room.blade.php b/resources/views/livewire/header/admin/room.blade.php index 415799a..5d81cf6 100644 --- a/resources/views/livewire/header/admin/room.blade.php +++ b/resources/views/livewire/header/admin/room.blade.php @@ -1,2 +1,13 @@ - +@php +use App\Models\Branch; +$branch= Branch::findOrFail(1); +@endphp + + + \ No newline at end of file