[PROMOTE] 晉升 dev 變更至 demo 測試環境

1. 銷售紀錄(Orders)與員工卡交易資訊進行全關聯。
2. 新增支援員工姓名、工號與感應卡號的模糊搜尋與過濾條件。
3. 桌面版與手機 RWD 版銷售列表,新增刷卡資訊與 icon 精美徽章展示。
4. 銷售詳情側滑面板,新增專屬的「員工卡資訊」網格區塊。
This commit is contained in:
sky121113 2026-05-19 10:54:59 +08:00
commit 307b98f86e
5 changed files with 73 additions and 3 deletions

View File

@ -62,7 +62,13 @@ class SalesController extends Controller
];
// 1. 建立基本查詢 (套用共用過濾器:機台、日期)
$ordersQuery = Order::with(['machine:id,name,serial_no', 'invoice:id,order_id,invoice_no', 'items']);
$ordersQuery = Order::with([
'machine:id,name,serial_no',
'invoice:id,order_id,invoice_no',
'items',
'staffCardLog:id,order_id,staff_card_id',
'staffCardLog.staffCard:id,employee_id,name,card_uid'
]);
$invoicesQuery = Invoice::with(['machine:id,name,serial_no', 'order:id,order_no,flow_id,payment_type']);
$dispenseQuery = DispenseRecord::with(['order:id,order_no,flow_id', 'machine:id,name,serial_no', 'product:id,name']);
@ -88,7 +94,12 @@ class SalesController extends Controller
$q->where('order_no', 'like', "%{$search}%")
->orWhere('flow_id', 'like', "%{$search}%")
->orWhere('invoice_info', 'like', "%{$search}%")
->orWhere('member_barcode', 'like', "%{$search}%");
->orWhere('member_barcode', 'like', "%{$search}%")
->orWhereHas('staffCardLog.staffCard', function($sq) use ($search) {
$sq->where('name', 'like', "%{$search}%")
->orWhere('employee_id', 'like', "%{$search}%")
->orWhere('card_uid', 'like', "%{$search}%");
});
});
} elseif ($tab === 'invoices') {
$invoicesQuery->where(function($q) use ($search) {
@ -136,7 +147,14 @@ class SalesController extends Controller
*/
public function show(Order $order)
{
$order->load(['machine', 'invoice', 'items', 'dispenseRecords.product']);
$order->load([
'machine',
'invoice',
'items',
'dispenseRecords.product',
'staffCardLog:id,order_id,staff_card_id',
'staffCardLog.staffCard:id,employee_id,name,card_uid'
]);
return response()->json([
'success' => true,

View File

@ -136,4 +136,9 @@ class Order extends Model
{
return $this->hasMany(DispenseRecord::class);
}
public function staffCardLog()
{
return $this->hasOne(\App\Models\StaffCardLog::class);
}
}

View File

@ -1531,6 +1531,7 @@
"Spring Limit": "彈簧貨道上限",
"Staff": "員工",
"Staff Card": "員工卡",
"Staff Card Info": "員工卡資訊",
"Staff Identification Management": "員工識別管理",
"Staff List": "員工列表",
"Staff Name": "員工姓名",

View File

@ -84,6 +84,36 @@
</div>
</section>
{{-- 員工卡資訊 --}}
@if($order->payment_type == 41 && $order->staffCardLog && $order->staffCardLog->staffCard)
<section class="space-y-4">
<div class="flex items-center gap-2 px-1">
<div class="w-1.5 h-4 bg-cyan-500 rounded-full"></div>
<h3 class="text-sm font-black text-slate-800 dark:text-white uppercase tracking-widest">{{ __('Staff Card Info') }}</h3>
</div>
<div class="grid grid-cols-2 gap-8 p-8 bg-slate-50/50 dark:bg-slate-800/30 rounded-[2rem] border border-slate-100 dark:border-slate-800">
<div class="space-y-1">
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('Staff Name') }}</p>
<p class="text-sm font-extrabold text-slate-700 dark:text-slate-200">{{ $order->staffCardLog->staffCard->name }}</p>
</div>
<div class="space-y-1">
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('Employee ID') }}</p>
<p class="text-sm font-bold text-slate-700 dark:text-slate-300 font-mono tracking-tight">{{ $order->staffCardLog->staffCard->employee_id }}</p>
</div>
<div class="space-y-1 col-span-2">
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('Card UID') }}</p>
<p class="text-xs font-black text-slate-400 dark:text-slate-500 font-mono uppercase tracking-widest">{{ $order->staffCardLog->staffCard->card_uid }}</p>
</div>
@if($order->staffCardLog->staffCard->notes)
<div class="space-y-1 col-span-2">
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('Notes') }}</p>
<p class="text-xs font-bold text-slate-500 dark:text-slate-400">{{ $order->staffCardLog->staffCard->notes }}</p>
</div>
@endif
</div>
</section>
@endif
{{-- 商品明細 --}}
<section class="space-y-4">
<div class="flex items-center justify-between px-1">

View File

@ -202,6 +202,14 @@
{{ __('Discounted') }} ${{ number_format($order->discount_amount, 0) }}
</span>
@endif
@if($order->payment_type == 41 && $order->staffCardLog && $order->staffCardLog->staffCard)
<span class="text-[10px] text-cyan-600 dark:text-cyan-400 font-extrabold mt-1.5 flex items-center gap-1">
<svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 9h3.75M15 12h3.75M15 15h3.75M4.5 19.5h15a2.25 2.25 0 002.25-2.25V6.75A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25v10.5A2.25 2.25 0 004.5 19.5zm6-10.125a1.875 1.875 0 11-3.75 0 1.875 1.875 0 013.75 0zm1.294 6.336a6.721 6.721 0 01-3.17.789 6.721 6.721 0 01-3.168-.789 3.376 3.376 0 016.338 0z" />
</svg>
{{ $order->staffCardLog->staffCard->name }} ({{ $order->staffCardLog->staffCard->employee_id }})
</span>
@endif
</div>
</td>
<td class="px-6 py-6 whitespace-nowrap">
@ -331,6 +339,14 @@
<span class="text-[10px] px-1.5 py-0.5 rounded bg-slate-100 dark:bg-slate-800/50 text-slate-500">{{
$paymentTypes[$order->payment_type] ?? '??' }}</span>
</p>
@if($order->payment_type == 41 && $order->staffCardLog && $order->staffCardLog->staffCard)
<div class="text-[10px] text-cyan-600 dark:text-cyan-400 font-extrabold mt-1 flex items-center gap-1">
<svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 9h3.75M15 12h3.75M15 15h3.75M4.5 19.5h15a2.25 2.25 0 002.25-2.25V6.75A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25v10.5A2.25 2.25 0 004.5 19.5zm6-10.125a1.875 1.875 0 11-3.75 0 1.875 1.875 0 013.75 0zm1.294 6.336a6.721 6.721 0 01-3.17.789 6.721 6.721 0 01-3.168-.789 3.376 3.376 0 016.338 0z" />
</svg>
{{ $order->staffCardLog->staffCard->name }} ({{ $order->staffCardLog->staffCard->employee_id }})
</div>
@endif
</div>
<div>
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1">{{