iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
自我挑戰組

Laravel 讀碼源系列 第 12

產品管理列表的後端code

  • 分享至 

  • xImage
  •  

這個是永康社大的作品,也歡迎大家來上課或購買
https://laihao.vaserver.com/admin/good_design
這是含有前端+資料庫+後端

當然也有 route的地方
因為怕大家動到CRUD 所以只有解釋 截圖畫面的部分,就是沒有連結

https://ithelp.ithome.com.tw/upload/images/20260821/20119035TDxQxjlr6L.png


這個也有另一個列表樣式,
因為怕大家動到CRUD所以先反灰,
不過大家還是可以看到原始的按鈕的樣子
https://laihao.vaserver.com/admin/products
https://ithelp.ithome.com.tw/upload/images/20260821/20119035YRsgUNZNIB.png

後端 程式碼

<?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,
    ]);
}
}




明天再來解釋~


上一篇
產品管理列表的資料表
系列文
Laravel 讀碼源12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言