user(); // 如果是在 Console、或是系統管理員,則不限制 (可看所有機台) if (app()->runningInConsole() || !$user || $user->isSystemAdmin()) { return; } // 一般租戶帳號:限制只能看自己擁有的機台 $builder->whereExists(function ($query) use ($user) { $query->select(\Illuminate\Support\Facades\DB::raw(1)) ->from('machine_user') ->whereColumn('machine_user.machine_id', 'machines.id') ->where('machine_user.user_id', $user->id); }); }); } protected $fillable = [ 'company_id', 'name', 'serial_no', 'model', 'location', 'status', 'current_page', 'door_status', 'temperature', 'firmware_version', 'api_token', 'last_heartbeat_at', 'card_reader_seconds', 'card_reader_checkout_time_1', 'card_reader_checkout_time_2', 'heating_start_time', 'heating_end_time', 'payment_buffer_seconds', 'card_reader_no', 'key_no', 'invoice_status', 'welcome_gift_enabled', 'is_spring_slot_1_10', 'is_spring_slot_11_20', 'is_spring_slot_21_30', 'is_spring_slot_31_40', 'is_spring_slot_41_50', 'is_spring_slot_51_60', 'member_system_enabled', 'payment_config_id', 'machine_model_id', 'images', 'creator_id', 'updater_id', ]; protected $appends = ['image_urls']; protected $casts = [ 'last_heartbeat_at' => 'datetime', 'welcome_gift_enabled' => 'boolean', 'is_spring_slot_1_10' => 'boolean', 'is_spring_slot_11_20' => 'boolean', 'is_spring_slot_21_30' => 'boolean', 'is_spring_slot_31_40' => 'boolean', 'is_spring_slot_41_50' => 'boolean', 'is_spring_slot_51_60' => 'boolean', 'member_system_enabled' => 'boolean', 'images' => 'array', ]; /** * Get machine images absolute URLs */ public function getImageUrlsAttribute(): array { if (empty($this->images)) { return []; } return array_map(fn($path) => \Illuminate\Support\Facades\Storage::disk('public')->url($path), $this->images); } public function logs() { return $this->hasMany(MachineLog::class); } public function slots() { return $this->hasMany(MachineSlot::class); } public function commands() { return $this->hasMany(RemoteCommand::class); } public function machineModel() { return $this->belongsTo(MachineModel::class); } public function paymentConfig() { return $this->belongsTo(\App\Models\System\PaymentConfig::class); } public function creator() { return $this->belongsTo(\App\Models\System\User::class, 'creator_id'); } public function updater() { return $this->belongsTo(\App\Models\System\User::class, 'updater_id'); } public const PAGE_STATUSES = [ '0' => 'Offline', '1' => 'Home Page', '2' => 'Vending Page', '3' => 'Admin Page', '4' => 'Replenishment Page', '5' => 'Tutorial Page', '6' => 'Purchasing', '7' => 'Locked Page', '60' => 'Dispense Success', '61' => 'Slot Test', '62' => 'Payment Selection', '63' => 'Waiting for Payment', '64' => 'Dispensing', '65' => 'Receipt Printing', '66' => 'Pass Code', '67' => 'Pickup Code', '68' => 'Message Display', '69' => 'Cancel Purchase', '610' => 'Purchase Finished', '611' => 'Welcome Gift', '612' => 'Dispense Failed', ]; public function getCurrentPageLabelAttribute(): string { $code = (string) $this->current_page; $label = self::PAGE_STATUSES[$code] ?? $code; return __($label); } public function users() { return $this->belongsToMany(\App\Models\System\User::class); } }