首先明确的是,只有登入的普通类型用户才能进行购买物品,如果没有登入则不能购买。在登入后,点击购买,相当于在购物车表[ShopCart]中加入一条数据,完成后在页面弹出提示框,“添加成功”。
然后,点击购物车。可以看到自己以前所点击购买的商品。并可以删除或是修改数量。
当点击“编辑”时
当点击“结账”时,出现的页面是
填完相应信息后,点击提交,弹出提示框并返回主页面
(实际上最后一步的逻辑是:生成一个订单号,在[Order]表中插入一条信息,存的是这个订单的整体信息,收件人地址,总价格等等,在[OrderItem]表中插入一条或者多条记录,但都是同一个订单号,存的是不同的商品及数量)
具体实现:
(1)登入后点击“购买”。
首先,在App_code文件夹里面新建OrderItem.cs的类,用于保存单条临时商品信息。
(这个类里面要有字段
public string ID; //商品编号
public float Price;//商品价格
public int Num;//商品数量
public float SumPrice;//小计 )
然后,由于“购买”这个Link_Button控件是在DataList控件里面,所以点击触发事件应该是在后台cs文件里面添加(注意:要在 protected void dlResult_ItemCommand(object source, DataListCommandEventArgs e) { if (e.CommandName == "detailSee") { } else if (e.CommandName == "buyGoods") { AddShopCartItem(e, dlResult); } } public void AddShopCartItem(DataListCommandEventArgs e, DataList DLName) { if (Session["USERNAME"] != null) { OrderItem Goods = null; Goods = GetSubGoodsInformation(e, DLName); if (Goods == null) { //显示错误信息 Response.Write(""); return; } else { //取得当前购物车有无此已购商品 string sql = "select * from ShopCart where GoodsID=@GoodsID and UserName=@UserName"; SqlParameter[] parameters ={ new SqlParameter("@GoodsID", SqlDbType.Char, 14), new SqlParameter("@UserName", SqlDbType.Char, 50)}; parameters[0].Value = Goods.ID; parameters[1].Value = Session["USERNAME"].ToString().Trim(); int i = new DataBaseHelper().Select(sql, parameters).Rows.Count; if (i > 0) { sql = @"update ShopCart set Num=(Num+1), SumPrice=(SumPrice+@Price) where GoodsID=@GoodsID and UserName=@UserName"; } else { sql = @"Insert into ShopCart(GoodsID,Num,SumPrice,UserName) values(@GoodsID,1,@Price,@UserName)"; } SqlParameter[] parameters1 ={ new SqlParameter("@GoodsID", SqlDbType.Char, 14), new SqlParameter("@Price", SqlDbType.Float, 8), new SqlParameter("@UserName", SqlDbType.Char, 50)}; parameters1[0].Value = Goods.ID; parameters1[1].Value = Goods.Price; parameters1[2].Value = Session["USERNAME"].ToString().Trim(); //执行 int s = new DataBaseHelper().ExecuteNonQuery(sql, parameters1); if (s > 0) { GlobleClass.PopInfo(this.Page, "恭喜您,添加成功!"); } else { GlobleClass.PopInfo(this.Page, "操作不成功!"); } } } else { GlobleClass.PopInfo(this.Page, "请先登录,谢谢!"); } } //当购买商品时,获取商品信息 public OrderItem GetSubGoodsInformation(DataListCommandEventArgs e, DataList DLName) { //获取购物车中的信息 OrderItem Goods = new OrderItem(); Goods.ID = DLName.DataKeys[e.Item.ItemIndex].ToString(); string GoodsInfo = e.CommandArgument.ToString(); Goods.Price = float.Parse(GoodsInfo); return (Goods); } (2)购物车功能(点击“我的购物车”) 点击“我的购物车”触发的是母版后台文件里的void hlkShopCar_Click函数,这个函数的功能是转到新建的一个UserDetail网页上,并传个参数type=0,表示普通用户 protected void hlkShopCar_Click(object sender, EventArgs e) { if (Session["USERNAME"] != null) { //重新定位转到User文件夹下的 UserDetail.aspx,并加个参数type=0 } else { GlobleClass.PopInfo(this.Page, "请先登录,谢谢!"); } } 新建UserDetail.aspx网页在User文件夹下面 在这个新的页面里面,继承的还是原先的母版文件。这个页面里面有两行文字,一个asp的Label控件(ID:lblTotal),一个Button(ID:btnReckoning),一个GridView的控件(ID:gvShopCart) 这个里面的重点是GridView控件的源码编写 像它可以分页显示,每分页显示5行,还有对应的“删除”,“编辑”,“更新”,“取消”的后台函数名等。所以,这个控件的属性有 OnRowCancelingEdit="gvShopCart_RowCancelingEdit" OnRowDeleting="gvShopCart_RowDeleting" OnRowEditing="gvShopCart_RowEditing" OnRowUpdating="gvShopCart_RowUpdating"> 并且这个空间绑定的实际上是ShopCart表和Goods表的联合,所需要的是4个字段,分别是商名名称,价格,数量,小计。所以在这个控件里面加入数据绑定。给出两个示例,另外两个同学们可以仿照写出 ¥<%# DataBinder.Eval(Container.DataItem,"Price").ToString()%> (注意:第一个商品名称直接显示的是数据库的这个字段的数据,没有额外添加什么,所以直接使用的是asp:BoundField。而第二列价格,由于要在数据库该字段数据下加个“¥”符号,所以使用的是asp:TemplateField,在这个Template里面使用<%# DataBinder.Eval(Container.DataItem,"Price").ToString()%>的方法强制绑定。注意在写“数量”这一列时,我们要求在点击“编辑”时它是可编辑的,所以不用ReadOnly) 显示删除,编辑按钮的源码是 外面的框架搭完后,就要开始写后台代码,在后台代码中将GridView控件的数据源绑定,数据源中要有前台绑定的相关字段。 部分后台代码: protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { if (Session["USERNAME"] != null) { LoadShopCar();// 显示购物车中的信息 TotalDs();// 显示购物车中的商品合计金额 } else { Response.Redirect("~/Default.aspx"); GlobleClass.PopInfo(this.Page, "请先登录,谢谢合作!"); } } } /// /// 显示购物车中的信息 /// private void LoadShopCar() { string sql =??? ( string sql = @"select GoodsID,Name,Price,Num,SumPrice,UserName from ShopCart S, Goods G where S.GoodsID=G.ID and UserName='" + Session["USERNAME"].ToString().Trim() + "' ";) DataTable dt = new DataBaseHelper().Select(sql); gvShopCart.DataSource = dt; gvShopCart.DataBind(); } /// /// 显示购物车中的商品合计金额 /// private void TotalDs() {?????? ( string sql = "select Sum(SumPrice) from ShopCart " + "where UserName='" + Session["USERNAME"].ToString().Trim() + "' "; DataTable dt = new DataBaseHelper().Select(sql); if (dt.Rows.Count > 0) { lblTotal.Text = dt.Rows[0][0].ToString(); } ) } protected void gvShopCart_PageIndexChanging(object sender, GridViewPageEventArgs e) { gvShopCart.PageIndex = e.NewPageIndex; LoadShopCar(); } protected void gvShopCart_RowDeleting(object sender, GridViewDeleteEventArgs e) {?????? ( string goodsID = gvShopCart.DataKeys[e.RowIndex]["GoodsID"].ToString(); string userName = gvShopCart.DataKeys[e.RowIndex]["UserName"].ToString(); string sql = @"delete from ShopCart where UserName='" + userName + "' and GoodsID='" + goodsID + "' "; int i = new DataBaseHelper().ExecuteNonQuery(sql); LoadShopCar(); TotalDs(); ) } protected void gvShopCart_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e) { gvShopCart.EditIndex = -1; LoadShopCar(); TotalDs(); } protected void gvShopCart_RowUpdating(object sender, GridViewUpdateEventArgs e) { string goodsID = gvShopCart.DataKeys[e.RowIndex]["GoodsID"].ToString(); string userName = gvShopCart.DataKeys[e.RowIndex]["UserName"].ToString(); string num = ((TextBox)(gvShopCart.Rows[e.RowIndex].Cells[2].Controls[0])).Text.ToString(); if (GlobleClass.IsNumber(num) == true) //注意:这里需要同学们写个函数IsNumber用于判断该字符串是否是数字 { string sql = @"update ShopCart set Num=" + num + ", " + "SumPrice=(" + num + "*( Select Price from Goods " + " where ID='" + goodsID + "')) " + "where UserName='" + userName + "' and GoodsID='" + goodsID + "'"; if (new DataBaseHelper().ExecuteNonQuery(sql) == 1) { gvShopCart.EditIndex = -1; LoadShopCar(); TotalDs(); } } else { GlobleClass.PopInfo(this.Page, "请输入正确的物品数量!"); } } protected void gvShopCart_RowEditing(object sender, GridViewEditEventArgs e) { gvShopCart.EditIndex = e.NewEditIndex; LoadShopCar(); TotalDs(); } protected void btnReckoning_Click(object sender, EventArgs e) { Response.Redirect("CheckOut.aspx?Total=" + lblTotal.Text.Trim()); } (3)结账功能(重点)(说明:订单生成过程) 在工程里的User文件夹下,新建CheckOut.aspx,和其它新建的页面一样,继承母版页面。在替换占位符时, 按钮“退出”点击时,触发的后台事件所做的工作是:重新定位到Default.aspx 按钮“提交”点击时,首先插入的是订单表,再是插入的订单明细表。