chore: bypass dns using host ip
Some checks failed
Koori-ERP-Deploy / auto-deploy (push) Failing after 12s
Some checks failed
Koori-ERP-Deploy / auto-deploy (push) Failing after 12s
This commit is contained in:
@@ -10,6 +10,11 @@ jobs:
|
||||
steps:
|
||||
- name: 1. Checkout Code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# --- 關鍵:直接指定 Gitea 的伺服器網址為 IP ---
|
||||
github-server-url: http://192.168.0.103:3000
|
||||
repository: ${{ gitea.repository }}
|
||||
# ------------------------------------------
|
||||
|
||||
- name: 2. Create .env from Secrets
|
||||
run: echo "${{ secrets.DOT_ENV }}" > .env
|
||||
|
||||
@@ -256,4 +256,24 @@ class PurchaseOrderController extends Controller
|
||||
return back()->withErrors(['error' => '更新失敗:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$order = PurchaseOrder::findOrFail($id);
|
||||
|
||||
// Delete associated items first (due to FK constraints if not cascade)
|
||||
$order->items()->delete();
|
||||
$order->delete();
|
||||
|
||||
DB::commit();
|
||||
|
||||
return redirect()->route('purchase-orders.index')->with('success', '採購單已刪除');
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return back()->withErrors(['error' => '刪除失敗:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
import { Edit, Eye } from "lucide-react";
|
||||
import { Edit, Eye, Trash2 } from "lucide-react";
|
||||
import { Button } from "@/Components/ui/button";
|
||||
import { Link } from "@inertiajs/react";
|
||||
import { Link, useForm } from "@inertiajs/react";
|
||||
import type { PurchaseOrder } from "@/types/purchase-order";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export function PurchaseOrderActions({
|
||||
order,
|
||||
}: { order: PurchaseOrder }) {
|
||||
const { delete: destroy, processing } = useForm({});
|
||||
|
||||
const handleDelete = () => {
|
||||
if (confirm(`確定要刪除採購單 ${order.poNumber} 嗎?`)) {
|
||||
// @ts-ignore
|
||||
destroy(route('purchase-orders.destroy', order.id), {
|
||||
onSuccess: () => toast.success("採購單已成功刪除"),
|
||||
onError: (errors: any) => toast.error(errors.error || "刪除過程中發生錯誤"),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex justify-end gap-2">
|
||||
<Link href={`/purchase-orders/${order.id}`}>
|
||||
@@ -28,6 +41,16 @@ export function PurchaseOrderActions({
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="hover:bg-red-50 hover:text-red-600 hover:border-red-200 text-gray-500 h-8 w-8 p-0 transition-colors"
|
||||
title="刪除採購單"
|
||||
onClick={handleDelete}
|
||||
disabled={processing}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -225,56 +225,56 @@ export default function CreatePurchaseOrder({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 步驟二:品項明細 */}
|
||||
<div className={`bg-white rounded-lg border shadow-sm overflow-hidden transition-all duration-300 ${!hasSupplier ? 'opacity-60 saturate-50' : ''}`}>
|
||||
<div className="p-6 bg-gray-50/50 border-b flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-primary text-white flex items-center justify-center font-bold">2</div>
|
||||
<h2 className="text-lg font-bold">採購商品明細</h2>
|
||||
</div>
|
||||
<Button
|
||||
onClick={addItem}
|
||||
disabled={!hasSupplier || isOrderSent}
|
||||
className="button-filled-primary h-10 gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" /> 新增一個品項
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="p-8">
|
||||
{!hasSupplier && (
|
||||
<Alert className="mb-6 bg-amber-50 border-amber-200 text-amber-800">
|
||||
<Info className="h-4 w-4 text-amber-600" />
|
||||
<AlertDescription>
|
||||
請先在步驟一選擇「供應商」,才能從該供應商的常用項目中選取商品。
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<PurchaseOrderItemsTable
|
||||
items={items}
|
||||
supplier={selectedSupplier}
|
||||
isReadOnly={isOrderSent}
|
||||
isDisabled={!hasSupplier}
|
||||
onRemoveItem={removeItem}
|
||||
onItemChange={updateItem}
|
||||
/>
|
||||
|
||||
{hasSupplier && items.length > 0 && (
|
||||
<div className="mt-8 flex justify-end">
|
||||
<div className="bg-primary/5 px-8 py-5 rounded-xl border border-primary/10 inline-flex flex-col items-end min-w-[240px]">
|
||||
<span className="text-sm text-gray-500 font-medium mb-1">採購預估總額</span>
|
||||
<span className="text-3xl font-black text-primary">{formatCurrency(totalAmount)}</span>
|
||||
</div>
|
||||
{/* 步驟二:品項明細 */}
|
||||
<div className={`bg-white rounded-lg border shadow-sm overflow-hidden transition-all duration-300 ${!hasSupplier ? 'opacity-60 saturate-50' : ''}`}>
|
||||
<div className="p-6 bg-gray-50/50 border-b flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-primary text-white flex items-center justify-center font-bold">2</div>
|
||||
<h2 className="text-lg font-bold">採購商品明細</h2>
|
||||
</div>
|
||||
)}
|
||||
<Button
|
||||
onClick={addItem}
|
||||
disabled={!hasSupplier || isOrderSent}
|
||||
className="button-filled-primary h-10 gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" /> 新增一個品項
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="p-8">
|
||||
{!hasSupplier && (
|
||||
<Alert className="mb-6 bg-amber-50 border-amber-200 text-amber-800">
|
||||
<Info className="h-4 w-4 text-amber-600" />
|
||||
<AlertDescription>
|
||||
請先在步驟一選擇「供應商」,才能從該供應商的常用項目中選取商品。
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<PurchaseOrderItemsTable
|
||||
items={items}
|
||||
supplier={selectedSupplier}
|
||||
isReadOnly={isOrderSent}
|
||||
isDisabled={!hasSupplier}
|
||||
onRemoveItem={removeItem}
|
||||
onItemChange={updateItem}
|
||||
/>
|
||||
|
||||
{hasSupplier && items.length > 0 && (
|
||||
<div className="mt-8 flex justify-end">
|
||||
<div className="bg-primary/5 px-8 py-5 rounded-xl border border-primary/10 inline-flex flex-col items-end min-w-[240px]">
|
||||
<span className="text-sm text-gray-500 font-medium mb-1">採購預估總額</span>
|
||||
<span className="text-3xl font-black text-primary">{formatCurrency(totalAmount)}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 底部按鈕 */}
|
||||
<div className="flex items-center justify-end gap-4 py-4">
|
||||
<div className="flex items-center justify-end gap-4 py-8 border-t border-gray-100 mt-8">
|
||||
<Link href="/purchase-orders">
|
||||
<Button variant="ghost" className="h-12 px-8 text-gray-500 hover:text-gray-700">
|
||||
取消
|
||||
|
||||
@@ -56,6 +56,7 @@ Route::post('/purchase-orders', [PurchaseOrderController::class, 'store'])->name
|
||||
Route::get('/purchase-orders/{id}', [PurchaseOrderController::class, 'show'])->name('purchase-orders.show');
|
||||
Route::get('/purchase-orders/{id}/edit', [PurchaseOrderController::class, 'edit'])->name('purchase-orders.edit');
|
||||
Route::put('/purchase-orders/{id}', [PurchaseOrderController::class, 'update'])->name('purchase-orders.update');
|
||||
Route::delete('/purchase-orders/{id}', [PurchaseOrderController::class, 'destroy'])->name('purchase-orders.destroy');
|
||||
|
||||
// 廠商管理
|
||||
Route::get('/vendors', [VendorController::class, 'index'])->name('vendors.index');
|
||||
|
||||
Reference in New Issue
Block a user