diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php index d7fe895..0d950f0 100644 --- a/app/Http/Controllers/Admin/ProductController.php +++ b/app/Http/Controllers/Admin/ProductController.php @@ -86,7 +86,14 @@ class ProductController extends Controller public function edit($id) { $user = auth()->user(); - $product = Product::with(['translations', 'company'])->findOrFail($id); + // 繞過 TenantScoped 載入翻譯,確保系統管理員能看到租戶公司的翻譯資料 + $product = Product::with(['company'])->findOrFail($id); + $product->setRelation('translations', + Translation::withoutGlobalScopes() + ->where('group', 'product') + ->where('key', $product->name_dictionary_key) + ->get() + ); $categories = ProductCategory::all(); $companies = $user->isSystemAdmin() ? Company::all() : collect(); @@ -131,10 +138,10 @@ class ProductController extends Controller ? $request->company_id : auth()->user()->company_id; - // Store translations + // 儲存多語系翻譯(繞過 TenantScoped,避免系統管理員操作租戶資料時被過濾) foreach ($request->names as $locale => $name) { if (empty($name)) continue; - Translation::create([ + Translation::withoutGlobalScopes()->create([ 'group' => 'product', 'key' => $dictKey, 'locale' => $locale, @@ -219,10 +226,10 @@ class ProductController extends Controller $dictKey = $product->name_dictionary_key ?: \Illuminate\Support\Str::uuid()->toString(); $company_id = $product->company_id; - // Update or Create translations + // 更新或建立多語系翻譯(繞過 TenantScoped,避免系統管理員操作租戶資料時被過濾) foreach ($request->names as $locale => $name) { if (empty($name)) { - Translation::where([ + Translation::withoutGlobalScopes()->where([ 'group' => 'product', 'key' => $dictKey, 'locale' => $locale @@ -230,7 +237,7 @@ class ProductController extends Controller continue; } - Translation::updateOrCreate( + Translation::withoutGlobalScopes()->updateOrCreate( [ 'group' => 'product', 'key' => $dictKey, @@ -246,6 +253,7 @@ class ProductController extends Controller $data = [ 'category_id' => $request->category_id, 'name' => $request->names['zh_TW'] ?? ($product->name ?? 'Untitled'), + 'name_dictionary_key' => $dictKey, 'barcode' => $request->barcode, 'spec' => $request->spec, 'manufacturer' => $request->manufacturer, @@ -316,9 +324,9 @@ class ProductController extends Controller try { $product = Product::findOrFail($id); - // Delete translations associated with this product + // 刪除與此商品關聯的翻譯資料(繞過 TenantScoped) if ($product->name_dictionary_key) { - Translation::where('key', $product->name_dictionary_key)->delete(); + Translation::withoutGlobalScopes()->where('key', $product->name_dictionary_key)->delete(); } // Delete image diff --git a/app/Models/Product/Product.php b/app/Models/Product/Product.php index a34a2de..ffb365d 100644 --- a/app/Models/Product/Product.php +++ b/app/Models/Product/Product.php @@ -48,6 +48,33 @@ class Product extends Model return $this->belongsTo(ProductCategory::class, 'category_id'); } + /** + * 自動附加到 JSON/陣列輸出的屬性(供 Alpine.js 等前端使用) + */ + protected $appends = ['localized_name']; + + /** + * 取得當前語系的商品名稱。 + * 回退順序:當前語系 → zh_TW → name 欄位 + */ + public function getLocalizedNameAttribute(): string + { + if ($this->relationLoaded('translations') && $this->translations->isNotEmpty()) { + $locale = app()->getLocale(); + // 先找當前語系 + $translation = $this->translations->firstWhere('locale', $locale); + if ($translation) { + return $translation->value; + } + // 回退至 zh_TW + $fallback = $this->translations->firstWhere('locale', 'zh_TW'); + if ($fallback) { + return $fallback->value; + } + } + return $this->name ?? ''; + } + /** * Get the translations for the product name. */ diff --git a/resources/views/admin/companies/index.blade.php b/resources/views/admin/companies/index.blade.php index 99c81c3..f0cb779 100644 --- a/resources/views/admin/companies/index.blade.php +++ b/resources/views/admin/companies/index.blade.php @@ -484,8 +484,20 @@
- +
+ + +
diff --git a/resources/views/admin/data-config/accounts.blade.php b/resources/views/admin/data-config/accounts.blade.php index 1aa1504..722d833 100644 --- a/resources/views/admin/data-config/accounts.blade.php +++ b/resources/views/admin/data-config/accounts.blade.php @@ -366,9 +366,21 @@ $roleSelectConfig = [ * - +
+ + +
diff --git a/resources/views/admin/products/edit.blade.php b/resources/views/admin/products/edit.blade.php index cb25a54..6bae50f 100644 --- a/resources/views/admin/products/edit.blade.php +++ b/resources/views/admin/products/edit.blade.php @@ -4,7 +4,7 @@ @php $names = []; foreach(['zh_TW', 'en', 'ja'] as $locale) { - $names[$locale] = $product->translations->where('locale', $locale)->first()?->text ?? ''; + $names[$locale] = $product->translations->where('locale', $locale)->first()?->value ?? ''; } // If zh_TW translation is empty, fallback to product->name if (empty($names['zh_TW'])) { diff --git a/resources/views/admin/products/index.blade.php b/resources/views/admin/products/index.blade.php index c55d92e..3fe27fc 100644 --- a/resources/views/admin/products/index.blade.php +++ b/resources/views/admin/products/index.blade.php @@ -90,7 +90,7 @@ $roleSelectConfig = [ @endif
- {{ $product->name }} + {{ $product->localized_name }}
@php $catName = $product->category->name ?? __('Uncategorized'); @@ -236,7 +236,7 @@ $roleSelectConfig = [

{{ __('Product Details') }}

-

+

+
+ {{ __('Specification') }} +
+