feat: 標準化全系統數值輸入欄位與擴充商品價格功能
1. UI 標準化: - 針對全系統數值輸入欄位統一加上 step='any' 以支援小數點。 - 表格形式 (Table) 的數值輸入欄位統一加上 text-right 靠右對齊。 - 修正 Components 與 Pages 中所有涉及金額與數量的輸入框。 2. 功能擴充與修正: - 擴充 Product 模型與相關 Dialog 以支援多種價格設定。 - 修正 Inventory/GoodsReceipt/Create.tsx 未使用的變數錯誤。 - 優化庫存相關頁面的 UI 一致性。 3. 其他: - 更新相關的 Type 定義與 Controller 邏輯。
This commit is contained in:
@@ -47,6 +47,10 @@ export default function ProductDialog({
|
||||
conversion_rate: "",
|
||||
purchase_unit_id: "",
|
||||
location: "",
|
||||
cost_price: "",
|
||||
price: "",
|
||||
member_price: "",
|
||||
wholesale_price: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -65,6 +69,10 @@ export default function ProductDialog({
|
||||
conversion_rate: product.conversionRate ? product.conversionRate.toString() : "",
|
||||
purchase_unit_id: product.purchaseUnitId?.toString() || "",
|
||||
location: product.location || "",
|
||||
cost_price: product.cost_price?.toString() || "",
|
||||
price: product.price?.toString() || "",
|
||||
member_price: product.member_price?.toString() || "",
|
||||
wholesale_price: product.wholesale_price?.toString() || "",
|
||||
});
|
||||
} else {
|
||||
reset();
|
||||
@@ -235,6 +243,72 @@ export default function ProductDialog({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 價格設定區塊 */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-medium border-b pb-2">價格設定</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="cost_price">成本價</Label>
|
||||
<Input
|
||||
id="cost_price"
|
||||
type="number"
|
||||
min="0"
|
||||
step="any"
|
||||
value={data.cost_price}
|
||||
onChange={(e) => setData("cost_price", e.target.value)}
|
||||
placeholder="0"
|
||||
className={errors.cost_price ? "border-red-500" : ""}
|
||||
/>
|
||||
{errors.cost_price && <p className="text-sm text-red-500">{errors.cost_price}</p>}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="price">售價</Label>
|
||||
<Input
|
||||
id="price"
|
||||
type="number"
|
||||
min="0"
|
||||
step="any"
|
||||
value={data.price}
|
||||
onChange={(e) => setData("price", e.target.value)}
|
||||
placeholder="0"
|
||||
className={errors.price ? "border-red-500" : ""}
|
||||
/>
|
||||
{errors.price && <p className="text-sm text-red-500">{errors.price}</p>}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="member_price">會員價</Label>
|
||||
<Input
|
||||
id="member_price"
|
||||
type="number"
|
||||
min="0"
|
||||
step="any"
|
||||
value={data.member_price}
|
||||
onChange={(e) => setData("member_price", e.target.value)}
|
||||
placeholder="0"
|
||||
className={errors.member_price ? "border-red-500" : ""}
|
||||
/>
|
||||
{errors.member_price && <p className="text-sm text-red-500">{errors.member_price}</p>}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="wholesale_price">批發價</Label>
|
||||
<Input
|
||||
id="wholesale_price"
|
||||
type="number"
|
||||
min="0"
|
||||
step="any"
|
||||
value={data.wholesale_price}
|
||||
onChange={(e) => setData("wholesale_price", e.target.value)}
|
||||
placeholder="0"
|
||||
className={errors.wholesale_price ? "border-red-500" : ""}
|
||||
/>
|
||||
{errors.wholesale_price && <p className="text-sm text-red-500">{errors.wholesale_price}</p>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 單位設定區塊 */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-medium border-b pb-2">單位設定</h3>
|
||||
@@ -278,7 +352,7 @@ export default function ProductDialog({
|
||||
<Input
|
||||
id="conversion_rate"
|
||||
type="number"
|
||||
step="0.0001"
|
||||
step="any"
|
||||
value={data.conversion_rate}
|
||||
onChange={(e) => setData("conversion_rate", e.target.value)}
|
||||
placeholder={data.large_unit_id && data.base_unit_id ? `1 ${units.find(u => u.id.toString() === data.large_unit_id)?.name} = ? ${units.find(u => u.id.toString() === data.base_unit_id)?.name}` : ""}
|
||||
|
||||
Reference in New Issue
Block a user