From 24aed44cd3fdc5bc1ca81c9e5bf2c88e709ab3c7 Mon Sep 17 00:00:00 2001 From: sky121113 Date: Thu, 5 Feb 2026 16:15:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(product):=20=E6=81=A2=E5=BE=A9=E4=B8=A6?= =?UTF-8?q?=E5=AF=A6=E4=BD=9C=E5=95=86=E5=93=81=E8=B5=B7=E5=81=9C=E7=94=A8?= =?UTF-8?q?=E7=8B=80=E6=85=8B=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=8C=85=E5=90=AB?= =?UTF-8?q?=E8=A1=A8=E5=96=AE=E9=96=8B=E9=97=9C=E8=88=87=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E9=A1=AF=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Inventory/Controllers/ProductController.php | 16 ++++++++++++---- app/Modules/Inventory/Models/Product.php | 2 ++ resources/js/Components/Product/ProductForm.tsx | 12 ++++++++++++ resources/js/Components/Product/ProductTable.tsx | 8 ++++++++ resources/js/Pages/Product/Index.tsx | 1 + 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/app/Modules/Inventory/Controllers/ProductController.php b/app/Modules/Inventory/Controllers/ProductController.php index 2bdca4e..7b8ee91 100644 --- a/app/Modules/Inventory/Controllers/ProductController.php +++ b/app/Modules/Inventory/Controllers/ProductController.php @@ -152,6 +152,7 @@ class ProductController extends Controller 'price' => (float) $product->price, 'member_price' => (float) $product->member_price, 'wholesale_price' => (float) $product->wholesale_price, + 'is_active' => (bool) $product->is_active, ] ]); } @@ -188,14 +189,17 @@ class ProductController extends Controller 'price' => 'nullable|numeric|min:0', 'member_price' => 'nullable|numeric|min:0', 'wholesale_price' => 'nullable|numeric|min:0', + 'is_active' => 'boolean', ]); - $validated['is_active'] = true; - if (empty($validated['code'])) { $validated['code'] = $this->generateRandomCode(); } + if (!isset($validated['is_active'])) { + $validated['is_active'] = true; + } + $product = Product::create($validated); return redirect()->route('products.index')->with('success', '商品已建立'); @@ -224,6 +228,7 @@ class ProductController extends Controller 'price' => (float) $product->price, 'member_price' => (float) $product->member_price, 'wholesale_price' => (float) $product->wholesale_price, + 'is_active' => (bool) $product->is_active, ], 'categories' => Category::where('is_active', true)->get()->map(fn($c) => (object)['id' => $c->id, 'name' => $c->name]), 'units' => Unit::all()->map(fn($u) => (object)['id' => (string) $u->id, 'name' => $u->name, 'code' => $u->code]), @@ -251,14 +256,17 @@ class ProductController extends Controller 'price' => 'nullable|numeric|min:0', 'member_price' => 'nullable|numeric|min:0', 'wholesale_price' => 'nullable|numeric|min:0', + 'is_active' => 'boolean', ]); - $validated['is_active'] = true; - if (empty($validated['code'])) { $validated['code'] = $this->generateRandomCode(); } + if (!isset($validated['is_active'])) { + $validated['is_active'] = true; + } + $product->update($validated); if ($request->input('from') === 'show') { diff --git a/app/Modules/Inventory/Models/Product.php b/app/Modules/Inventory/Models/Product.php index b8a018e..e243aba 100644 --- a/app/Modules/Inventory/Models/Product.php +++ b/app/Modules/Inventory/Models/Product.php @@ -31,10 +31,12 @@ class Product extends Model 'price', 'member_price', 'wholesale_price', + 'is_active', ]; protected $casts = [ 'conversion_rate' => 'decimal:4', + 'is_active' => 'boolean', ]; /** diff --git a/resources/js/Components/Product/ProductForm.tsx b/resources/js/Components/Product/ProductForm.tsx index a30cef4..816198a 100644 --- a/resources/js/Components/Product/ProductForm.tsx +++ b/resources/js/Components/Product/ProductForm.tsx @@ -4,6 +4,7 @@ import { Input } from "@/Components/ui/input"; import { Label } from "@/Components/ui/label"; import { Textarea } from "@/Components/ui/textarea"; import { SearchableSelect } from "@/Components/ui/searchable-select"; +import { Switch } from "@/Components/ui/switch"; import { useForm } from "@inertiajs/react"; import { toast } from "sonner"; import type { Category, Product } from "@/Pages/Product/Index"; @@ -41,6 +42,7 @@ export default function ProductForm({ price: initialData?.price?.toString() || "", member_price: initialData?.member_price?.toString() || "", wholesale_price: initialData?.wholesale_price?.toString() || "", + is_active: initialData?.is_active ?? true, }); const handleSubmit = (e: React.FormEvent) => { @@ -79,6 +81,16 @@ export default function ProductForm({

基本資訊

+
+ + setData("is_active", checked)} + /> +
diff --git a/resources/js/Components/Product/ProductTable.tsx b/resources/js/Components/Product/ProductTable.tsx index 1e4bc9c..d7d855b 100644 --- a/resources/js/Components/Product/ProductTable.tsx +++ b/resources/js/Components/Product/ProductTable.tsx @@ -98,6 +98,7 @@ export default function ProductTable({ 換算率 規格 儲位 + 狀態 操作 @@ -160,6 +161,13 @@ export default function ProductTable({ {product.location || '-'} + + {product.is_active ? ( + 啟用 + ) : ( + 停用 + )} +
diff --git a/resources/js/Pages/Product/Index.tsx b/resources/js/Pages/Product/Index.tsx index 33708b5..e8ce9ad 100644 --- a/resources/js/Pages/Product/Index.tsx +++ b/resources/js/Pages/Product/Index.tsx @@ -43,6 +43,7 @@ export interface Product { price?: number; member_price?: number; wholesale_price?: number; + is_active?: boolean; } interface PageProps {