這個是永康社大的作品,也歡迎大家來上課或購買
https://laihao.vaserver.com/admin/good_design
這是含有前端+資料庫+後端
當然也有 route的地方
因為怕大家動到CRUD 所以只有解釋 截圖畫面的部分,就是沒有連結

–
這個也有另一個列表樣式,
因為怕大家動到CRUD所以先反灰,
不過大家還是可以看到原始的按鈕的樣子
https://laihao.vaserver.com/admin/products
後端 程式碼
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Models\Product;
use App\Http\Controllers\Controller;
use App\Notifications\ProductDelivery;
use App\Imports\ProductsImport;
use Maatwebsite\Excel\Facades\Excel;
class ProductController extends Controller
{
public function index(Request $request)
{
$productCount = Product::count();
$dataPerPage = 10;
$productPages = ceil($productCount / $dataPerPage);
$currentPage = isset($request->all()['page']) ? $request->all()['page'] : 1;
$products = Product::orderBy('created_at','desc')
->offset($dataPerPage * ($currentPage - 1))
->limit($dataPerPage)
->get();
return view('admin.products.index',['products' => $products,
'productCount' => $productCount,
'productPages' => $productPages]);
}
public function uploadImage(Request $request)
{
$request->validate([
'product_id' => 'required|integer|exists:products,id',
'product_image' => 'required|image|max:2048',
]);
$product = Product::findOrFail($request->product_id);
$path = $request->file('product_image')->store('images', 'public');
$filename = basename($path);
// Create a new image record in the images table instead of updating products table
$product->images()->create([
'path' => $path,
'filename' => $filename,
'attachable_type' => 'App\Models\Product',
//'attachable_type' => Product::class, // Use ::class instead of string literal
'attachable_id' => $product->id,
]);
return redirect()->back()->with('success', '圖片上傳成功');
}
public function import(Request $request)
{
$file = $request->file('excel');
Excel::import(new ProductsImport,$file);
return redirect()->back();
}
/**
* 顯示卡片式產品列表
*/
public function indexCard(Request $request)
{
$page = $request->input('page', 1);
$perPage = 12; // 每頁顯示 12 個產品
$products = Product::with('images')
->orderBy('id', 'desc')
->paginate($perPage);
return view('admin.products.index-card', [
'products' => $products,
'productCount' => Product::count(),
'readonly' => false,
]);
}
/**
* 顯示編輯表單
*/
public function edit($id)
{
$product = Product::with('images')->findOrFail($id);
return view('admin.products.edit', compact('product'));
}
/**
* 更新產品
*/
public function update(Request $request, $id)
{
$product = Product::findOrFail($id);
$request->validate([
'title' => 'required|max:255',
'content' => 'nullable',
'price' => 'required|numeric|min:0',
'quantity' => 'required|integer|min:0',
], [
'title.required' => '標題為必填',
'price.required' => '價格為必填',
'price.numeric' => '價格必須為數字',
'quantity.required' => '數量為必填',
'quantity.integer' => '數量必須為整數',
]);
$product->update([
'title' => $request->title,
'content' => $request->content,
'price' => $request->price,
'quantity' => $request->quantity,
]);
return redirect()->route('admin.products.card')
->with('success', '產品更新成功!');
}
/**
* 刪除產品圖片
*/
public function deleteImage($id)
{
$image = \App\Models\Image::findOrFail($id);
// 刪除實體檔案
$filePath = storage_path('app/public/' . $image->path);
if (file_exists($filePath)) {
unlink($filePath);
}
// 刪除資料庫記錄
$image->delete();
return response()->json(['success' => true]);
}
/**
* 顯示新增產品表單
*/
public function create()
{
return view('admin.products.create');
}
/**
* 儲存新產品
*/
public function store(Request $request)
{
$request->validate([
'title' => 'required|max:255',
'content' => 'nullable',
'price' => 'required|numeric|min:0',
'quantity' => 'required|integer|min:0',
], [
'title.required' => '標題為必填',
'price.required' => '價格為必填',
'price.numeric' => '價格必須為數字',
'quantity.required' => '數量為必填',
'quantity.integer' => '數量必須為整數',
]);
Product::create([
'title' => $request->title,
'content' => $request->content,
'price' => $request->price,
'quantity' => $request->quantity,
]);
return redirect()->route('admin.products.card')
->with('success', '產品新增成功!');
}
/**
* good_design 唯讀展示頁
*/
public function goodDesign(Request $request)
{
$perPage = 12;
$products = Product::with('images')
->orderBy('id', 'desc')
->paginate($perPage);
return view('admin.products.index-card', [
'products' => $products,
'productCount' => Product::count(),
'readonly' => true,
]);
}
}
明天再來解釋~