[FEAT] 商品詳情支援多行排版並原樣下發 APP
1. 多語系輸入元件 product-locale-tabs 新增 multiline 參數,啟用時改用 textarea(保留換行、可垂直拖曳),名稱欄位維持單行 input。 2. 商品新增/編輯頁的「詳情」欄位改為多行輸入。 3. ProductController store/update 將 specs.* 與 spec 驗證上限由 255 放寬至 2000。 4. 新增 migration 將 products.spec 由 VARCHAR(255) 改為 TEXT,避免較長 zh_TW 詳情被截斷(translations.value 本即 TEXT)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7f700df418
commit
9511ebe71f
@ -272,9 +272,9 @@ class ProductController extends Controller
|
||||
'names.zh_TW' => 'required|string|max:255',
|
||||
'names.*' => 'nullable|string|max:255',
|
||||
'specs' => 'nullable|array',
|
||||
'specs.*' => 'nullable|string|max:255',
|
||||
'specs.*' => 'nullable|string|max:2000',
|
||||
'barcode' => 'nullable|string|max:100',
|
||||
'spec' => 'nullable|string|max:255',
|
||||
'spec' => 'nullable|string|max:2000',
|
||||
'category_id' => 'nullable|exists:product_categories,id',
|
||||
'manufacturer' => 'nullable|string|max:255',
|
||||
'track_limit' => 'required|integer|min:1',
|
||||
@ -374,9 +374,9 @@ class ProductController extends Controller
|
||||
'names.zh_TW' => 'required|string|max:255',
|
||||
'names.*' => 'nullable|string|max:255',
|
||||
'specs' => 'nullable|array',
|
||||
'specs.*' => 'nullable|string|max:255',
|
||||
'specs.*' => 'nullable|string|max:2000',
|
||||
'barcode' => 'nullable|string|max:100',
|
||||
'spec' => 'nullable|string|max:255',
|
||||
'spec' => 'nullable|string|max:2000',
|
||||
'category_id' => 'nullable|exists:product_categories,id',
|
||||
'manufacturer' => 'nullable|string|max:255',
|
||||
'track_limit' => 'required|integer|min:1',
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* 將 products.spec(商品詳情主鏡像值)由 VARCHAR(255) 改為 TEXT,
|
||||
* 以支援多行詳情排版,避免 zh_TW 較長內容被截斷。
|
||||
* (translations.value 本即 TEXT,不需變更。)
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
DB::statement('ALTER TABLE products MODIFY spec TEXT NULL COMMENT \'詳情\'');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::statement('ALTER TABLE products MODIFY spec VARCHAR(255) NULL COMMENT \'規格\'');
|
||||
}
|
||||
};
|
||||
@ -130,7 +130,7 @@
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xl font-black text-slate-800 dark:text-white font-display tracking-tight">{{ __('Details (Multilingual)') }}</h2>
|
||||
</div>
|
||||
<x-product-locale-tabs field="specs" active="activeSpecLocale" :required="false" />
|
||||
<x-product-locale-tabs field="specs" active="activeSpecLocale" :required="false" multiline />
|
||||
</div>
|
||||
|
||||
<!-- Basic Specs Section -->
|
||||
|
||||
@ -165,7 +165,7 @@
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xl font-black text-slate-800 dark:text-white font-display tracking-tight">{{ __('Details (Multilingual)') }}</h2>
|
||||
</div>
|
||||
<x-product-locale-tabs field="specs" active="activeSpecLocale" :required="false" />
|
||||
<x-product-locale-tabs field="specs" active="activeSpecLocale" :required="false" multiline />
|
||||
</div>
|
||||
|
||||
<!-- Basic Specs Section -->
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
'field', // 'names' | 'specs' — 對應 formData[field] 與送出欄位名稱
|
||||
'active', // Alpine 狀態變數名稱,如 'activeNameLocale'
|
||||
'required' => true, // zh_TW 是否必填(名稱必填、規格選填)
|
||||
'multiline' => false, // 是否使用多行 textarea(詳情啟用,名稱維持單行)
|
||||
])
|
||||
|
||||
{{--
|
||||
@ -32,11 +33,20 @@
|
||||
{{-- Inputs:所有語系皆在 DOM(一併送出),僅顯示當前 Tab --}}
|
||||
<template x-for="loc in locales" :key="'{{ $field }}-input-' + loc">
|
||||
<div x-show="{{ $active }} === loc" x-cloak>
|
||||
@if($multiline)
|
||||
{{-- 多行:保留換行排版,原樣傳至 APP --}}
|
||||
<textarea rows="6"
|
||||
:name="'{{ $field }}[' + loc + ']'"
|
||||
x-model="formData.{{ $field }}[loc]"
|
||||
:required="{{ $required ? "loc === 'zh_TW'" : 'false' }}"
|
||||
class="luxury-input !py-3 text-base font-bold shadow-sm w-full whitespace-pre-wrap resize-y leading-relaxed"></textarea>
|
||||
@else
|
||||
<input type="text"
|
||||
:name="'{{ $field }}[' + loc + ']'"
|
||||
x-model="formData.{{ $field }}[loc]"
|
||||
:required="{{ $required ? "loc === 'zh_TW'" : 'false' }}"
|
||||
class="luxury-input !py-3 text-base font-bold shadow-sm w-full">
|
||||
@endif
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user