star-cloud/app/Http/Controllers/Admin/SalesController.php
sky121113 78321ad693 [FEAT] 取貨碼功能優化與 QR Code 生成標準化
1. 修復 PickupCode 與 PassCode 模型中 User 命名空間錯誤。
2. 建立統一的 x-qr-code 組件,取代外部 API 並收斂至系統後端路由。
3. 優化取貨碼管理介面:將機台與商品貨道資訊拆分欄位,並動態顯示關聯商品名稱。
4. 補全 status-badge 組件中已使用、已過期與已取消的狀態樣式。
5. 修復取貨碼產生過程中的 Carbon 型別錯誤與 company_id 缺失問題。
2026-04-28 17:25:59 +08:00

221 lines
6.8 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Transaction\PickupCode;
use App\Models\Transaction\PassCode;
use App\Models\Machine\Machine;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
class SalesController extends Controller
{
// 銷售&金流紀錄
public function index()
{
return view('admin.placeholder', [
'title' => '銷售&金流紀錄',
'description' => '銷售交易與金流明細查詢',
'features' => [
'銷售記錄查詢',
'金流對帳',
'發票管理',
'退款處理',
]
]);
}
// 取貨碼設定
public function pickupCodes(Request $request)
{
$query = PickupCode::with(['machine.slots.product', 'creator'])->latest();
if ($request->search) {
$query->where(function($q) use ($request) {
$q->where('code', 'like', "%{$request->search}%")
->orWhereHas('machine', function($mq) use ($request) {
$mq->where('name', 'like', "%{$request->search}%")
->orWhere('serial_no', 'like', "%{$request->search}%");
});
});
}
if ($request->status) {
$query->where('status', $request->status);
}
$pickupCodes = $query->paginate(15)->withQueryString();
// 供新增彈窗使用的機台清單
$machines = Machine::all();
return view('admin.sales.pickup-codes.index', [
'title' => '取貨碼設定',
'description' => '產生與管理商品取貨驗證碼',
'pickupCodes' => $pickupCodes,
'machines' => $machines,
]);
}
/**
* 產生取貨碼
*/
public function storePickupCode(Request $request)
{
$validated = $request->validate([
'machine_id' => 'required|exists:machines,id',
'slot_no' => 'required|string',
'expires_hours' => 'nullable|integer|min:1|max:720', // 最長一個月
]);
$machine = Machine::findOrFail($validated['machine_id']);
$expiresAt = now()->addHours((int) ($request->expires_hours ?? 24));
$pickupCode = PickupCode::create([
'machine_id' => $validated['machine_id'],
'slot_no' => $validated['slot_no'],
'code' => PickupCode::generateUniqueCode($validated['machine_id']),
'expires_at' => $expiresAt,
'status' => 'active',
'company_id' => $machine->company_id,
'created_by' => Auth::id(),
]);
return back()->with('success', __('Pickup code generated: :code', ['code' => $pickupCode->code]));
}
/**
* 更新取貨碼 (僅限修改時間)
*/
public function updatePickupCode(Request $request, PickupCode $pickupCode)
{
$validated = $request->validate([
'expires_at' => 'required|date|after:now',
]);
$pickupCode->update([
'expires_at' => $validated['expires_at'],
]);
return back()->with('success', __('Pickup code updated.'));
}
/**
* 刪除/取消取貨碼
*/
public function destroyPickupCode(PickupCode $pickupCode)
{
$pickupCode->update(['status' => 'cancelled']);
return back()->with('success', __('Pickup code cancelled.'));
}
// 購買單
public function orders()
{
return view('admin.placeholder', [
'title' => '購買單',
'description' => '購買訂單管理',
]);
}
// 促銷時段設定
public function promotions()
{
return view('admin.placeholder', [
'title' => '促銷時段設定',
'description' => '促銷活動時間設定',
]);
}
// 通行碼設定
public function passCodes(Request $request)
{
$query = PassCode::with(['machine', 'creator'])->latest();
if ($request->search) {
$query->where(function($q) use ($request) {
$q->where('code', 'like', "%{$request->search}%")
->orWhere('name', 'like', "%{$request->search}%")
->orWhereHas('machine', function($mq) use ($request) {
$mq->where('name', 'like', "%{$request->search}%")
->orWhere('serial_no', 'like', "%{$request->search}%");
});
});
}
$passCodes = $query->paginate(15)->withQueryString();
$machines = Machine::all();
return view('admin.sales.pass-codes.index', [
'title' => '通行碼設定',
'description' => '特殊通行權限碼管理 (測試/補貨用)',
'passCodes' => $passCodes,
'machines' => $machines,
]);
}
/**
* 產生通行碼
*/
public function storePassCode(Request $request)
{
$validated = $request->validate([
'machine_id' => 'required|exists:machines,id',
'name' => 'nullable|string|max:50',
'expires_days' => 'nullable|integer|min:1',
'custom_code' => 'nullable|string|min:4|max:12',
]);
$machine = Machine::findOrFail($validated['machine_id']);
$expiresAt = $request->expires_days ? now()->addDays((int) $request->expires_days) : null;
$passCode = PassCode::create([
'machine_id' => $validated['machine_id'],
'name' => $validated['name'] ?? 'Manual Generate',
'code' => $validated['custom_code'] ?? PassCode::generateUniqueCode($validated['machine_id']),
'expires_at' => $expiresAt,
'status' => 'active',
'company_id' => $machine->company_id,
'created_by' => Auth::id(),
]);
return back()->with('success', __('Pass code created: :code', ['code' => $passCode->code]));
}
/**
* 更新通行碼
*/
public function updatePassCode(Request $request, PassCode $passCode)
{
$validated = $request->validate([
'name' => 'nullable|string|max:50',
'expires_at' => 'nullable|date',
'status' => 'required|in:active,disabled',
]);
$passCode->update($validated);
return back()->with('success', __('Pass code updated.'));
}
/**
* 刪除通行碼
*/
public function destroyPassCode(PassCode $passCode)
{
$passCode->delete();
return back()->with('success', __('Pass code deleted.'));
}
// 來店禮設定
public function storeGifts()
{
return view('admin.placeholder', [
'title' => '來店禮設定',
'description' => '來店優惠活動設定',
]);
}
}