diff --git a/app/Services/Product/ProductCatalogService.php b/app/Services/Product/ProductCatalogService.php
index 51d8c5e..5f2ed78 100644
--- a/app/Services/Product/ProductCatalogService.php
+++ b/app/Services/Product/ProductCatalogService.php
@@ -10,21 +10,21 @@ class ProductCatalogService
/**
* Get the Redis cache key for a company's product catalog.
*
- * @param int $companyId
+ * @param int|null $companyId
* @return string
*/
- public function getCacheKey(int $companyId): string
+ public function getCacheKey(?int $companyId): string
{
- return "products_catalog:{$companyId}";
+ return "products_catalog:" . ($companyId ?? 'global');
}
/**
* Get the product catalog payload, using cache if available.
*
- * @param int $companyId
+ * @param int|null $companyId
* @return array
*/
- public function getPayload(int $companyId): array
+ public function getPayload(?int $companyId): array
{
$cacheKey = $this->getCacheKey($companyId);
$cached = Cache::get($cacheKey);
@@ -39,10 +39,10 @@ class ProductCatalogService
/**
* Rebuild the product catalog cache for a company.
*
- * @param int $companyId
+ * @param int|null $companyId
* @return array
*/
- public function rebuildCache(int $companyId): array
+ public function rebuildCache(?int $companyId): array
{
$products = Product::where('company_id', $companyId)
->with(['translations'])
@@ -64,10 +64,10 @@ class ProductCatalogService
/**
* Invalidate the product catalog cache for a company.
*
- * @param int $companyId
+ * @param int|null $companyId
* @return void
*/
- public function invalidate(int $companyId): void
+ public function invalidate(?int $companyId): void
{
Cache::forget($this->getCacheKey($companyId));
}
diff --git a/lang/zh_TW.json b/lang/zh_TW.json
index 318bf14..e49963d 100644
--- a/lang/zh_TW.json
+++ b/lang/zh_TW.json
@@ -1988,5 +1988,29 @@
"Old": "舊值",
"New": "新值",
"No changes detected": "未偵測到資料變更",
- "Log Details": "操作紀錄詳情"
+ "Log Details": "操作紀錄詳情",
+ "No detailed changes recorded": "沒有詳細的變更紀錄",
+ "Modified fields": "修改欄位",
+ "company_id": "公司",
+ "category_id": "分類",
+ "name": "商品名稱",
+ "name_dictionary_key": "多語系鍵值",
+ "barcode": "條碼",
+ "spec": "規格",
+ "manufacturer": "製造商",
+ "description": "商品描述",
+ "price": "售價",
+ "member_price": "會員價",
+ "cost": "成本",
+ "track_limit": "履帶容量",
+ "spring_limit": "彈簧容量",
+ "type": "商品類型",
+ "image_url": "商品圖片",
+ "status": "狀態",
+ "is_active": "啟用狀態",
+ "Operator": "操作人員",
+ "Create": "新增",
+ "Update": "編輯",
+ "Target Item": "操作目標",
+ "Manage machine access permissions": "管理機台存取權限"
}
\ No newline at end of file
diff --git a/resources/views/admin/products/partials/tab-logs.blade.php b/resources/views/admin/products/partials/tab-logs.blade.php
index e0a2583..e41d54e 100644
--- a/resources/views/admin/products/partials/tab-logs.blade.php
+++ b/resources/views/admin/products/partials/tab-logs.blade.php
@@ -96,11 +96,14 @@
{{ __('Time') }}
|
+
+ {{ __('Operator') }}
+ |
{{ __('Action') }}
|
- {{ __('Module') }} / {{ __('Target') }}
+ {{ __('Target Item') }}
|
{{ __('Note') }}
@@ -112,12 +115,39 @@
|
@forelse($logs as $log)
+ @php
+ $oldValues = is_string($log->old_values) ? json_decode($log->old_values, true) : (array)($log->old_values ?? []);
+ $newValues = is_string($log->new_values) ? json_decode($log->new_values, true) : (array)($log->new_values ?? []);
+ $ignoredKeys = ['updated_at', 'created_at', 'deleted_at', 'localized_name'];
+ $allKeys = array_diff(array_unique(array_merge(array_keys($oldValues), array_keys($newValues))), $ignoredKeys);
+
+ $changedKeys = [];
+ foreach($allKeys as $k) {
+ if (($oldValues[$k] ?? null) !== ($newValues[$k] ?? null)) {
+ $changedKeys[] = $k;
+ }
+ }
+
+ $displayNote = $log->translated_note;
+ if ($log->action === 'update' && !empty($changedKeys)) {
+ $translatedKeys = array_map(function($k) { return __($k); }, $changedKeys);
+ $displayNote = __('Modified fields') . ': ' . implode(', ', $translatedKeys);
+ }
+ @endphp
|
{{ $log->created_at?->format('Y-m-d H:i:s') }}
|
+
+
+
+ {{ $log->user->name ?? 'System' }}
+
+ |
|
@@ -128,21 +158,52 @@
- {{ $log->translated_note }}
+ {{ $displayNote }}
|
- |
+ {{-- Desktop Expandable Row --}}
+ @if(!empty($changedKeys))
+
+
+
+ @foreach($changedKeys as $key)
+
+ {{ __($key) }}
+
+
+ {{ __('Old Value') }}
+ @php $oldVal = $oldValues[$key] ?? null; @endphp
+ {{ is_array($oldVal) ? json_encode($oldVal) : ($oldVal ?? '-') }}
+
+
+
+ {{ __('New Value') }}
+ @php $newVal = $newValues[$key] ?? null; @endphp
+ {{ is_array($newVal) ? json_encode($newVal) : ($newVal ?? '-') }}
+
+
+
+ @endforeach
+
+ |
+
+ @endif
@empty
- |
+ |
|
@@ -154,6 +215,25 @@
{{-- Card Mode (Mobile) --}}
@forelse($logs as $log)
+ @php
+ $oldValuesMob = is_string($log->old_values) ? json_decode($log->old_values, true) : (array)($log->old_values ?? []);
+ $newValuesMob = is_string($log->new_values) ? json_decode($log->new_values, true) : (array)($log->new_values ?? []);
+ $ignoredKeysMob = ['updated_at', 'created_at', 'deleted_at', 'localized_name'];
+ $allKeysMob = array_diff(array_unique(array_merge(array_keys($oldValuesMob), array_keys($newValuesMob))), $ignoredKeysMob);
+
+ $changedKeysMob = [];
+ foreach($allKeysMob as $k) {
+ if (($oldValuesMob[$k] ?? null) !== ($newValuesMob[$k] ?? null)) {
+ $changedKeysMob[] = $k;
+ }
+ }
+
+ $displayNoteMob = $log->translated_note;
+ if ($log->action === 'update' && !empty($changedKeysMob)) {
+ $translatedKeysMob = array_map(function($k) { return __($k); }, $changedKeysMob);
+ $displayNoteMob = __('Modified fields') . ': ' . implode(', ', $translatedKeysMob);
+ }
+ @endphp
@@ -165,18 +245,49 @@
{{ $log->created_at?->format('H:i:s') }}
-
{{ $log->translated_note }}
+
{{ $displayNoteMob }}
#{{ $log->target_id }}
{{ $log->user->name ?? 'System' }}
-
+
+ {{-- Mobile Expandable Section --}}
+ @if(!empty($changedKeysMob))
+
+ @foreach($changedKeysMob as $key)
+
+
{{ __($key) }}
+
+
+
{{ __('Old Value') }}
+ @php $oldValMob = $oldValuesMob[$key] ?? null; @endphp
+
{{ is_array($oldValMob) ? json_encode($oldValMob) : ($oldValMob ?? '-') }}
+
+
+
+
{{ __('New Value') }}
+ @php $newValMob = $newValuesMob[$key] ?? null; @endphp
+
{{ is_array($newValMob) ? json_encode($newValMob) : ($newValMob ?? '-') }}
+
+
+
+ @endforeach
+
+ @endif
@empty
diff --git a/resources/views/components/status-badge.blade.php b/resources/views/components/status-badge.blade.php
index c1e8732..af1f846 100644
--- a/resources/views/components/status-badge.blade.php
+++ b/resources/views/components/status-badge.blade.php
@@ -65,6 +65,14 @@
'failed' => ['label' => __('Failed'), 'color' => 'rose'],
'timeout' => ['label' => __('Timeout'), 'color' => 'rose'],
'superseded' => ['label' => __('Superseded'),'color' => 'slate'],
+
+ // 操作紀錄 (Activity Log)
+ 'create' => ['label' => __('Create'), 'color' => 'emerald'],
+ 'update' => ['label' => __('Update'), 'color' => 'amber'],
+ 'delete' => ['label' => __('Delete'), 'color' => 'rose'],
+ 'created' => ['label' => __('Created'), 'color' => 'emerald'],
+ 'updated' => ['label' => __('Updated'), 'color' => 'amber'],
+ 'deleted' => ['label' => __('Deleted'), 'color' => 'rose'],
];
$preset = $presets[$status] ?? ['label' => $status, 'color' => 'slate'];