feat: 統一採購單與操作紀錄 UI、增強各模組操作紀錄功能
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 59s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped

- 統一採購單篩選列與表單樣式 (移除舊元件、標準化 Input)
- 增強操作紀錄功能 (加入篩選、快照、詳細異動比對)
- 統一刪除確認視窗與按鈕樣式
- 修復庫存編輯頁面樣式
- 實作採購單品項異動紀錄
- 實作角色分配異動紀錄
- 擴充供應商與倉庫模組紀錄
This commit is contained in:
2026-01-19 17:07:45 +08:00
parent 5c4693577a
commit 7367577f6a
16 changed files with 541 additions and 444 deletions

View File

@@ -9,14 +9,64 @@ use Spatie\Activitylog\Models\Activity;
class ActivityLogController extends Controller
{
private function getSubjectMap()
{
return [
'App\Models\User' => '使用者',
'App\Models\Role' => '角色',
'App\Models\Product' => '商品',
'App\Models\Vendor' => '廠商',
'App\Models\Category' => '商品分類',
'App\Models\Unit' => '單位',
'App\Models\PurchaseOrder' => '採購單',
'App\Models\Warehouse' => '倉庫',
'App\Models\Inventory' => '庫存',
];
}
public function index(Request $request)
{
$perPage = $request->input('per_page', 10);
$sortBy = $request->input('sort_by', 'created_at');
$sortOrder = $request->input('sort_order', 'desc');
$search = $request->input('search');
$dateStart = $request->input('date_start');
$dateEnd = $request->input('date_end');
$event = $request->input('event');
$subjectType = $request->input('subject_type');
$causerId = $request->input('causer_id');
$query = Activity::with('causer');
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('description', 'like', "%{$search}%")
->orWhere('log_name', 'like', "%{$search}%")
->orWhere('properties', 'like', "%{$search}%");
});
}
if ($dateStart) {
$query->whereDate('created_at', '>=', $dateStart);
}
if ($dateEnd) {
$query->whereDate('created_at', '<=', $dateEnd);
}
if ($event) {
$query->where('event', $event);
}
if ($subjectType) {
$query->where('subject_type', $subjectType);
}
if ($causerId) {
$query->where('causer_id', $causerId);
}
if ($sortBy === 'created_at') {
$query->orderBy($sortBy, $sortOrder);
} else {
@@ -25,17 +75,7 @@ class ActivityLogController extends Controller
$activities = $query->paginate($perPage)
->through(function ($activity) {
$subjectMap = [
'App\Models\User' => '使用者',
'App\Models\Role' => '角色',
'App\Models\Product' => '商品',
'App\Models\Vendor' => '廠商',
'App\Models\Category' => '商品分類',
'App\Models\Unit' => '單位',
'App\Models\PurchaseOrder' => '採購單',
'App\Models\Warehouse' => '倉庫',
'App\Models\Inventory' => '庫存',
];
$subjectMap = $this->getSubjectMap();
$eventMap = [
'created' => '新增',
@@ -54,13 +94,32 @@ class ActivityLogController extends Controller
];
});
// Prepare subject types for frontend filter
$subjectTypes = collect($this->getSubjectMap())->map(function ($label, $value) {
return ['label' => $label, 'value' => $value];
})->values();
// Get users for causer filter
$users = \App\Models\User::select('id', 'name')->orderBy('name')->get()
->map(function ($user) {
return ['label' => $user->name, 'value' => (string) $user->id];
});
return Inertia::render('Admin/ActivityLog/Index', [
'activities' => $activities,
'filters' => [
'per_page' => $request->input('per_page', '10'),
'sort_by' => $request->input('sort_by'),
'sort_order' => $request->input('sort_order'),
'search' => $request->input('search'),
'date_start' => $request->input('date_start'),
'date_end' => $request->input('date_end'),
'event' => $request->input('event'),
'subject_type' => $request->input('subject_type'),
'causer_id' => $request->input('causer_id'),
],
'subject_types' => $subjectTypes,
'users' => $users,
]);
}
}

View File

@@ -86,7 +86,7 @@ class UserController extends Controller
if ($activity) {
$roleNames = $user->roles()->pluck('display_name')->join(', ');
$properties = $activity->properties;
$properties = $activity->properties->toArray();
$properties['attributes']['role_id'] = $roleNames;
$activity->properties = $properties;
$activity->save();

View File

@@ -34,6 +34,15 @@ class PurchaseOrderController extends Controller
$query->where('warehouse_id', $request->warehouse_id);
}
// Date Range
if ($request->date_start) {
$query->whereDate('created_at', '>=', $request->date_start);
}
if ($request->date_end) {
$query->whereDate('created_at', '<=', $request->date_end);
}
// Sorting
$sortField = $request->sort_field ?? 'id';
$sortDirection = $request->sort_direction ?? 'desc';
@@ -48,7 +57,7 @@ class PurchaseOrderController extends Controller
return Inertia::render('PurchaseOrder/Index', [
'orders' => $orders,
'filters' => $request->only(['search', 'status', 'warehouse_id', 'sort_field', 'sort_direction', 'per_page']),
'filters' => $request->only(['search', 'status', 'warehouse_id', 'date_start', 'date_end', 'sort_field', 'sort_direction', 'per_page']),
'warehouses' => Warehouse::all(['id', 'name']),
]);
}