[RELEASE] 晉升銷售紀錄員工卡資訊功能至正式生產環境
1. 新增 Order 模型中的 `staffCardLog` 一對一關聯關係。 2. 於 SalesController 列表與詳情查詢中進行 Eager Loading 欄位限定優化,完全避免 N+1 查詢。 3. 擴充銷售紀錄模糊搜尋,支援依員工姓名、工號(Employee ID)與感應卡號(Card UID)進行即時篩選。 4. 調整桌面版表格、手機 RWD 卡片,於員工卡支付之訂單下方呈現感應卡圖示與 `姓名 (工號)`。 5. 於訂單詳情側滑面板中新增專屬「員工卡資訊」網格區塊。 6. 補齊 Traditional Chinese(zh_TW)、English(en)、Japanese(ja)三語系之相關翻譯與搜尋框 Placeholder 提示詞。
This commit is contained in:
commit
cfbe4655da
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1388,6 +1388,7 @@
|
||||
"Search Invoice No / Flow ID...": "Search Invoice No / Flow ID...",
|
||||
"Search Machine...": "Search Machine...",
|
||||
"Search Order No / Flow ID / Invoice...": "Search Order No / Flow ID / Invoice...",
|
||||
"Search Order No / Cards & Codes...": "Search Order No / Cards & Codes...",
|
||||
"Search Product": "Search Product",
|
||||
"Search Product / Slot...": "Search Product / Slot...",
|
||||
"Search accounts...": "Search accounts...",
|
||||
@ -1511,6 +1512,7 @@
|
||||
"Spring Limit": "Spring Limit",
|
||||
"Staff": "Staff",
|
||||
"Staff Card": "Staff Card",
|
||||
"Staff Card Info": "Staff Card Info",
|
||||
"Staff Identification Management": "Staff Identification Management",
|
||||
"Staff List": "Staff List",
|
||||
"Staff Name": "Staff Name",
|
||||
|
||||
@ -1388,6 +1388,7 @@
|
||||
"Search Invoice No / Flow ID...": "領収書番号 / フローIDを検索...",
|
||||
"Search Machine...": "機器を検索...",
|
||||
"Search Order No / Flow ID / Invoice...": "注文番号 / フローID / 領収書を検索...",
|
||||
"Search Order No / Cards & Codes...": "注文番号 / カード・コードを検索...",
|
||||
"Search Product": "商品を検索",
|
||||
"Search Product / Slot...": "商品名 / スロットを検索...",
|
||||
"Search accounts...": "アカウントを検索...",
|
||||
@ -1511,6 +1512,7 @@
|
||||
"Spring Limit": "スプリング上限",
|
||||
"Staff": "スタッフ",
|
||||
"Staff Card": "スタッフカード",
|
||||
"Staff Card Info": "スタッフカード情報",
|
||||
"Staff Identification Management": "スタッフ識別管理",
|
||||
"Staff List": "スタッフ一覧",
|
||||
"Staff Name": "スタッフ名",
|
||||
|
||||
@ -1407,6 +1407,7 @@
|
||||
"Search Invoice No / Flow ID...": "搜尋 發票號碼 / 流水號...",
|
||||
"Search Machine...": "搜尋機台...",
|
||||
"Search Order No / Flow ID / Invoice...": "搜尋 訂單號 / 流水號 / 發票號碼...",
|
||||
"Search Order No / Cards & Codes...": "搜尋 訂單號 / 卡號與代碼...",
|
||||
"Search Product": "搜尋商品",
|
||||
"Search Product / Slot...": "搜尋商品名稱 / 貨道...",
|
||||
"Search accounts...": "搜尋帳號...",
|
||||
@ -1531,6 +1532,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">
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
</span>
|
||||
<input type="text" name="search" value="{{ $tab === 'orders' ? $filters['search'] : '' }}"
|
||||
class="py-2.5 pl-12 pr-6 block w-full luxury-input"
|
||||
placeholder="{{ __('Search Order No / Flow ID / Invoice...') }}">
|
||||
placeholder="{{ __('Search Order No / Cards & Codes...') }}">
|
||||
</div>
|
||||
|
||||
<div class="w-full lg:w-48">
|
||||
@ -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