20250803
Branch 加入 同步畫面 修面包廂 分頁問題 調整 is_online 改成圖示顯示
This commit is contained in:
parent
948d21667b
commit
3228031528
68
app/Jobs/ExportSqliteTextAdJob.php
Normal file
68
app/Jobs/ExportSqliteTextAdJob.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Models\TextAd;
|
||||||
|
use App\Services\SqliteExportService;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ExportSqliteTextAdJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
public $timeout = 600;
|
||||||
|
|
||||||
|
protected ?int $branchId;
|
||||||
|
|
||||||
|
public function __construct(?int $branchId = null)
|
||||||
|
{
|
||||||
|
$this->branchId = $branchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$sqlitePath = storage_path('app/database/tempTextAd.sqlite');
|
||||||
|
|
||||||
|
if (!file_exists(dirname($sqlitePath))) {
|
||||||
|
mkdir(dirname($sqlitePath), 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($sqlitePath)) {
|
||||||
|
file_put_contents($sqlitePath, '');
|
||||||
|
}
|
||||||
|
$connectionName = 'tempsqlite_' . md5($sqlitePath . microtime());
|
||||||
|
config(["database.connections.{$connectionName}" => [
|
||||||
|
'driver' => 'sqlite',
|
||||||
|
'database' => $sqlitePath,
|
||||||
|
'prefix' => '',
|
||||||
|
]]);
|
||||||
|
|
||||||
|
$exporter = new SqliteExportService($connectionName);
|
||||||
|
$exporter->exportMultiple([
|
||||||
|
'text_ads' => [
|
||||||
|
'query' => fn () => DB::table('text_ads'),
|
||||||
|
'tableSchema' => function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('content')->comment('廣告內容');
|
||||||
|
$table->enum('color', ['black','white', 'red', 'green','blue'])->default('black')->comment('顯示顏色');
|
||||||
|
$table->integer('duration')->default(1)->comment('播放間隔時間(分鐘)');
|
||||||
|
$table->boolean('is_active')->default(true); // 啟用狀態
|
||||||
|
$table->timestamps();
|
||||||
|
},
|
||||||
|
'transformer' => fn ($row) => [
|
||||||
|
'content' => $row->content,
|
||||||
|
'color' => $row->color,
|
||||||
|
'duration' => $row->duration,
|
||||||
|
'is_active' => $row->is_active,
|
||||||
|
'created_at' => $row->created_at,
|
||||||
|
'updated_at' => $row->updated_at,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
SendSqliteFileJob::dispatch($sqlitePath, $this->branchId);
|
||||||
|
}
|
||||||
|
}
|
76
app/Livewire/Modals/BranchSyncModal.php
Normal file
76
app/Livewire/Modals/BranchSyncModal.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Modals;
|
||||||
|
|
||||||
|
use App\Models\Branch;
|
||||||
|
use Livewire\Component;
|
||||||
|
use App\Jobs\ExportSqliteBranchJob;
|
||||||
|
use App\Jobs\ExportSqliteSongJob;
|
||||||
|
use App\Jobs\ExportSqliteFavoriteJob;
|
||||||
|
use App\Jobs\ExportSqliteTextAdJob;
|
||||||
|
use App\Jobs\ExportSqliteUserJob;
|
||||||
|
use WireUi\Traits\WireUiActions;
|
||||||
|
|
||||||
|
class BranchSyncModal extends Component
|
||||||
|
{
|
||||||
|
use WireUiActions;
|
||||||
|
|
||||||
|
protected $listeners = [
|
||||||
|
'openModal','closeModal'
|
||||||
|
];
|
||||||
|
|
||||||
|
public int $branch_id;
|
||||||
|
public string $branch_name;
|
||||||
|
public bool $syncBranch = false;
|
||||||
|
public bool $syncSong = false;
|
||||||
|
public bool $syncFavorite = false;
|
||||||
|
public bool $syncTextAds = false;
|
||||||
|
public bool $syncUser = false;
|
||||||
|
|
||||||
|
public bool $showModal = false;
|
||||||
|
|
||||||
|
public function openModal($branch_id)
|
||||||
|
{
|
||||||
|
$this->branch_id = $branch_id;
|
||||||
|
$this->branch_name = Branch::find($branch_id)->name;
|
||||||
|
$this->reset('syncBranch', 'syncSong', 'syncFavorite', 'syncTextAds', 'syncUser');
|
||||||
|
$this->showModal = true;
|
||||||
|
}
|
||||||
|
public function closeModal()
|
||||||
|
{
|
||||||
|
$this->showModal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
if ($this->syncBranch) {
|
||||||
|
ExportSqliteBranchJob::dispatch($this->branch_id);
|
||||||
|
}
|
||||||
|
if ($this->syncSong) {
|
||||||
|
ExportSqliteSongJob::dispatch($this->branch_id);
|
||||||
|
}
|
||||||
|
if ($this->syncFavorite) {
|
||||||
|
ExportSqliteFavoriteJob::dispatch($this->branch_id);
|
||||||
|
}
|
||||||
|
if($this->syncTextAds){
|
||||||
|
ExportSqliteTextAdJob::dispatch($this->branch_id);
|
||||||
|
}
|
||||||
|
if ($this->syncUser) {
|
||||||
|
ExportSqliteUserJob::dispatch(true, $this->branch_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notification()->send([
|
||||||
|
'icon' => 'success',
|
||||||
|
'title' => '同步任務',
|
||||||
|
'description' => '已加入排程',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->showModal = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.modals.branch-sync-modal');
|
||||||
|
}
|
||||||
|
}
|
@ -202,10 +202,10 @@ final class BranchTable extends PowerGridComponent
|
|||||||
{
|
{
|
||||||
$actions = [];
|
$actions = [];
|
||||||
$actions[] = Button::add('room-synchronous')
|
$actions[] = Button::add('room-synchronous')
|
||||||
->slot('包廂同步')
|
->slot('分店中控同步')
|
||||||
->icon('solid-cog')
|
->icon('solid-cog')
|
||||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded bg-amber-200 text-black')
|
->class('inline-flex items-center gap-1 px-3 py-1 rounded bg-amber-200 text-black')
|
||||||
->dispatch('synchronous.' . $this->tableName, ['branch_id' => $row->id]);
|
->dispatchTo('modals.branch-sync-modal','openModal', ['branch_id' => $row->id]);
|
||||||
if ($this->canEdit) {
|
if ($this->canEdit) {
|
||||||
$actions[] =Button::add('edit')
|
$actions[] =Button::add('edit')
|
||||||
->slot(__('branches.edit'))
|
->slot(__('branches.edit'))
|
||||||
|
@ -62,7 +62,12 @@ final class RoomStatusLogTable extends PowerGridComponent
|
|||||||
->add('user_name', function (RoomStatusLog $model){
|
->add('user_name', function (RoomStatusLog $model){
|
||||||
return $model->user?->name;
|
return $model->user?->name;
|
||||||
})
|
})
|
||||||
->add('is_online')
|
->add('is_online_img', fn ($model) =>
|
||||||
|
[
|
||||||
|
$model->is_online ? 'check-circle' : 'x-circle' => [
|
||||||
|
'text-color' => $model->is_online ? 'text-green-600' : 'text-red-600',
|
||||||
|
],
|
||||||
|
])
|
||||||
->add('status_str',function (RoomStatusLog $model){
|
->add('status_str',function (RoomStatusLog $model){
|
||||||
return $model->status->labelPowergridFilter();
|
return $model->status->labelPowergridFilter();
|
||||||
})
|
})
|
||||||
@ -80,7 +85,7 @@ final class RoomStatusLogTable extends PowerGridComponent
|
|||||||
$column[]=Column::make(__('room-status-log.branch'), 'branch_name');
|
$column[]=Column::make(__('room-status-log.branch'), 'branch_name');
|
||||||
$column[]=Column::make(__('room-status-log.room'), 'room_name');
|
$column[]=Column::make(__('room-status-log.room'), 'room_name');
|
||||||
$column[]=Column::make(__('room-status-log.user'), 'user_name');
|
$column[]=Column::make(__('room-status-log.user'), 'user_name');
|
||||||
$column[]=Column::make(__('room-status-log.is_online'), 'is_online');
|
$column[]=Column::make(__('room-status-log.is_online'), 'is_online_img')->template();
|
||||||
$column[]=Column::make(__('room-status-log.status'), 'status_str');
|
$column[]=Column::make(__('room-status-log.status'), 'status_str');
|
||||||
$column[]=Column::make(__('room-status-log.started_at'), 'started_at');
|
$column[]=Column::make(__('room-status-log.started_at'), 'started_at');
|
||||||
$column[]=Column::make(__('room-status-log.ended_at'), 'ended_at');
|
$column[]=Column::make(__('room-status-log.ended_at'), 'ended_at');
|
||||||
@ -89,6 +94,17 @@ final class RoomStatusLogTable extends PowerGridComponent
|
|||||||
$column[]=Column::make(__('room-status-log.created_at'), 'created_at');
|
$column[]=Column::make(__('room-status-log.created_at'), 'created_at');
|
||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
public function rowTemplates(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'check-circle' => '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6 {{ text-color }}">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||||
|
</svg>',
|
||||||
|
'x-circle' => '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6 {{ text-color }}">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||||
|
</svg>',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function filters(): array
|
public function filters(): array
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@ use PowerComponents\LivewirePowerGrid\PowerGridComponent;
|
|||||||
use PowerComponents\LivewirePowerGrid\Traits\WithExport;
|
use PowerComponents\LivewirePowerGrid\Traits\WithExport;
|
||||||
use PowerComponents\LivewirePowerGrid\Components\SetUp\Exportable;
|
use PowerComponents\LivewirePowerGrid\Components\SetUp\Exportable;
|
||||||
use Livewire\Attributes\On;
|
use Livewire\Attributes\On;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
use WireUi\Traits\WireUiActions;
|
use WireUi\Traits\WireUiActions;
|
||||||
|
|
||||||
final class RoomTable extends PowerGridComponent
|
final class RoomTable extends PowerGridComponent
|
||||||
@ -26,7 +27,7 @@ final class RoomTable extends PowerGridComponent
|
|||||||
public string $tableName = 'room-table';
|
public string $tableName = 'room-table';
|
||||||
public bool $canDownload;
|
public bool $canDownload;
|
||||||
public bool $canDelect;
|
public bool $canDelect;
|
||||||
|
#[Url]
|
||||||
public ?int $selectedBranchId = null;
|
public ?int $selectedBranchId = null;
|
||||||
public ?string $external_ip= "";
|
public ?string $external_ip= "";
|
||||||
|
|
||||||
@ -38,8 +39,7 @@ final class RoomTable extends PowerGridComponent
|
|||||||
$this->canDownload=Auth::user()?->can('room-delete') ?? false;
|
$this->canDownload=Auth::user()?->can('room-delete') ?? false;
|
||||||
$this->canDelect = Auth::user()?->can('room-delete') ?? false;
|
$this->canDelect = Auth::user()?->can('room-delete') ?? false;
|
||||||
$branch = Branch::first();
|
$branch = Branch::first();
|
||||||
$this->selectedBranchId = $branch?->id;
|
$this->selectChanged($branch?->id,"", "");
|
||||||
$this->external_ip = $branch?->external_ip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUp(): array
|
public function setUp(): array
|
||||||
@ -57,7 +57,7 @@ final class RoomTable extends PowerGridComponent
|
|||||||
->showToggleColumns();
|
->showToggleColumns();
|
||||||
$header->includeViewOnTop('livewire.headers.room');
|
$header->includeViewOnTop('livewire.headers.room');
|
||||||
$actions[]=$header;
|
$actions[]=$header;
|
||||||
$actions[]=PowerGrid::footer()->pageName('selectedBranchId')->showPerPage()->showRecordCount();
|
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
|
||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
public function header(): array
|
public function header(): array
|
||||||
@ -83,10 +83,6 @@ final class RoomTable extends PowerGridComponent
|
|||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
public function updatedSelectedBranchId($value)
|
|
||||||
{
|
|
||||||
$this->resetPage(); // 重設分頁
|
|
||||||
}
|
|
||||||
|
|
||||||
public function relationSearch(): array
|
public function relationSearch(): array
|
||||||
{
|
{
|
||||||
@ -102,7 +98,12 @@ final class RoomTable extends PowerGridComponent
|
|||||||
return $model->type->labelPowergridFilter();
|
return $model->type->labelPowergridFilter();
|
||||||
})
|
})
|
||||||
->add('name')
|
->add('name')
|
||||||
->add('is_online', fn ($model) => $model->is_online===true ? '在線' : '斷線')
|
->add('is_online_img', fn ($model) => [
|
||||||
|
$model->is_online ? 'check-circle' : 'x-circle' => [
|
||||||
|
'text-color' => $model->is_online ? 'text-green-600' : 'text-red-600',
|
||||||
|
],
|
||||||
|
]
|
||||||
|
)
|
||||||
->add('status_str',function (Room $model){
|
->add('status_str',function (Room $model){
|
||||||
return $model->status->labelPowergridFilter();
|
return $model->status->labelPowergridFilter();
|
||||||
})
|
})
|
||||||
@ -118,7 +119,7 @@ final class RoomTable extends PowerGridComponent
|
|||||||
$column[]=Column::make(__('rooms.floor'), 'floor')->sortable()->searchable();
|
$column[]=Column::make(__('rooms.floor'), 'floor')->sortable()->searchable();
|
||||||
$column[]=Column::make(__('rooms.type'), 'type_str','room.type')->sortable()->searchable();
|
$column[]=Column::make(__('rooms.type'), 'type_str','room.type')->sortable()->searchable();
|
||||||
$column[]=Column::make(__('rooms.name'), 'name')->sortable()->searchable();
|
$column[]=Column::make(__('rooms.name'), 'name')->sortable()->searchable();
|
||||||
$column[]=Column::make(__('rooms.isOnline'), 'is_online');
|
$column[]=Column::make(__('rooms.isOnline'), 'is_online_img')->template();
|
||||||
$column[]=Column::make(__('rooms.status'), 'status_str','room.status')->sortable()->searchable()->hidden(true, false);
|
$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.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.ended_at'), 'str_ended_at', 'ended_at')->sortable()->hidden(true, false);
|
||||||
@ -127,6 +128,17 @@ final class RoomTable extends PowerGridComponent
|
|||||||
|
|
||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
public function rowTemplates(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'check-circle' => '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6 {{ text-color }}">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||||
|
</svg>',
|
||||||
|
'x-circle' => '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6 {{ text-color }}">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||||
|
</svg>',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function filters(): array
|
public function filters(): array
|
||||||
{
|
{
|
||||||
@ -153,11 +165,12 @@ final class RoomTable extends PowerGridComponent
|
|||||||
#[On('selectChanged')]
|
#[On('selectChanged')]
|
||||||
public function selectChanged($value,$fieldName, $modelId): void
|
public function selectChanged($value,$fieldName, $modelId): void
|
||||||
{
|
{
|
||||||
//dd($value,$fieldName, $modelId);
|
|
||||||
if($fieldName == 'selectedBranchId'){
|
if($fieldName == 'selectedBranchId'){
|
||||||
$this->selectedBranchId=$value;
|
$this->selectedBranchId=$value;
|
||||||
$branch = Branch::find($this->selectedBranchId);
|
$branch = Branch::find($this->selectedBranchId);
|
||||||
$this->external_ip=$branch->external_ip;
|
$this->external_ip=$branch->external_ip;
|
||||||
|
$this->resetPage(); // 重設分頁
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[On('deleteRoom')]
|
#[On('deleteRoom')]
|
||||||
|
@ -42,6 +42,12 @@ class Room extends Model
|
|||||||
'started_at',
|
'started_at',
|
||||||
'ended_at',
|
'ended_at',
|
||||||
];
|
];
|
||||||
|
protected $attributes = [
|
||||||
|
'type' => \App\Enums\RoomType::Unset,
|
||||||
|
'floor' => 1,
|
||||||
|
'is_online' => false,
|
||||||
|
'status' => \App\Enums\RoomStatus::Error,
|
||||||
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'internal_ip',
|
'internal_ip',
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
<x-wireui:notifications/>
|
<x-wireui:notifications/>
|
||||||
<livewire:tables.branch-table />
|
<livewire:tables.branch-table />
|
||||||
<livewire:forms.branch-form />
|
<livewire:forms.branch-form />
|
||||||
|
<livewire:modals.branch-sync-modal />
|
||||||
<livewire:import-datas.branch />
|
<livewire:import-datas.branch />
|
||||||
</x-layouts.admin>
|
</x-layouts.admin>
|
32
resources/views/livewire/modals/branch-sync-modal.blade.php
Normal file
32
resources/views/livewire/modals/branch-sync-modal.blade.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<x-wireui:modal id="room-sync-modal" wire:model.defer="showModal" persistent>
|
||||||
|
<x-wireui:card class="border border-gray-200">
|
||||||
|
<x-slot name="action">
|
||||||
|
<button class="cursor-pointer p-1 rounded-full focus:outline-none focus:outline-hidden focus:ring-2 focus:ring-secondary-200 text-secondary-300"
|
||||||
|
wire:click="closeModal"
|
||||||
|
tabindex="-1"
|
||||||
|
>
|
||||||
|
<x-dynamic-component
|
||||||
|
:component="WireUi::component('icon')"
|
||||||
|
name="x-mark"
|
||||||
|
class="w-5 h-5"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</x-slot>
|
||||||
|
<x-slot name="title">
|
||||||
|
{{ $branch_name ?? '未選擇' }} 分店中控同步
|
||||||
|
</x-slot>
|
||||||
|
<div class="grid grid-cols-1 gap-2 mb-4">
|
||||||
|
<x-wireui:checkbox id="sync-song" wire:model="syncSong" label="歌曲資料 Song" />
|
||||||
|
<x-wireui:checkbox id="sync-favorite" wire:model="syncFavorite" label="收藏資料 Favorite" />
|
||||||
|
<x-wireui:checkbox id="sync-text-ads" wire:model="syncTextAds" label="跑馬燈 TextAd" />
|
||||||
|
<x-wireui:checkbox id="sync-user" wire:model="syncUser" label="使用者資料 User" />
|
||||||
|
<x-wireui:checkbox id="sync-branch" wire:model="syncBranch" label="分店資料 Branch" />
|
||||||
|
</div>
|
||||||
|
<x-slot name="footer">
|
||||||
|
<div class="flex justify-between w-full">
|
||||||
|
<x-wireui:button flat label="{{__('branches.cancel')}}" wire:click="closeModal" />
|
||||||
|
<x-wireui:button primary label="{{__('branches.submit')}}" wire:click="save" />
|
||||||
|
</div>
|
||||||
|
</x-slot>
|
||||||
|
</x-wireui:card>
|
||||||
|
</x-wireui:modal>
|
Loading…
x
Reference in New Issue
Block a user