Thao tác hiển thị Danh sách, Thêm, Xóa, Sửa trong Laravel 8.
Trang 1PHẦN 3: CRUD CODE (CONTROLLERS & VIEWS) Lab 1: CRUD Loại sản phẩm
Đã xây dựng ở Phần 1 và Phần 2
Link tải các phần: https://bit.ly/laravel_shoponline
Lab 2: CRUD Sản phẩm
Nội dung tập tin Controller: app/Http/Controlles/SanPhamController.php
Hình ảnh upload xem trong Phần tiếp theo (Phần 4)
<?php
namespace App\Http\Controllers;
use App\Models\SanPham;
use App\Models\LoaiSanPham;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class SanPhamController extends Controller
{
public function construct()
{
$this->middleware('auth');
}
public function getDanhSach()
{
$sanpham SanPham::all();
return view('sanpham.danhsach', compact('sanpham'));
}
public function getThem()
{
$loaisanpham LoaiSanPham::all();
return view('sanpham.them', compact('loaisanpham'));
}
public function postThem(Request $request)
{
$this->validate($request, [
'loaisanpham_id' => 'required'],
'tensanpham' => 'required', 'max:255', 'unique:sanpham'],
'soluong' => 'required', 'numeric'],
'dongia' => 'required', 'numeric'],
// 'hinhanh' => ['image', 'max:2048'],
]);
$orm new SanPham();
$orm->loaisanpham_id = $request->loaisanpham_id;
$orm->tensanpham = $request->tensanpham;
Biên soạn: Nguyễn Hoàng Tùng Giấy phép CC BY-NC 4.0 Quốc tế
Trang 2$orm->tensanpham_slug = Str::slug($request->tensanpham, '-');
$orm->soluong = $request->soluong;
$orm->dongia = $request->dongia;
if($request->hasFile('hinhanh')) $orm->hinhanh = $request->hinhanh;
$orm->motasanpham = $request->motasanpham;
$orm->save();
return redirect()->route('sanpham');
}
public function getSua($id)
{
$sanpham SanPham::find($id);
$loaisanpham LoaiSanPham::all();
return view('sanpham.sua', compact('sanpham', 'loaisanpham'));
}
public function postSua(Request $request, $id)
{
$this->validate($request, [
'loaisanpham_id' => 'required'],
'tensanpham' => 'required', 'max:255', 'unique:sanpham,tensanpham,' $id],
'soluong' => 'required', 'numeric'],
'dongia' => 'required', 'numeric'],
// 'hinhanh' => ['image', 'max:2048'],
]);
$orm SanPham::find($id);
$orm->loaisanpham_id = $request->loaisanpham_id;
$orm->tensanpham = $request->tensanpham;
$orm->tensanpham_slug = Str::slug($request->tensanpham, '-');
$orm->soluong = $request->soluong;
$orm->dongia = $request->dongia;
if($request->hasFile('hinhanh')) $orm->hinhanh = $request->hinhanh;
$orm->motasanpham = $request->motasanpham;
$orm->save();
return redirect()->route('sanpham');
}
public function getXoa($id)
{
$orm SanPham::find($id);
$orm->delete();
return redirect()->route('sanpham');
}
}
Nội dung view Danh sách: resources/views/sanpham/danhsach.blade.php
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-header">Sản phẩm</div>
<div class="card-body table-responsive">
<p>
<a href="{{ route('sanpham.them') }}" class="btn btn-info"><i class="fal fa-plus"></i> Thêm mới</a>
</p>
<table class="table table-bordered table-hover table-sm mb-0">
Trang 3<thead>
<tr>
<th width="5%"> </th>
<th width="10%">Hình ảnh</th>
<th width="20%">Loại sản phẩm</th>
<th width="40%">Tên sản phẩm</th>
<th width="5%">SL</th>
<th width="10%">Đơn giá</th>
<th width="5%">Sửa</th>
<th width="5%">Xóa</th>
</tr>
</thead>
<tbody>
@foreach($sanpham as $value)
<tr>
<td>{{ $loop->iteration }}</td>
<td class="text-center"><img src="{{ env('APP_URL') '/storage/app/' $value->hinhanh }}" width="80" /></td>
<td>{{ $value->LoaiSanPham->tenloai }}</td>
<td>{{ $value->tensanpham }}</td>
<td class="text-end">{{ $value->soluong }}</td>
<td class="text-end">{{ number_format($value->dongia) }}</td>
<td class="text-center"><a href="{{ route('sanpham.sua', ['id' => $value->id]) }}"><i class="fal fa-edit"></i></a></td>
<td class="text-center"><a href="{{ route('sanpham.xoa', ['id' => $value->id]) }}"><i class="fal fa-trash-alt text-danger"></i></a></td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
Nội dung view Sửa: resources/views/sanpham/sua.blade.php
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-header">Sửa sản phẩm</div>
<div class="card-body">
<form action="{{ route('sanpham.sua', ['id' => $sanpham->id]) }}" method="post">
@csrf
<div class="mb-3">
<label class="form-label" for="loaisanpham_id">Loại sản phẩm</label>
<select class="form-select @error('loaisanpham_id') is-invalid @enderror" id="loaisanpham_id" name="loaisanpham_id" required>
<option value=""> Chọn loại </option>
@foreach($loaisanpham as $value)
<option value="{{ $value->id }}" {{ ($sanpham->loaisanpham_id == $value->id) ? 'selected' : '' }}>{{ $value->tenloai }}</option>
@endforeach
</select>
@error('loaisanpham_id')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="tensanpham">Tên sản phẩm</label>
<input type="text" class="form-control @error('tensanpham') is-invalid @enderror" id="tensanpham" name="tensanpham"value="{{ $sanpham->tensanpham }}" required />
@error('tensanpham')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
Trang 4</div>
<div class="mb-3">
<label class="form-label" for="soluong">Số lượng</label>
<input type="number" min="0" class="form-control @error('soluong') is-invalid @enderror" id="soluong"name="soluong"value="{{ $sanpham->soluong }}"required />
@error('soluong')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="dongia">Đơn giá</label>
<input type="number" min="0" class="form-control @error('dongia') is-invalid @enderror" id="dongia" name="dongia" value="{{ $sanpham->dongia }}" required />
@error('dongia')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="hinhanh">Hình ảnh sản phẩm</label>
@if(!empty($sanpham->hinhanh))
<img class="d-block rounded" src="{{ env('APP_URL') '/storage/app/' $sanpham->hinhanh }}" width="100" />
<span class="d-block small text-danger">Bỏ trống nếu muốn giữ nguyên ảnh cũ.</span>
@endif
<input type="file" class="form-control @error('hinhanh') is-invalid @enderror" id="hinhanh" name="hinhanh" value="{{ $sanpham->hinhanh }}" />
@error('hinhanh')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="motasanpham">Mô tả sản phẩm</label>
<textarea class="form-control" id="motasanpham" name="motasanpham">{{ $sanpham->motasanpham }}</textarea>
</div>
<button type="submit" class="btn btn-primary"><i class="fal fa-save"></i> Cập nhật</button>
</form>
</div>
</div>
@endsection
Nội dung view Thêm: resources/views/sanpham/them.blade.php
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-header">Thêm sản phẩm</div>
<div class="card-body">
<form action="{{ route('sanpham.them') }}" method="post">
@csrf
<div class="mb-3">
<label class="form-label" for="loaisanpham_id">Loại sản phẩm</label>
<select class="form-select @error('loaisanpham_id') is-invalid @enderror" id="loaisanpham_id" name="loaisanpham_id" required>
<option value=""> Chọn loại </option>
@foreach($loaisanpham as $value)
<option value="{{ $value->id }}">{{ $value->tenloai }}</option>
@endforeach
</select>
@error('loaisanpham_id')
Trang 5<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="tensanpham">Tên sản phẩm</label>
<input type="text" class="form-control @error('tensanpham') is-invalid @enderror" id="tensanpham" name="tensanpham"value="{{ old('tensanpham') }}" required/>
@error('tensanpham')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="soluong">Số lượng</label>
<input type="number" min="0" class="form-control @error('soluong') is-invalid @enderror" id="soluong" name="soluong" value="{{ old('soluong') }}" required />
@error('soluong')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="dongia">Đơn giá</label>
<input type="number" min="0" class="form-control @error('dongia') is-invalid @enderror" id="dongia" name="dongia" value="{{ old('dongia') }}" required />
@error('dongia')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="hinhanh">Hình ảnh sản phẩm</label>
<input type="file" class="form-control @error('hinhanh') is-invalid @enderror" id="hinhanh" name="hinhanh" value="{{ old('hinhanh') }}" />
@error('hinhanh')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="motasanpham">Mô tả sản phẩm</label>
<textarea class="form-control" id="motasanpham" name="motasanpham">{{ old('motasanpham') }}</textarea>
</div>
<button type="submit" class="btn btn-primary"><i class="fal fa-save"></i> Thêm vào CSDL</button>
</form>
</div>
</div>
@endsection
Lab 3: CRUD Đơn hàng
Trạng thái đơn hàng:
1 Đang xác nhận / Đã xác nhận Trạng thái lúc gọi điện cho khách để xác nhận lại đơn hàng
Trang 62 Đã hủy Không liên lạc được với khách hàng hoặc khách hàng tự hủy đơn khi ở trạng thái Đang xác nhận
3 Đang đóng gói sản phẩm Trạng thái lúc in và đóng gói hàng để gửi cho hãng vận chuyển
4 Chờ đi nhận / Đang đi nhận / Đã nhận hàng Chờ đi nhận khi shop gửi sang hãng vận chuyển; Đang đi nhận, Đã nhận hàng hãng vận chuyển
sẽ cập nhật trạng thái này khi đi và nhận hàng gửi từ shop
6 Thất bại Nếu hãng vận chuyển gửi hàng đến khách hàng nhưng vì một lý do nào đó khách không nhận hoặc không gửi được cho khách, hãng sẽ cập nhật về trạng thái này
trạng thái này và mang hàng về cho shop
Nguồn tham khảo: Tiki (Tìm kiếm – Tiết kiệm), Lazada, Shoppe
Nội dung tập tin Controller: app/Http/Controlles/DonHangController.php
<?php
namespace App\Http\Controllers;
use App\Models\DonHang;
use App\Models\DonHang_ChiTiet;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
class DonHangController extends Controller
{
public function construct()
{
$this->middleware('auth');
}
public function getDanhSach()
{
$donhang DonHang::orderBy('created_at', 'desc')->get();
return view('donhang.danhsach', compact('donhang'));
}
public function getSua($id)
{
$donhang DonHang::find($id);
return view('donhang.sua', compact('donhang'));
}
Trang 7
public function postSua(Request $request, $id)
{
$this->validate($request, [
'dienthoai' => 'required', 'max:20'],
'diachi' => 'required', 'max:255'],
'tinhtrang' => 'required'],
]);
$orm DonHang::find($id);
$orm->dienthoaigiaohang = $request->dienthoai;
$orm->diachigiaohang = $request->diachi;
$orm->tinhtrang = $request->tinhtrang;
$orm->save();
return redirect()->route('donhang');
}
public function getXoa($id)
{
$orm DonHang::find($id);
$orm->delete();
$chitiet DonHang_ChiTiet::where('donhang_id', $orm->id)->first();
$chitiet->delete();
return redirect()->route('donhang');
}
}
Nội dung view Danh sách: resources/views/donhang/danhsach.blade.php
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-header">Đơn hàng</div>
<div class="card-body table-responsive">
<p><a href="{{ route('donhang.them') }}" class="btn btn-info"><i class="fal fa-plus"></i> Thêm mới</a></p>
<table class="table table-bordered table-hover table-sm mb-0">
<thead>
<tr>
<th width="5%"> </th>
<th width="15%">Khách hàng</th>
<th width="45%">Thông tin giao hàng</th>
<th width="15%">Ngày đặt</th>
<th width="10%">Tình trạng</th>
<th width="5%">Sửa</th>
<th width="5%">Xóa</th>
</tr>
</thead>
<tbody>
@foreach($donhang as $value)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $value->NguoiDung->name }}</td>
<td>
<span class="d-block">Điện thoại: <strong>{{ $value->dienthoaigiaohang }}</strong></span>
<span class="d-block">Địa chỉ giao: <strong>{{ $value->diachigiaohang }}</strong></span>
<span class="d-block">Sản phẩm:</span>
<table class="table table-bordered table-hover table-sm mb-0">
<thead>
Trang 8<tr>
<th width="5%"> </th>
<th>Sản phẩm</th>
<th width="5%">SL</th>
<th width="15%">Đơn giá</th>
<th width="20%">Thành tiền</th>
</tr>
</thead>
<tbody>
@php $tongtien = 0; @endphp
@foreach($value->DonHang_ChiTiet as $chitiet)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $chitiet->SanPham->tensanpham }}</td>
<td>{{ $chitiet->soluongban }}</td>
<td class="text-end">{{ number_format($chitiet->dongiaban) }}<sup><u>đ</u></sup></td>
<td class="text-end">{{ number_format($chitiet->soluongban * $chitiet->dongiaban) }}<sup><u>đ</u></sup></td>
</tr>
@php $tongtien += $chitiet->soluongban * $chitiet->dongiaban; @endphp
@endforeach
<tr>
<td colspan="4">Tổng tiền sản phẩm:</td>
<td class="text-end"><strong>{{ number_format($tongtien) }}</strong><sup><u>đ</u></sup></td>
</tr>
</tbody>
</table>
</td>
<td>{{ $value->created_at->format('d/m/Y H:i:s') }}</td>
<td>{{ $value->tinhtrang }}</td>
<td class="text-center"><a href="{{ route('donhang.sua', ['id' => $value->id]) }}"><i class="fal fa-edit"></i></a></td>
<td class="text-center"><a href="{{ route('donhang.xoa', ['id' => $value->id]) }}"><i class="fal fa-trash-alt text-danger"></i></a></td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
Nội dung view Sửa: resources/views/donhang/sua.blade.php
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-header">Chỉnh sửa đơn hàng</div>
<div class="card-body">
<form action="{{ route('donhang.sua', ['id' => $donhang->id]) }}" method="post">
@csrf
<div class="mb-3">
<label class="form-label" for="user_id">Khách hàng</label>
<input type="text" class="form-control" id="user" name="user_id" value="{{ $donhang->NguoiDung->name }}" disabled required />
</div>
<div class="mb-3">
<label class="form-label" for="dienthoai">Điện thoại giao hàng</label>
<input type="text" class="form-control @error('dienthoai') is-invalid @enderror" id="dienthoai" name="dienthoai" value="{{ $donhang->dienthoaigiaohang }}" required/>
@error('dienthoai')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
Trang 9</div>
<div class="mb-3">
<label class="form-label" for="diachi">Địa chỉ giao hàng</label>
<input type="text" class="form-control @error('diachi') is-invalid @enderror" id="diachi" name="diachi" value="{{ $donhang->diachigiaohang }}" required />
@error('diachi')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<div class="mb-3">
<label class="form-label" for="tinhtrang">Tình trạng đơn hàng</label>
<select class="form-select @error('tinhtrang') is-invalid @enderror" id="tinhtrang" name="tinhtrang" required>
<option value=""> Chọn </option>
<option value="0" {{ ($donhang->tinhtrang == 0) ? 'selected' : '' }}>Mới</option>
<option value="1" {{ ($donhang->tinhtrang == 1) ? 'selected' : '' }}>Đang xác nhận</option>
<option value="2" {{ ($donhang->tinhtrang == 2) ? 'selected' : '' }}>Đã hủy</option>
<option value="3" {{ ($donhang->tinhtrang == 3) ? 'selected' : '' }}>Đang đóng gói</option>
<option value="4" {{ ($donhang->tinhtrang == 4) ? 'selected' : '' }}>Đang đi nhận</option>
<option value="5" {{ ($donhang->tinhtrang == 5) ? 'selected' : '' }}>Đang chuyển</option>
<option value="6" {{ ($donhang->tinhtrang == 6) ? 'selected' : '' }}>Thất bại</option>
<option value="7" {{ ($donhang->tinhtrang == 7) ? 'selected' : '' }}>Đang chuyển hoàn</option>
<option value="8" {{ ($donhang->tinhtrang == 8) ? 'selected' : '' }}>Đã chuyển hoàn</option>
<option value="9" {{ ($donhang->tinhtrang == 9) ? 'selected' : '' }}>Thành công</option>
</select>
@error('tinhtrang')
<div class="invalid-feedback"><strong>{{ $message }}</strong></div>
@enderror
</div>
<button type="submit" class="btn btn-primary"><i class="fal fa-save"></i> Cập nhật</button>
</form>
</div>
</div>
@endsection
Lab 4: CRUD Đơn hàng chi tiết
Nội dung tập tin Controller: app/Http/Controlles/DonHangChiTietController.php
<?php
namespace App\Http\Controllers;
use App\Models\DonHang_ChiTiet;
use Illuminate\Http\Request;
class DonHangChiTietController extends Controller
{
public function construct()
{
$this->middleware('auth');
}
public function getDanhSach()
{
$donhang_chitiet DonHang_ChiTiet::all();
return view('donhang_chitiet.danhsach', compact('donhang_chitiet'));
}
}
Trang 10Nội dung view Danh sách: resources/views/donhang_chitiet/danhsach.blade.php
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-header">Đơn hàng chi tiết</div>
<div class="card-body table-responsive">
<table class="table table-bordered table-hover table-sm mb-0">
<thead>
<tr>
<th width="5%"> </th>
<th width="10%">Mã đơn hàng</th>
<th width="45%">Tên sản phẩm</th>
<th width="10%">SL</th>
<th width="15%">Đơn giá bán</th>
<th width="15%">Thành tiền</th>
</tr>
</thead>
<tbody>
@foreach($donhang_chitiet as $value)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $value->DonHang->id }}</td>
<td>{{ $value->SanPham->tensanpham }}</td>
<td class="text-end">{{ $value->soluongban }}</td>
<td class="text-end">{{ number_format($value->dongiaban) }}<sup><u>đ</u></sup></td>
<td class="text-end">{{ number_format($value->soluongban * $value->dongiaban) }}<sup><u>đ</u></sup></td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
Lab 5: CRUD Tài khoản người dùng
Nội dung tập tin Controller: app/Http/Controlles/UserController.php
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class UserController extends Controller
{
public function construct()
{
$this->middleware('auth');
}
public function getDanhSach()