首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 餐飲管理系統核心模組程式碼分享:菜單展示、購物車、訂單流程

     編輯:ASP.NET 基礎

本文分享一個 ASP.NET WebForms 餐飲管理系統的核心模組程式碼,涵蓋菜單分頁展示 (GridView/DataList)、優惠價格顯示、購物車增刪改查 (DataList + PagedDataSource)、訂單結帳流程。程式碼採用 Master Page 版面、SqlDataSource 控制項、Session 狀態管理,適合教學參考或中小型專案快速原型。

系統架構概覽

  • 前台:MasterPage 版面、GridView/DataList 資料綁定、AspNetPager 分頁 (隱含)
  • 資料層:SqlDataSource 控制項宣告式存取、自訂 DB Helper 執行 SQL
  • 狀態管理:Session 儲存使用者資訊、購物車項目
  • 資料表:Menus (菜單)、OrderMenu (購物車)、IndentMenu (訂單)、Users (會員)

模組一:菜單管理頁面 (menu.aspx)

前台標記 - 雙重顯示模式

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" CodeFile="menu.aspx.cs" Inherits="menu" %>

    
    
        
        
            
            
            
            
            
            
            
        
    
    



    
    
        
            
圖片菜名原價優惠價
菜單管理介面 1
後台 GridView 管理檢視
菜單管理介面 2
前台 DataList 卡片展示

模組二:購物車頁面 (menuCar.aspx)

前台標記 - DataList 實現可編輯購物車

<%@ Page Language="C#" MasterPageFile="~/Land-zhuce.master" CodeFile="menuCar.aspx.cs" Inherits="menuCar" %>

    
        
            
            
序號菜名圖片 價格份數儲存刪除
<%# DataBinder.Eval(Container.DataItem, "goodID") %> <%# DataBinder.Eval(Container.DataItem, "menuName") %> <%# DataBinder.Eval(Container.DataItem, "payMoney", "{0:C}") %>
總金額:

後台邏輯 (menuCar.aspx.cs) - 核心 CRUD

public partial class menuCar : System.Web.UI.Page
{
    DB db = new DB(); // 自訂資料庫 Helper
    DataSet Ds = new DataSet();

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack) DataListBind();
    }

    void DataListBind()
    {
        string sql = "SELECT * FROM OrderMenu WHERE customerName = @user";
        var param = new SqlParameter("@user", Session["UserName"]?.ToString() ?? "");
        Ds = Dataoperator.GetRows(sql, param); // 參數化查詢
        DataList1.DataSource = Ds;
        DataList1.DataBind();
        CalculateTotal();
    }

    // 修改數量 (UpdateCommand)
    protected void DataList1_UpdateCommand(object source, DataListCommandEventArgs e)
    {
        string id = DataList1.DataKeys[e.Item.ItemIndex].ToString();
        TextBox txtCount = (TextBox)e.Item.FindControl("txtCount");
        
        if (int.TryParse(txtCount.Text, out int qty) && qty > 0)
        {
            // 查詢單價計算總價
            string priceSql = "SELECT menuPrice FROM Menus WHERE menuID = @id";
            object priceObj = Dataoperator.GetScalar(priceSql, new SqlParameter("@id", id));
            if (priceObj != null)
            {
                decimal price = Convert.ToDecimal(priceObj);
                decimal total = price * qty;
                
                string updSql = "UPDATE OrderMenu SET number = @qty, payMoney = @total WHERE ID = @id";
                bool ok = db.UpdateDataBySql(updSql, 
                    new SqlParameter("@qty", qty), 
                    new SqlParameter("@total", total), 
                    new SqlParameter("@id", id));
                
                if (ok) { ScriptAlert("數量修改成功"); DataListBind(); }
                else ScriptAlert("修改失敗");
            }
        }
    }

    // 刪除項目 (DeleteCommand)
    protected void DataList1_DeleteCommand(object source, DataListCommandEventArgs e)
    {
        string id = DataList1.DataKeys[e.Item.ItemIndex].ToString();
        string delSql = "DELETE FROM OrderMenu WHERE ID = @id";
        if (db.UpdateDataBySql(delSql, new SqlParameter("@id", id)))
        {
            ScriptAlert("刪除成功");
            DataListBind();
        }
        else ScriptAlert("刪除失敗");
    }

    void CalculateTotal()
    {
        decimal total = 0;
        if (Ds?.Tables.Count > 0)
        {
            foreach (DataRow row in Ds.Tables[0].Rows)
                total += Convert.ToDecimal(row["payMoney"]);
        }
        total_money_txt.Text = total.ToString("C");
    }

    protected void shoppingbtn_Click(object sender, EventArgs e) => Response.Redirect("orderMainMenu.aspx");
    protected void delallbtn_Click(object sender, EventArgs e) { /* 清空邏輯 */ }
    protected void orderbtn_Click(object sender, EventArgs e) => Response.Redirect("menuorder.aspx");

    void ScriptAlert(string msg) => ClientScript.RegisterStartupScript(GetType(), "alert", $"alert('{msg}');", true);
}
購物車介面
購物車 - 可修改數量、刪除、查看總計

