Công nghệ | Vai trò chính |
---|---|
Laravel | Framework PHP backend chính |
Laravel Breeze | Xác thực người dùng, session |
Blade + Tailwind CSS | Giao diện frontend nhẹ, đẹp |
MySQL (Aiven) | Cơ sở dữ liệu chính |
Eloquent ORM | Xử lý dữ liệu dạng hướng đối tượng |
Middleware | Bảo mật & kiểm soát truy cập |
Sử dụng hệ thống
Quản lý sản phẩm
Quản lý đơn đặt hàng
Quản lý danh mục
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
class Order extends Model
{
protected $fillable = [
'user_id', 'name', 'email', 'phone', 'address',
'order_notes', 'subtotal', 'total', 'payment_method', 'status'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function orderDetails()
{
return $this->hasMany(OrderDetail::class);
}
}
class OrderDetail extends Model
{
protected $fillable = ['order_id', 'product_id', 'quantity', 'price', 'total'];
public function order()
{
return $this->belongsTo(Order::class);
}
public function product()
{
return $this->belongsTo(Product::class);
}
}
class Product extends Model
{
protected $fillable = [
'name', 'slug', 'description', 'price', 'discount_price', 'stock', 'image', 'category_id'
];
public function category()
{
return $this->belongsTo(Category::class);
}
public function cartItems()
{
return $this->hasMany(CartItem::class);
}
public function orderItems()
{
return $this->hasMany(OrderItem::class);
}
public function reviews()
{
return $this->hasMany(Review::class);
}
}
class Category extends Model
{
protected $fillable = ['name', 'slug','image'];
public function products()
{
return $this->hasMany(Product::class);
}
}
class Contact extends Model
{
protected $fillable = [
'name',
'email',
'phone',
'message',
'is_read',
'user_id',
];
/**
* Lấy các phản hồi của admin.
*/
public function replies(): HasMany
{
return $this->hasMany(ContactReply::class);
}
/**
* Lấy thông tin user gửi tin nhắn.
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
class ContactReply extends Model
{
use HasFactory;
protected $fillable = [
'contact_id',
'replied_by_user_id',
'reply',
];
public function contact()
{
return $this->belongsTo(Contact::class);
}
public function repliedBy()
{
return $this->belongsTo(User::class, 'replied_by_user_id');
}
}
### Cart Model
class Cart extends Model
{
protected $fillable = ['user_id', 'subtotal', 'total'];
public function user()
{
return $this->belongsTo(User::class);
}
public function cartItems()
{
return $this->hasMany(CartItem::class);
}
}
class CartItem extends Model
{
protected $fillable = ['cart_id', 'product_id', 'quantity', 'price', 'total'];
public function cart()
{
return $this->belongsTo(Cart::class);
}
public function product()
{
return $this->belongsTo(Product::class);
}
}
public function send(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email',
'phone' => 'required|string|max:20',
'message' => 'required|string|max:1000',
]);
// Lưu thông tin liên hệ vào database
Contact::create([
'name' => $validated['name'],
'email' => $validated['email'],
'phone' => $validated['phone'],
'message' => $validated['message'],
'is_read' => false, // tin nhắn mới gửi sẽ chưa đọc
]);
return redirect()->back()->with('success', 'Cảm ơn bạn đã liên hệ!');
}
public function index(Request $request)
{
$keyword = $request->input('keyword');
$orders = Order::when($keyword, function ($query, $keyword) {
$query->where('name', 'like', "%{$keyword}%");
})
->with('orderDetails.product')
->latest()
->paginate(10);
return view('admin.order', compact('orders'));
}
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required|string|max:50',
'email' => 'required|email|max:150',
'phone' => 'required|string|max:20',
'address' => 'required|string|max:200',
'order_notes' => 'nullable|string|max:1000',
'total' => 'required|numeric|min:0',
'status' => 'required|in:pending,processing,completed,cancelled',
]);
$order = Order::findOrFail($id);
$order->update([
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone,
'address' => $request->address,
'order_notes' => $request->order_notes,
'total' => $request->total,
'status' => $request->status,
]);
return redirect()->route('admin.order')->with('success', 'Order updated successfully.');
}
public function destroy($id)
{
$order = Order::findOrFail($id);
$order->delete();
return redirect()->route('admin.order')->with('success', 'Order deleted successfully.');
}
// Hiển thị danh sách người dùng với tìm kiếm
public function index(Request $request)
{
$keyword = $request->keyword;
$users = User::query()
->when($keyword, function ($query, $keyword) {
return $query->where('email', 'like', '%' . $keyword . '%');
})
->orderBy('id','asc')
->get();
return view('admin.user', compact('users'));
}
// Cập nhật thông tin người dùng
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|max:255|unique:users,email,' . $id,
'phone' => 'nullable|string|max:20',
'address' => 'nullable|string|max:255',
'role' => 'required|in:admin,user',
]);
$user = User::findOrFail($id);
$user->update([
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone,
'address' => $request->address,
'role' => $request->role,
]);
return redirect()->route('admin.user')->with('success', 'Cập nhật người dùng thành công!');
}
// Xóa người dùng
public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return redirect()->route('admin.user')->with('success', 'Xóa người dùng thành công!');
}
Ví dụ:CSRF & XSS Token bảo vệ form (ví dụ: productdetail.blade)
<!-- Form thêm vào giỏ -->
<form action="" method="POST">
@csrf
<input type="hidden" name="product_id" value="">
<div class="product__details__quantity">
<div class="quantity">
<div class="pro-qty">
<input name="quantity" value="1" min="1" type="number">
</div>
</div>
</div>
<button type="submit" class="primary-btn">ADD TO CARD</button>
</form>
📝Đăng ký
🔐Đăng nhập
** 🏡 Trang chủ**
🧑🌾Trang giới thiệu
🥗Trang sản phẩm
🧺Giỏ hàng
🧾Thanh toán (Checkout)
📞Liên hệ
💬Trang phản hồi
📊Dashboard
👥Quản lý người dùng
📦Quản lý đơn hàng
🛍️Quản lý sản phẩm
📂Quản lý danh mục
🔔Thông báo
-🔗 GitHub:https://github.com/PhanThiGiaHan108/Organ
-🥦Readme (web io) :https://phanthigiahan108.github.io/Organ/
-🌐 Public Website: https://organshop-master-uvy5n7.laravel.cloud/
This project is built using Laravel, which is open-sourced software licensed under the MIT license.