加入 SongForm 權限 20250724
This commit is contained in:
parent
f3eaa9c715
commit
79588bf0c7
36
app/Enums/TextAdColors.php
Normal file
36
app/Enums/TextAdColors.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Enums\Traits\HasLabels;
|
||||
|
||||
enum TextAdColors: string
|
||||
{
|
||||
use HasLabels;
|
||||
|
||||
case Black = 'black';
|
||||
case White = 'white';
|
||||
case Red = 'red';
|
||||
case Green = 'green';
|
||||
case Blue = 'blue';
|
||||
|
||||
public function labels(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::Black => '黑色',
|
||||
self::White => '白色',
|
||||
self::Red => '紅色',
|
||||
self::Green => '綠色',
|
||||
self::Blue => '藍色',
|
||||
};
|
||||
}
|
||||
public function colorCode(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::White => '#FFFFFF',
|
||||
self::Red => '#FF0000',
|
||||
self::Green => '#90EE90',
|
||||
self::Blue => '#ADD8E6',
|
||||
};
|
||||
}
|
||||
}
|
@ -69,6 +69,9 @@ class SongForm extends Component
|
||||
'name' => $situation->labels(),
|
||||
'value' => $situation->value,
|
||||
])->toArray();
|
||||
$this->canCreate = Auth::user()?->can('song-edit') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('song-edit') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('song-delete') ?? false;
|
||||
}
|
||||
|
||||
public function openModal($id = null)
|
||||
|
81
app/Livewire/Forms/TextAdTestForm.php
Normal file
81
app/Livewire/Forms/TextAdTestForm.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Forms;
|
||||
|
||||
use Livewire\Component;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
|
||||
use App\Models\Room;
|
||||
use App\Models\TextAd;
|
||||
use App\Services\TcpSocketClient;
|
||||
|
||||
class TextAdTestForm extends Component
|
||||
{
|
||||
use WireUiActions;
|
||||
protected $listeners = ['openModal','closeModal'];
|
||||
|
||||
public bool $showModal = false;
|
||||
public ?string $prefix ="";
|
||||
public ?string $content = "";
|
||||
public ?int $roomId = null;
|
||||
public array $roomOptions =[];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->roomOptions = Room::where('type', '!=', 'svr')->get()->map(fn ($room) => [
|
||||
'name' => $room->type->value.$room->name,
|
||||
'value' => $room->id,
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public function openModal($id = null)
|
||||
{
|
||||
$textAd=TextAd::findOrFail($id);
|
||||
$this->prefix = "({$textAd->color->labels()})-測試:";
|
||||
$this->content = $textAd->content;
|
||||
$this->showModal = true;
|
||||
}
|
||||
public function closeModal()
|
||||
{
|
||||
$this->textAd=null;
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
|
||||
$room = Room::find($this->roomId);
|
||||
$roomCode = str_pad($room->name, 4, '0', STR_PAD_LEFT);
|
||||
try {
|
||||
|
||||
$client = new TcpSocketClient($room->internal_ip, $room->port);
|
||||
$client->send($roomCode.$this->prefix.$this->content);
|
||||
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => "✅ 已送出至房間 {$room->name}",
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
$this->notification()->send([
|
||||
'icon' => 'error',
|
||||
'title' => '失敗',
|
||||
'description' => "❌ 發送失敗:{$e->getMessage()}",
|
||||
]);
|
||||
}
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
$this->dispatch('pg:eventRefresh-text-ads-table');
|
||||
}
|
||||
public function resetFields()
|
||||
{
|
||||
$this->content='';
|
||||
$this->roomId=null;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.forms.text-ad-test-form');
|
||||
}
|
||||
}
|
126
app/Livewire/Forms/TextAdsForm.php
Normal file
126
app/Livewire/Forms/TextAdsForm.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Forms;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
use Livewire\Component;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
|
||||
use App\Models\TextAd;
|
||||
use App\Enums\TextAdColors;
|
||||
|
||||
class TextAdsForm extends Component
|
||||
{
|
||||
use WireUiActions;
|
||||
|
||||
protected $listeners = ['openModal','closeModal', 'deleteTextAd'];
|
||||
|
||||
public bool $canCreate;
|
||||
public bool $canEdit;
|
||||
public bool $canDelect;
|
||||
|
||||
public bool $showModal = false;
|
||||
public ?int $textAdId = null;
|
||||
|
||||
public array $colorOptions =[];
|
||||
public array $fields = [
|
||||
'content' =>'',
|
||||
'color' => 'black',
|
||||
'duration' => 1,
|
||||
'is_active' => 1,
|
||||
];
|
||||
|
||||
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->colorOptions = collect(TextAdColors::cases())->map(fn ($color) => [
|
||||
'name' => $color->labels(),
|
||||
'value' => $color->value,
|
||||
])->toArray();
|
||||
$this->canCreate = Auth::user()?->can('song-edit') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('song-edit') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('song-delete') ?? false;
|
||||
}
|
||||
|
||||
public function openModal($id = null)
|
||||
{
|
||||
$this->resetFields();
|
||||
|
||||
if ($id) {
|
||||
$textAd = TextAd::findOrFail($id);
|
||||
$this->textAdId = $textAd->id;
|
||||
$this->fields = $textAd->only(array_keys($this->fields));
|
||||
}
|
||||
|
||||
$this->showModal = true;
|
||||
}
|
||||
|
||||
public function closeModal()
|
||||
{
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
if ($this->textAdId) {
|
||||
if ($this->canEdit) {
|
||||
$textAd = TextAd::findOrFail($this->textAdId);
|
||||
$textAd->update($this->fields);
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '文字廣吿已更新',
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if ($this->canCreate) {
|
||||
$textAd = TextAd::create($this->fields);
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '文字廣吿已新增',
|
||||
]);
|
||||
}
|
||||
}
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
$this->dispatch('pg:eventRefresh-text-ads-table');
|
||||
}
|
||||
|
||||
public function deleteTextAd($id)
|
||||
{
|
||||
if ($this->canDelect) {
|
||||
TextAd::findOrFail($id)->delete();
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '文字廣吿已刪除',
|
||||
]);
|
||||
|
||||
$this->dispatch('pg:eventRefresh-text-ads-table');
|
||||
}
|
||||
}
|
||||
|
||||
public function resetFields()
|
||||
{
|
||||
foreach ($this->fields as $key => $value) {
|
||||
if ($key == 'color') {
|
||||
$this->fields[$key] = 'black';
|
||||
} else if ($key == 'content'){
|
||||
$this->fields[$key] = '';
|
||||
} else {
|
||||
$this->fields[$key] = 1;
|
||||
}
|
||||
}
|
||||
$this->textAdId = null;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.forms.text-ads-form');
|
||||
}
|
||||
}
|
215
app/Livewire/Tables/TextAdsTable.php
Normal file
215
app/Livewire/Tables/TextAdsTable.php
Normal file
@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Tables;
|
||||
|
||||
use App\Models\TextAd;
|
||||
use App\Enums\TextAdColors;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use PowerComponents\LivewirePowerGrid\Button;
|
||||
use PowerComponents\LivewirePowerGrid\Column;
|
||||
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 PowerComponents\LivewirePowerGrid\Facades\Rule;
|
||||
use Livewire\Attributes\On;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
|
||||
final class TextAdsTable extends PowerGridComponent
|
||||
{
|
||||
use WithExport, WireUiActions;
|
||||
public string $tableName = 'text-ads-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('text-ad-create') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('text-ad-edit') ?? false;
|
||||
$this->canDownload=Auth::user()?->can('text-ad-delete') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('text-ad-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()->showSoftDeletes()->showToggleColumns();
|
||||
if($this->canCreate){
|
||||
$header->includeViewOnTop('livewire.header.text-ad');
|
||||
}
|
||||
$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 (<span x-text="window.pgBulkActions.count(\'' . $this->tableName . '\')"></span>)')
|
||||
->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
|
||||
{
|
||||
return TextAd::query();
|
||||
}
|
||||
|
||||
public function relationSearch(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function fields(): PowerGridFields
|
||||
{
|
||||
return PowerGrid::fields()
|
||||
->add('id')
|
||||
->add('content')
|
||||
->add(
|
||||
'content_short',
|
||||
fn (TextAd $model) =>
|
||||
'<span title="' . e($model->content) . '">' . e(Str::limit($model->content, 50)) . '</span>'
|
||||
)
|
||||
->add('color')
|
||||
->add('color_str', function (TextAd $model) {
|
||||
if ($this->canEdit) {
|
||||
return Blade::render(
|
||||
'<x-select-category type="occurrence" :options=$options :modelId=$modelId :fieldName=$fieldName :selected=$selected/>',
|
||||
[
|
||||
'options' => TextAdColors::options(),
|
||||
'modelId' => intval($model->id),
|
||||
'fieldName'=>'color',
|
||||
'selected' => $model->color->value
|
||||
]
|
||||
);
|
||||
}
|
||||
// 沒有權限就顯示對應的文字
|
||||
|
||||
return $model->color->labelPowergridFilter(); // 假設 label() 會回傳顯示文字
|
||||
} )
|
||||
->add('duration')
|
||||
->add('is_active')
|
||||
->add('created_at');
|
||||
}
|
||||
|
||||
public function columns(): array
|
||||
{
|
||||
$column=[];
|
||||
$column[] = Column::make(__('text_ads.id'), 'id');
|
||||
$column[] = Column::make(__('text_ads.content'), 'content_short', 'text_ads.content')->sortable()->searchable();
|
||||
$column[] = Column::make(__('text_ads.color'),'color_str', 'text-ads.color')->searchable();
|
||||
$column[] = Column::make(__('text_ads.duration'), 'duration')->sortable()->searchable();
|
||||
$column[] = Column::make(__('text_ads.is_active'), 'is_active')->toggleable(hasPermission: $this->canEdit, trueLabel: 'yes', falseLabel: 'no');
|
||||
$column[] = Column::make(__('text_ads.created_at'), 'created_at')->sortable()->searchable();
|
||||
$column[] = Column::action(__('text_ads.actions'));
|
||||
return $column;
|
||||
}
|
||||
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
];
|
||||
}
|
||||
|
||||
#[On('bulkDelete.{tableName}')]
|
||||
public function bulkDelete(): void
|
||||
{
|
||||
$this->js('alert(window.pgBulkActions.get(\'' . $this->tableName . '\'))');
|
||||
if($this->checkboxValues){
|
||||
foreach ($this->checkboxValues as $id) {
|
||||
$textAd = TextAd::find($id);
|
||||
if ($textAd) {
|
||||
$textAd->delete();
|
||||
}
|
||||
}
|
||||
$this->js('window.pgBulkActions.clearAll()'); // clear the count on the interface.
|
||||
}
|
||||
}
|
||||
#[On('categoryChanged')]
|
||||
public function categoryChanged($value,$fieldName, $modelId): void
|
||||
{
|
||||
//dd($value,$fieldName, $modelId);
|
||||
if (in_array($fieldName, ['color'])) {
|
||||
$this->noUpdated($modelId,$fieldName,$value);
|
||||
}
|
||||
}
|
||||
#[On('onUpdatedEditable')]
|
||||
public function onUpdatedEditable($id, $field, $value): void
|
||||
{
|
||||
if (in_array($field,[
|
||||
''
|
||||
]) && $this->canEdit) {
|
||||
$this->noUpdated($id,$field,$value);
|
||||
}
|
||||
}
|
||||
#[On('onUpdatedToggleable')]
|
||||
public function onUpdatedToggleable($id, $field, $value): void
|
||||
{
|
||||
if (in_array($field,['is_active']) && $this->canEdit) {
|
||||
$this->noUpdated($id,$field,$value);
|
||||
}
|
||||
}
|
||||
private function noUpdated($id,$field,$value){
|
||||
$textAd = TextAd::find($id);
|
||||
if ($textAd) {
|
||||
$textAd->{$field} = $value;
|
||||
$textAd->save(); // 明確觸發 saving
|
||||
}
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => $id.'.'.__('text_ads.'.$field).':'.$value,
|
||||
'description' => '已經寫入',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function actions(TextAd $row): array
|
||||
{
|
||||
$actions = [];
|
||||
$actions[] = Button::add('text-ad-test')
|
||||
->slot('測試')
|
||||
->icon('solid-cog')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded bg-amber-200 text-black')
|
||||
->dispatchTo('forms.text-ad-test-form', 'openModal', ['id' => $row->id]);
|
||||
|
||||
if ($this->canEdit) {
|
||||
$actions[]=Button::add('edit')
|
||||
->slot(__('text_ads.edit'))
|
||||
->icon('solid-pencil-square')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatchTo('forms.text-ads-form', 'openModal', ['id' => $row->id]);
|
||||
}
|
||||
if($this->canDelect){
|
||||
$actions[]=Button::add('delete')
|
||||
->slot(__('text_ads.delete'))
|
||||
->icon('solid-trash')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatchTo('forms.text-ads-form', 'deleteTextAd', ['id' => $row->id]);
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
}
|
20
app/Models/TextAd.php
Normal file
20
app/Models/TextAd.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TextAd extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'content',
|
||||
'color',
|
||||
'duration',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'color' => \App\Enums\TextAdColors::class,
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('text_ads', 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();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('text_ads');
|
||||
}
|
||||
};
|
@ -19,6 +19,7 @@ class DatabaseSeeder extends Seeder
|
||||
FavoriteSongsSeeder::class,
|
||||
CreateAdminUserSeeder::class,
|
||||
TextAdPermissionSeeder::class,
|
||||
TextAdSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
148
database/seeders/TextAdSeeder.php
Normal file
148
database/seeders/TextAdSeeder.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\TextAd;
|
||||
use App\Enums\TextAdColors;
|
||||
|
||||
class TextAdSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$ads = [
|
||||
[
|
||||
'content' => '本公司可使用觸控螢幕及遙控器點歌,另支援<手機點歌>歡迎多加使用,如有操作問題歡迎洽詢服務人員,超級巨星祝您歡唱愉快!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '如需要使用<歌本>點歌,歡迎洽詢服務人員,超級巨星祝您歡唱愉快!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '本公司設有免費WIFI可供貴賓使用(無需密碼)!歡迎多加利用,超級巨星祝您歡唱愉快!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '親愛的貴賓您好:如要<續唱>請於歡唱時間<結束前40分鐘>告知服務人員,造成不便敬請見諒!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '親愛的貴賓您好:凡使用餐飲券進行折抵,每間包廂折抵上限為六百元,造成不便敬請見諒!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '親愛的貴賓您好:凡持有本公司票券(餐飲券.歡唱抵用券)印有"分店店章"或"限OO店使用"等字樣,即無法用於其他分店,造成不便敬請見諒!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '親愛的貴賓您好:七折卡會員卡如未填寫使用截止日期,本公司恕不再提供折扣服務,造成不便敬請見諒!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '親愛的貴賓您好:本公司提供生日.求婚.迎新.送舊,影片播放服務,請於歡唱日期之前三天,洽詢櫃檯人員,超級巨星祝您歡唱愉快!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '親愛的貴賓您好:因本公司寄酒空間有限,即日起寄酒以<三個月>為限,超過期限者本公司有權處理,造成不便敬請見諒!(僅洋酒類享寄酒服務,啤酒類恕不提供)',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '活動消息!來店歡唱FB或IG打卡,即贈送一壺飲料(紅茶.綠茶.熱烏龍茶),打卡後請出示畫面給服務人員確認。',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '活動消息!當日壽星來店享好禮三選一(莓果調酒.紅酒.什錦水果)及600元餐飲券(可當日使用)。(優惠活動及各項專案不得合併使用,造成不便敬請見諒!)',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '活動消息!本公司販售擋酒部隊(每包100元)及檳榔(每包50元),如有需要歡迎洽詢服務人員。',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '依政府法令規定,未滿18歲之青少年,請於23:30前離場,若凌晨12點後,仍有未滿18歲之青少年逗留包廂內,本公司有權利關閉包廂,恕不退費,如父母陪同亦比照上述辦理,敬請顧客配合,造成不便敬請見諒。',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '依政府法令規定,晚上11點後進場,請務必攜帶實體證件(身分證.健保卡.駕照.護照均可)無實體證件或手機翻拍照片或證件無大頭照者,均不得入場,敬請顧客配合,造成不便敬請見諒。',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '因應菸害防制法規定,本場所室內全面禁止吸菸(電子菸),違規吸菸者,最高可處新台幣1萬元罰鍰,敬請顧客配合,造成不便敬請見諒。',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '本公司經衛生局安檢合格通過,使用台灣產豬肉及美國.巴拉圭產牛肉,敬請貴賓安心食用!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '為營造無毒消費環境,讓民眾安心消費,本場所嚴禁毒品,如經發現本公司將立即通報!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '溫馨提醒!酒後不開車,安全有保障!本公司提供代客泊車.駕駛服務,如有需要歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '溫馨提醒!請勿在公共場所打架滋事,以免觸犯法律,若有相關情事,將報警處理,依法送辦!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '溫馨提醒!遠離毒品讓我幫你:0800-770-885(請請您,幫幫我)。毒害報您知,反毒作伙來。健康無價,拒做[毒]行俠!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '溫馨提醒!離場時請記得您的隨身物品及貴重物品,超級巨星祝您歡唱愉快!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '招兵買馬!外場服務生、櫃檯、吧檯、泊車、清潔人員皆有職缺!如有意願應徵者歡迎洽詢櫃檯人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '年度大優惠來囉!幸福套餐優惠星期一至星期四08:00~18:59(四小時),19:00~07:59(三小時)(限中包及大包),詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '促銷優惠!年度大優惠<啤酒類>特定品項有現金優惠價;持現金購買<洋酒類>不加收服務費,詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '新品上市!真露淡麗梅酒600元,原味燒酒199元,水蜜桃燒酒199元,青葡萄燒酒199元(另加一成服務費),詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '春夏暢飲,限時特價!星銀海尼根(箱)現金優惠價799元,優惠日期到2025/07/31止詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '新品上市!金牌ONE啤酒一箱899元(另加一成服務費),持現金購買優惠價只要800元,詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '新品上市!蹦迪調酒一壺只要800元,(另加一成服務費)要飲要快,詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '夏日玩啤趣!紅茶或綠茶二選一(無限暢飲)加限定炸物六選二,持現金購買優惠價只要299元(刷卡另加一成服務費),活動日期只到2025/08/31止,詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '夏日玩啤趣!限定啤酒三選一加限定炸物六選二,持現金購買優惠價只要399元(刷卡另加一成服務費),活動日期只到2025/08/31止,詳情歡迎洽詢服務人員!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($ads as $ad) {
|
||||
TextAd::create([
|
||||
'content' => $ad['content'],
|
||||
'color' => $ad['color'],
|
||||
'duration' => 1,
|
||||
'is_active' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
25
resources/lang/zh-tw/text_ads.php
Normal file
25
resources/lang/zh-tw/text_ads.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'management' => '文字廣吿管理',
|
||||
'list' => '文字廣吿列表',
|
||||
'CreateNew' => '新增文字廣吿',
|
||||
'EditArtist' => '編輯文字廣吿',
|
||||
'ImportData' => '滙入文字廣吿',
|
||||
'create_edit' => '新增 / 編輯',
|
||||
'create' => '新增',
|
||||
'edit' => '編輯',
|
||||
'delete' => '刪除',
|
||||
'id' => '編號',
|
||||
'content' => '廣告內容',
|
||||
'color' => '顏色',
|
||||
'duration' => '播放間隔時間(分鐘)',
|
||||
'is_active' => '是否推播',
|
||||
'created_at' =>'建立於',
|
||||
|
||||
|
||||
'actions' => '操作',
|
||||
'view' => '查看',
|
||||
'submit' => '提交',
|
||||
'cancel' => '取消',
|
||||
];
|
7
resources/views/livewire/admin/text-ads.blade.php
Normal file
7
resources/views/livewire/admin/text-ads.blade.php
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
<x-layouts.admin>
|
||||
<x-wireui:notifications/>
|
||||
<livewire:tables.text-ads-table />
|
||||
<livewire:forms.text-ads-form />
|
||||
<livewire:forms.text-ad-test-form />
|
||||
</x-layouts.admin>
|
24
resources/views/livewire/forms/text-ad-test-form.blade.php
Normal file
24
resources/views/livewire/forms/text-ad-test-form.blade.php
Normal file
@ -0,0 +1,24 @@
|
||||
<div class="p-4 space-y-4">
|
||||
<x-wireui:modal-card title="測試" blur wire:model.defer="showModal">
|
||||
<x-wireui:select
|
||||
label="選擇房間"
|
||||
wire:model.defer="roomId"
|
||||
placeholder="請選擇房間"
|
||||
:options="$roomOptions"
|
||||
option-label="name"
|
||||
option-value="value"
|
||||
/>
|
||||
<div class="text-gray-700 bg-gray-100 p-3 rounded shadow">
|
||||
<div class="font-semibold mb-1">將發送內容:</div>
|
||||
<div>{{ $content }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
<x-slot name="footer">
|
||||
<div class="flex justify-between w-full">
|
||||
<x-wireui:button flat label="{{__('text_ads.cancel')}}" wire:click="closeModal" />
|
||||
<x-wireui:button primary wire:click="send" primary label="立即發送" spinner />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-wireui:modal-card>
|
||||
</div>
|
24
resources/views/livewire/forms/text-ads-form.blade.php
Normal file
24
resources/views/livewire/forms/text-ads-form.blade.php
Normal file
@ -0,0 +1,24 @@
|
||||
<x-wireui:modal-card title="{{ $textAdId ? __('text_ads.EditArtist') : __('text_ads.CreateNew') }}" blur wire:model.defer="showModal">
|
||||
<div class="space-y-4">
|
||||
<x-wireui:input label="{{__('text_ads.content')}}" wire:model.defer="fields.content" />
|
||||
<x-wireui:select
|
||||
label="{{__('text_ads.color')}}"
|
||||
wire:model.defer="fields.color"
|
||||
placeholder="{{__('text_ads.select_color')}}"
|
||||
:options="$colorOptions"
|
||||
option-label="name"
|
||||
option-value="value"
|
||||
/>
|
||||
<x-wireui:input label="{{__('text_ads.duration')}}" type="number" min="1" max="60" wire:model.defer="fields.duration" />
|
||||
|
||||
<x-wireui:toggle label="{{__('text_ads.is_active')}}" wire:model.defer="fields.is_active" />
|
||||
</div>
|
||||
|
||||
<x-slot name="footer">
|
||||
<div class="flex justify-between w-full">
|
||||
<x-wireui:button flat label="{{__('text_ads.cancel')}}" wire:click="closeModal" />
|
||||
<x-wireui:button primary label="{{__('text_ads.submit')}}" wire:click="save" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-wireui:modal-card>
|
||||
|
@ -13,6 +13,7 @@ new class extends Component
|
||||
['label' => 'Artist', 'route' => 'admin.artists', 'icon' => 'musical-note', 'permission' => 'song-list'],
|
||||
['label' => 'Song', 'route' => 'admin.songs', 'icon' => 'musical-note', 'permission' => 'song-list'],
|
||||
['label' => 'Branche', 'route' => 'admin.branches', 'icon' => 'building-library', 'permission' => 'room-list'],
|
||||
['label' => 'TextAd', 'route' => 'admin.text-ads', 'icon' => 'megaphone', 'permission' => 'text-ad-list'],
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -28,5 +28,5 @@ Route::middleware(['auth'])->prefix('admin')->name('admin.')->group(function ()
|
||||
Route::get('/songs', function () {return view('livewire.admin.songs');})->name('songs');
|
||||
Route::get('/branches', function () {return view('livewire.admin.branches');})->name('branches');
|
||||
Route::get('/rooms', function () {return view('livewire.admin.rooms');})->name('rooms');
|
||||
|
||||
Route::get('/text-ads', function () {return view('livewire.admin.text-ads');})->name('text-ads');
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user