模組三:訂單結帳流程 (menuorder.aspx.cs 片段)

protected void orderbtn_Click(object sender, EventArgs e)
{
    // 1. 取得購物車明細 (join view)
    string sql = "SELECT * FROM menuView WHERE customerName = @user";
    DataSet ds = Dataoperator.GetRows(sql, new SqlParameter("@user", Session["UserName"]));
    
    if (ds.Tables[0].Rows.Count == 0)
    {
        ScriptAlert("購物車是空的");
        return;
    }

    // 2. 計算總金額
    decimal total = ds.Tables[0].Rows.Cast().Sum(r => Convert.ToDecimal(r["payMoney"]));
    total_money_txt.Text = total.ToString("C");

    // 3. 使用者確認送出 (實際應在前端表單提交)
    // 這裡示範後台直接寫入訂單主檔 + 明細檔
    bool success = true;
    string orderNo = "ORD" + DateTime.Now.ToString("yyyyMMddHHmmss");
    
    foreach (DataRow row in ds.Tables[0].Rows)
    {
        string insertSql = @"INSERT INTO IndentMenu 
            (OrderNo, GoodID, CustomerName, MenuName, Quantity, PayMoney, OrderDate, PayType, Remark)
            VALUES (@ono, @gid, @cust, @name, @qty, @money, @odate, @pay, @remark)";
        
        success &= Dataoperator.ExecSql(insertSql,
            new SqlParameter("@ono", orderNo),
            new SqlParameter("@gid", row["goodID"]),
            new SqlParameter("@cust", row["customerName"]),
            new SqlParameter("@name", row["menuName"]),
            new SqlParameter("@qty", row["number"]),
            new SqlParameter("@money", row["payMoney"]),
            new SqlParameter("@odate", DateTime.Now),
            new SqlParameter("@pay", ddlPayment.SelectedValue), // 下拉選單:現金/刷卡/LinePay
            new SqlParameter("@remark", txtRemark.Text));
    }

    if (success)
    {
        // 清空購物車
        db.UpdateDataBySql("DELETE FROM OrderMenu WHERE customerName = @user", 
            new SqlParameter("@user", Session["UserName"]));
        Response.Redirect("menuIndent.aspx?orderNo=" + orderNo); // 導向訂單確認頁
    }
    else ScriptAlert("訂單建立失敗,請聯繫客服");
}
訂單結帳介面
結帳頁面 - 選擇付款方式、備註、確認送出

資料庫核心結構參考

-- 菜單主檔
CREATE TABLE Menus (
    menuID INT PRIMARY KEY IDENTITY,
    menuName NVARCHAR(100) NOT NULL,
    menuPhoto NVARCHAR(200),      -- 圖片相對路徑
    menuPhUrl NVARCHAR(200),      -- 縮圖路徑
    menuCooker NVARCHAR(50),
    menuStyle NVARCHAR(50),
    menuPrice DECIMAL(10,2),
    menuNewPrice DECIMAL(10,2),   -- 優惠價 (NULL 表示無優惠)
    menuDate DATETIME DEFAULT GETDATE()
);

-- 購物車 (暫存)
CREATE TABLE OrderMenu (
    ID INT PRIMARY KEY IDENTITY,
    goodID INT,                   -- 關聯 menuID
    customerName NVARCHAR(50),    -- Session 用戶名
    menuName NVARCHAR(100),
    menuPhUrl NVARCHAR(200),
    number INT DEFAULT 1,
    payMoney DECIMAL(10,2)
);

-- 訂單主檔
CREATE TABLE IndentMenu (
    ID INT PRIMARY KEY IDENTITY,
    OrderNo NVARCHAR(30) NOT NULL,
    GoodID INT,
    CustomerName NVARCHAR(50),
    MenuName NVARCHAR(100),
    Quantity INT,
    PayMoney DECIMAL(10,2),
    OrderDate DATETIME DEFAULT GETDATE(),
    PayType NVARCHAR(20),         -- Cash, Card, LinePay
    Remark NVARCHAR(500)
);

程式碼優化與現代化建議

現狀問題建議改進
SqlDataSource 控制項邏輯分散於標記、難以單元測試改用 Repository Pattern + Entity Framework / Dapper
DataList + 手動分頁功能有限、樣式難控制改用 GridView/ListView + AspNetPager 或前端分頁 (AJAX)
Session 儲存用戶名不支援分散式部署、安全性低ASP.NET Core Identity + JWT / Cookie Authentication
字串拼接 SQL (部分)SQL Injection 風險全面參數化查詢 / ORM
WebForms Postback 模式ViewState 大、SEO 差、前後端耦合遷移至 ASP.NET Core MVC / Razor Pages / Blazor
自訂 DB Helper重複造輪子、連線管理易出錯使用成熟 ORM (EF Core) 或 Micro-ORM (Dapper)

此程式碼展示了經典 ASP.NET WebForms 時代典型的資料導向開發模式,理解其運作機制有助於維護舊系統或規劃現代化遷移策略。新專案強烈建議採用 ASP.NET Core + 前後端分離架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved