\專案\routes\web.php
,加入儲存訂單的功能:
Route::post('/order/store', 'OrderController@store')->name('order.store');
\專案\resources\views\cart\index.blade.php
:
<h1>我的購物車</h1>
<form action="{{ route('order.store') }}" method="post" id="order-form">
@csrf
<table class="table table-striped">
...略...
@forelse($user->carts as $cart)
...略...
@empty
...略...
@endforelse
...略...
</table>
@if(count($user->carts))
<div class="form-group row">
<label class="col-form-label col-sm-3 text-md-right">收貨地址</label>
<div class="col-sm-7">
<input type="text" class="form-control" name="address" value="{{ $user->address }}">
</div>
<div class="col-sm-2">
<button type="submit" class="btn btn-primary">送出訂單</button>
</div>
</div>
@endif
</form>
首先,我們在前後加入<form></form>
使之成為一個可以送出的表單,表單的方法必須設定為post
,因為屆時要儲存的store
其動詞就是post
(第 2 行)
表單務必加入@csrf
,以產生csrf令牌,否則送出後,會出現419 Page Expired的訊息(第 3 行),詳情可參考:https://learnku.com/docs/laravel/5.8/csrf/3892#csrf-introduction
接著在第 13~23 行加入預設地址及送出鈕,地址預設值由會員的地址產生,前後會先用count()
判斷購物車陣列數量,也就是判斷是否有東西,有才會顯示,避免送出空訂單。
\專案\app\Http\Controllers\OrderController.php
:
use App\Order;
use App\OrderItem;
use App\Product;
use DB;
use Illuminate\Http\Request;
...略...
public function store(Request $request)
{
$user = $request->user();
// 開啟一個資料庫交易
DB::transaction(function () use ($user, $request) {
// 建立一個訂單
$order = new Order;
$order->address = $request->address;
$order->total = 0;
$order->closed = 0;
$order->user_id = $user->id;
$order->save();
$total = 0;
// 計算所有購物車內容的數量及價格
foreach ($request->amount as $product_id => $amount) {
$product = Product::find($product_id);
$item = new OrderItem;
$item->order_id = $order->id;
$item->product_id = $product_id;
$item->amount = $amount;
$item->price = $product->price;
$item->save();
$total += $product->price * $amount;
}
// 更新訂單總金額
$order->total = $total;
$order->update();
// 將下單的商品從購物車中移除
$user->carts()->delete();
});
return redirect()->route('index');
}
DB::transaction();
建立一個資料庫的交易,需完成裡面所有動作,交易才會成立,否則會全部作廢。
function () use ($user, $request) {}
,這是閉包+引用的作法,用來傳參數給閉包的內容使用,詳情可參考:https://www.twblogs.net/a/5b84d7ab2b71775d1cd21703total
(總計)暫時先設成0,等所有購物車項目計算完再來更新這裡的值(切勿相信或使用從模板傳來的金額,因為非常容易被修改)$request->amount
是一個陣列,其索引就是產品編號$product_id
,其值就是購買數量$amount
。product_id
取得該商品資訊,我們主要是為了要取的該商品價錢$order->id
。update()
更新該訂單的總價,關於更新可以參考:https://learnku.com/docs/laravel/5.8/eloquent/3931#updates$user->carts()
即該使用者的所有購物車中的項目,利用delete()
將之全數刪除即可。redirect()
做轉向,暫時回到首頁即可,關於redirect
用法可參考:https://learnku.com/docs/laravel/5.8/helpers/3919#method-redirect