[FIX] 修正多語系升級導致既有環境商品編輯器只剩繁中 Tab

1. 新增回填 migration:將既有機台 settings.languages 補為 ["zh_TW","en","ja"](僅補缺鍵/空值者,已設定者不動,以 DB 更新避免觸發機台事件),使 demo/prod 升級後公司語系聯集維持中英日、商品編輯器照常顯示三 Tab。
2. 商品編輯頁加保險:語系 Tab = 公司機台語系聯集 ∪「此商品已有翻譯的語系」,並依白名單排序,避免日後公司聯集縮減時藏掉既有翻譯而無法編輯。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
sky121113 2026-06-15 09:07:41 +08:00
parent 779c59138f
commit 1f1eb7714e
2 changed files with 56 additions and 0 deletions

View File

@ -0,0 +1,47 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* 回填既有機台的顯示語系:將尚未設定 settings.languages 的機台補為
* ["zh_TW","en","ja"],使既有 demo/prod 行為與現況一致 —— 公司機台語系
* 聯集維持中英日,商品編輯器照常顯示三 Tab機台 B014 LangSet 亦得中英日。
*
* 僅補「缺鍵或空值」者,已設定者不動。直接以 DB 更新避免觸發 Machine 事件
* MQTT 同步等)與全域範圍。
*/
public function up(): void
{
$default = ['zh_TW', 'en', 'ja'];
DB::table('machines')->select('id', 'settings')->orderBy('id')
->chunkById(200, function ($machines) use ($default) {
foreach ($machines as $m) {
$settings = $m->settings ? json_decode($m->settings, true) : [];
if (!is_array($settings)) {
$settings = [];
}
// 已有非空 languages 者跳過
if (!empty($settings['languages']) && is_array($settings['languages'])) {
continue;
}
$settings['languages'] = $default;
DB::table('machines')->where('id', $m->id)->update([
'settings' => json_encode($settings, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
]);
}
});
}
/**
* 不反向移除 languages無法區分回填值與使用者後續手動設定值
* 貿然移除恐誤刪設定,故 down 不動資料。
*/
public function down(): void
{
// no-op
}
};

View File

@ -6,6 +6,15 @@
$localeLabels = config('locales.supported', ['zh_TW' => '繁體中文']);
$locales = \App\Models\System\Company::activeLocalesFor($product->company_id);
// 保險:併入「此商品已有翻譯」的語系,避免公司聯集縮減時藏掉既有翻譯而無法編輯。
$existingLocales = $product->translations->pluck('locale')
->merge($product->specTranslations->pluck('locale'))
->unique()->all();
$order = array_keys($localeLabels); // 依白名單順序穩定排序
$locales = collect($locales)->merge($existingLocales)->unique()
->sortBy(fn ($l) => ($i = array_search($l, $order)) === false ? 999 : $i)
->values()->all();
$names = [];
$specs = [];
foreach ($locales as $locale) {