[FIX] 合併取貨碼/通行碼/來店禮租戶機台授權修復

This commit is contained in:
sky121113 2026-06-24 15:40:26 +08:00
commit a65f4cd45c
4 changed files with 48 additions and 15 deletions

View File

@ -194,7 +194,10 @@ class SalesController extends Controller
// 1. 取貨碼列表 (list) // 1. 取貨碼列表 (list)
if (!$isAjax || $tab === 'list') { if (!$isAjax || $tab === 'list') {
$query = PickupCode::with(['machine.slots.product', 'creator', 'order'])->latest(); // 僅顯示目前帳號可存取機台的取貨碼(機台授權以 machine_user 為準whereHas 會套用 Machine 的 machine_access 全域 scope
$query = PickupCode::with(['machine.slots.product', 'creator', 'order'])
->whereHas('machine')
->latest();
if ($request->search) { if ($request->search) {
$query->where(function ($q) use ($request) { $query->where(function ($q) use ($request) {
@ -219,7 +222,12 @@ class SalesController extends Controller
// 2. 操作紀錄 (logs) // 2. 操作紀錄 (logs)
if (!$isAjax || $tab === 'logs') { if (!$isAjax || $tab === 'logs') {
$logQuery = PickupCodeLog::with(['user:id,name', 'machine:id,name,serial_no', 'pickupCode', 'order']); // 同上操作紀錄只顯示可存取機台的資料machine_id 為 null 的非機台紀錄仍保留)
$logQuery = PickupCodeLog::with(['user:id,name', 'machine:id,name,serial_no', 'pickupCode', 'order'])
->where(function ($q) {
$q->whereNull('machine_id')
->orWhereHas('machine');
});
if ($request->filled('search_log')) { if ($request->filled('search_log')) {
$search = $request->input('search_log'); $search = $request->input('search_log');
@ -362,6 +370,11 @@ class SalesController extends Controller
*/ */
public function destroyPickupCode(PickupCode $pickupCode) public function destroyPickupCode(PickupCode $pickupCode)
{ {
// 機台授權以 machine_user 為準:非系統管理員若無法存取該取貨碼所屬機台則拒絕
if (!Auth::user()->isSystemAdmin() && !Machine::whereKey($pickupCode->machine_id)->exists()) {
abort(403);
}
$oldValues = $pickupCode->toArray(); $oldValues = $pickupCode->toArray();
$pickupCode->update(['status' => 'cancelled']); $pickupCode->update(['status' => 'cancelled']);
@ -411,7 +424,10 @@ class SalesController extends Controller
// 1. 通行碼列表 (list) // 1. 通行碼列表 (list)
if (!$isAjax || $tab === 'list') { if (!$isAjax || $tab === 'list') {
$query = PassCode::with(['machine', 'creator'])->latest(); // 僅顯示目前帳號可存取機台的通行碼(機台授權以 machine_user 為準whereHas 會套用 Machine 的 machine_access 全域 scope
$query = PassCode::with(['machine', 'creator'])
->whereHas('machine')
->latest();
if ($request->search) { if ($request->search) {
$query->where(function ($q) use ($request) { $query->where(function ($q) use ($request) {
@ -447,7 +463,9 @@ class SalesController extends Controller
// 2. 操作紀錄 (logs) // 2. 操作紀錄 (logs)
if (!$isAjax || $tab === 'logs') { if (!$isAjax || $tab === 'logs') {
$logQuery = PassCodeLog::with(['user:id,name', 'machine:id,name,serial_no', 'passCode']); // 同上操作紀錄只顯示可存取機台的資料pass_code_logs.machine_id 為 NOT NULL
$logQuery = PassCodeLog::with(['user:id,name', 'machine:id,name,serial_no', 'passCode'])
->whereHas('machine');
if ($request->filled('search_log')) { if ($request->filled('search_log')) {
$search = $request->input('search_log'); $search = $request->input('search_log');
@ -587,6 +605,11 @@ class SalesController extends Controller
*/ */
public function destroyPassCode(PassCode $passCode) public function destroyPassCode(PassCode $passCode)
{ {
// 機台授權以 machine_user 為準:非系統管理員若無法存取該通行碼所屬機台則拒絕
if (!Auth::user()->isSystemAdmin() && !Machine::whereKey($passCode->machine_id)->exists()) {
abort(403);
}
$oldValues = $passCode->toArray(); $oldValues = $passCode->toArray();
$passCode->update(['status' => 'disabled']); $passCode->update(['status' => 'disabled']);
@ -618,7 +641,10 @@ class SalesController extends Controller
// 1. 來店禮列表 (list) // 1. 來店禮列表 (list)
if (!$isAjax || $tab === 'list') { if (!$isAjax || $tab === 'list') {
$query = WelcomeGift::with(['machine', 'creator'])->latest(); // 僅顯示目前帳號可存取機台的來店禮(機台授權以 machine_user 為準whereHas 會套用 Machine 的 machine_access 全域 scope
$query = WelcomeGift::with(['machine', 'creator'])
->whereHas('machine')
->latest();
if ($request->search) { if ($request->search) {
$query->where(function ($q) use ($request) { $query->where(function ($q) use ($request) {
@ -654,7 +680,9 @@ class SalesController extends Controller
// 2. 操作紀錄 (logs) // 2. 操作紀錄 (logs)
if (!$isAjax || $tab === 'logs') { if (!$isAjax || $tab === 'logs') {
$logQuery = WelcomeGiftLog::with(['machine:id,name,serial_no', 'welcomeGift', 'order:id,order_no']); // 同上操作紀錄只顯示可存取機台的資料welcome_gift_logs.machine_id 為 NOT NULL
$logQuery = WelcomeGiftLog::with(['machine:id,name,serial_no', 'welcomeGift', 'order:id,order_no'])
->whereHas('machine');
if ($request->filled('search_log')) { if ($request->filled('search_log')) {
$search = $request->input('search_log'); $search = $request->input('search_log');
@ -846,6 +874,11 @@ class SalesController extends Controller
*/ */
public function destroyWelcomeGift(WelcomeGift $welcomeGift) public function destroyWelcomeGift(WelcomeGift $welcomeGift)
{ {
// 機台授權以 machine_user 為準:非系統管理員若無法存取該來店禮所屬機台則拒絕
if (!Auth::user()->isSystemAdmin() && !Machine::whereKey($welcomeGift->machine_id)->exists()) {
abort(403);
}
$oldValues = $welcomeGift->toArray(); $oldValues = $welcomeGift->toArray();
$welcomeGift->update(['status' => 'disabled']); $welcomeGift->update(['status' => 'disabled']);

View File

@ -109,7 +109,7 @@
<div class="text-base font-extrabold text-slate-800 dark:text-slate-100 tracking-tight"> <div class="text-base font-extrabold text-slate-800 dark:text-slate-100 tracking-tight">
{{ $code->name }}</div> {{ $code->name }}</div>
<div class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{ <div class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{
$code->machine->name }}</div> $code->machine?->name ?? '-' }}</div>
</td> </td>
<td class="px-6 py-6 whitespace-nowrap"> <td class="px-6 py-6 whitespace-nowrap">
@if($code->expires_at) @if($code->expires_at)
@ -241,7 +241,7 @@
class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1"> class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1">
{{ __('Machine') }}</p> {{ __('Machine') }}</p>
<p class="text-sm font-bold text-slate-700 dark:text-slate-300 truncate">{{ <p class="text-sm font-bold text-slate-700 dark:text-slate-300 truncate">{{
$code->machine->name }}</p> $code->machine?->name ?? '-' }}</p>
</div> </div>
<div> <div>
<p <p

View File

@ -117,15 +117,15 @@
<td class="px-6 py-6"> <td class="px-6 py-6">
<div <div
class="text-base font-extrabold text-slate-800 dark:text-slate-100 tracking-tight"> class="text-base font-extrabold text-slate-800 dark:text-slate-100 tracking-tight">
{{ $code->machine->name }}</div> {{ $code->machine?->name ?? '-' }}</div>
<div <div
class="text-[10px] font-bold text-slate-400 uppercase tracking-[0.2em]"> class="text-[10px] font-bold text-slate-400 uppercase tracking-[0.2em]">
{{ {{
$code->machine->serial_no }}</div> $code->machine?->serial_no }}</div>
</td> </td>
<td class="px-6 py-6"> <td class="px-6 py-6">
@php @php
$slot = $code->machine->slots->where('slot_no', $code->slot_no)->first(); $slot = $code->machine?->slots->where('slot_no', $code->slot_no)->first();
$productName = $slot ? ($slot->product?->name ?? __('Empty')) : __('Empty'); $productName = $slot ? ($slot->product?->name ?? __('Empty')) : __('Empty');
@endphp @endphp
<div class="text-sm font-black text-cyan-600 dark:text-cyan-400 mb-0.5">{{ <div class="text-sm font-black text-cyan-600 dark:text-cyan-400 mb-0.5">{{
@ -251,7 +251,7 @@
@endif @endif
<p <p
class="text-xs font-mono font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest truncate"> class="text-xs font-mono font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest truncate">
{{ $code->machine->name }} {{ $code->machine?->name ?? '-' }}
</p> </p>
</div> </div>
</div> </div>
@ -287,7 +287,7 @@
<p class="text-sm font-bold text-slate-700 dark:text-slate-300"> <p class="text-sm font-bold text-slate-700 dark:text-slate-300">
{{ $code->slot_no }} {{ $code->slot_no }}
@php @php
$slotMobile = $code->machine->slots->where('slot_no', $slotMobile = $code->machine?->slots->where('slot_no',
$code->slot_no)->first(); $code->slot_no)->first();
$prodMobile = $slotMobile ? ($slotMobile->product?->name ?? __('Empty')) : $prodMobile = $slotMobile ? ($slotMobile->product?->name ?? __('Empty')) :
__('Empty'); __('Empty');

View File

@ -108,7 +108,7 @@
<div class="text-base font-extrabold text-slate-800 dark:text-slate-100 tracking-tight"> <div class="text-base font-extrabold text-slate-800 dark:text-slate-100 tracking-tight">
{{ $gift->name }}</div> {{ $gift->name }}</div>
<div class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{ <div class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{
$gift->machine->name }}</div> $gift->machine?->name ?? '-' }}</div>
</td> </td>
<td class="px-6 py-6 whitespace-nowrap"> <td class="px-6 py-6 whitespace-nowrap">
<span class="text-sm font-black text-indigo-600 dark:text-indigo-400 bg-indigo-50 dark:bg-indigo-500/10 px-3 py-1 rounded-lg border border-indigo-100 dark:border-indigo-500/20"> <span class="text-sm font-black text-indigo-600 dark:text-indigo-400 bg-indigo-50 dark:bg-indigo-500/10 px-3 py-1 rounded-lg border border-indigo-100 dark:border-indigo-500/20">
@ -258,7 +258,7 @@
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1"> <p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1">
{{ __('Machine') }}</p> {{ __('Machine') }}</p>
<p class="text-sm font-bold text-slate-700 dark:text-slate-300 truncate"> <p class="text-sm font-bold text-slate-700 dark:text-slate-300 truncate">
{{ $gift->machine->name }}</p> {{ $gift->machine?->name ?? '-' }}</p>
</div> </div>
<div> <div>
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1"> <p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1">