[FEAT] 銷售紀錄新增員工卡交易資訊關聯、搜尋與介面展示
1. 於 Order 模型中定義 staffCardLog 關係以關聯 StaffCardLog。 2. 於 SalesController 列表查詢(index)與單筆詳情(show)中進行極致效能優化,限定 Eager Loading 僅撈取必要欄位(id, employee_id, name, card_uid),避免 N+1 查詢與記憶體開銷。 3. 擴充 SalesController 的銷售紀錄搜尋過濾邏輯,新增支援員工姓名、工號與感應卡號的模糊搜尋。 4. 修改 tab-orders 桌面版表格與手機版卡片視圖,為員工卡支付的訂單加上精美的員工卡 icon 與「姓名 (工號)」徽章。 5. 修改 order-detail-panel 側滑詳情面板,新增「員工卡資訊」網格區塊,展示員工姓名、工號、卡片 UID 與備註欄位。 6. 更新 zh_TW.json 補齊「員工卡資訊」的繁體中文翻譯,確保全站語言一致。
This commit is contained in:
parent
916d0891f1
commit
433714d9b0
@ -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,
|
||||
|
||||
@ -136,4 +136,9 @@ class Order extends Model
|
||||
{
|
||||
return $this->hasMany(DispenseRecord::class);
|
||||
}
|
||||
|
||||
public function staffCardLog()
|
||||
{
|
||||
return $this->hasOne(\App\Models\StaffCardLog::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1531,6 +1531,7 @@
|
||||
"Spring Limit": "彈簧貨道上限",
|
||||
"Staff": "員工",
|
||||
"Staff Card": "員工卡",
|
||||
"Staff Card Info": "員工卡資訊",
|
||||
"Staff Identification Management": "員工識別管理",
|
||||
"Staff List": "員工列表",
|
||||
"Staff Name": "員工姓名",
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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">{{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user