该系统购物车的实现方式是数据库+Cookies。
首先说明下该系统的业务要求:每个游客不必登录就会拥有他们自己的购物车,可以随意的添加商品到他们自己的购物车上,该购物车能显示他们购买商品,数量,价钱以及所有商品的总价钱。并且游客可以随意的更改或删除购物车上的商品。当游客要结账时就需要登录会员,此时就会跳出一新的界面购物清单,请会员确认清单上的商品,并填写邮寄商品的地址及相关的信息以及支付方式。然后会再次出现确认您填写信息的界面。点击确认时候就会跳转到付款的界面(支付宝等等类似的,但是国外一般用的是paypal,这个比支付宝好多了,它会给开发人员提供一个sandbox测试账号,开发人员可以随意开户,并进行虚拟转账,以便测试程序,具我所知好像支付宝就没有提供我们开发人员测试账号,我们要拿真的银行卡去测试我们的程序,好像每交易一次它就会收取一次佣金吧。而且paypalSDK有完备文档和示例。可惜是国外的。我自己本来是想实现这块内容,但是上会去申请测试账号时候,我愤怒了,因为开始我填写我是中国居民时候,你不能申请测试账号,只有当你填写你是美国或着英国的居民才能使用测试账号,于是我就填写我是美国居民,结果还要填写什么美国电话,ZIP code,Ferderal TaxID,以及Satae主要是这些都要和所填的城市对应,最后终于搞定了,但是最终倒在Social Security number的填写,没有搞成功。后来自己想想如果要做电子商务的话可能还是会用得到国内的支付宝,把paypal弄熟悉没多大作用,于是干脆把支付这块剪掉了)。
这里要为每位游客建立一个唯一的购物车,其实就是要生成一个唯一的购物车编号。这里我们用Guid类。如果客户端存在Cookies["Shop"],那么就在这里面提取cartID,如果没有就new一个Guid作为购物车编号,并存储到客户端的Cookies["Shop"]。这里是放在类库Shop.Operational下面的Utilities类中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
namespace Shop.Operational
{
public class Utilities
{
public static string FormatText(string text, bool allow)
{
string formatted = "";
StringBuilder sb = new StringBuilder(text);
sb.Replace(" ", " ");
if (!allow)
{
sb.Replace("<br>", Environment.NewLine);
sb.Replace(" ", " ");
formatted = sb.ToString();
}
else
{
StringReader sr = new StringReader(sb.ToString());
StringWriter sw = new StringWriter();
//能否读取下一个字符
while (sr.Peek() > -1)
{
string temp = sr.ReadLine();
sw.Write(temp + "<br>");
}
formatted = sw.GetStringBuilder().ToString();
}
return formatted;
}
public static void LogException(Exception ex)
{
string path = HttpContext.Current.Server.MapPath(@"ExceptionLog\LogFile.txt");
using (StreamWriter sw = new StreamWriter(path, true))
{
sw.WriteLine(DateTime.Now + Environment.NewLine + ex.InnerException.ToString() + Environment.NewLine + Environment.NewLine);
}
}
public static string GetCartGUID()
{
if (HttpContext.Current.Request.Cookies["Shop"] != null)
{
return HttpContext.Current.Request.Cookies["Shop"]["CartID"].ToString();
}
else
{
Guid CartGUID = Guid.NewGuid();
HttpCookie cookie=new HttpCookie("shop");
cookie.Values.Add("CartID", CartGUID.ToString());
cookie.Expires = DateTime.Now.AddDays(30);
HttpContext.Current.Response.AppendCookie(cookie);
return CartGUID.ToString();
}
}
}
}
前面在Cookies里得到了CartGUID,那么就可以通CartGUID操作购物车。每次向购物车添加商品时候就是在向数据库dt_ShoppingCart插入或更新表的内容(若购物车无该商品就插入,若有该商品就更新该商品的数量)
CREATE PROCEDURE [dbo].[ShoppingCart_Insert]
@CartGUID nvarchar(50),
@ProductID int,
@Quantity int
AS
DECLARE @ItemCount int
SELECT
@ItemCount=Count(ProductID)
FROM
dt_ShoppingCart
WHERE
ProductID=@ProductID
AND
CartGUID=@CartGUID
IF @ItemCount>0
UPDATE
dt_ShoppingCart
SET Quantity=(@Quantity+dt_ShoppingCart.Quantity)
WHERE
ProductID=@ProductID
AND
ShoppingCartID=ShoppingCartID
ELSE
INSERT INTO dt_ShoppingCart(CartGUID,ProductID,Quantity,DateCreated)
VALUES(@CartGUID,@ProductID,@Quantity,getdate())
查看购物车就是查询这张表
CREATE PROCEDURE [dbo].[ShoppingCart_Select]
@CartGUID nvarchar(50)
AS
SELECT
ShoppingCartID,
dt_Products.ProductID,
dt_Products.ProductName,
Quantity,
dt_Products.ProductPrice AS UnitPrice,
(dt_Products.ProductPrice*Quantity) AS TotalPrice
FROM dt_ShoppingCart
INNER JOIN
dt_Products ON dt_Products.ProductID=dt_ShoppingCart.ProductID
WHERE CartGUID=@CartGUID
删除购物车的商品:
@ShoppingCartID int
AS
Delete FROM dt_ShoppingCart
Where ShoppingCartID = @ShoppingCartID
修改购物车的内容:
@Quantity int ,
@ShoppingCartID int
AS
UPDATE dt_ShoppingCart
SET Quantity = @Quantity
WHERE ShoppingCartID = @ShoppingCartID
这样一个购物车就完成了,增,删,查,改操作都有。
当用户在产品目录中浏览时,在大多数情况下,他们会将他们感兴趣的项添加到购物车中,有些人会通过结账来结束他们的事务,但是也有些不会结束他们的事务。他们肯能会过几天结束。还有一些是不会结束的。这些不会结束的,他们的记录任然在数据库dt_ShoppingCart表中,所以我们要丢弃这些购物车。
这里我们指定丢弃购物车时间是5天后。这里要用作业来定时清理数据库的dt_ShoppingCart表丢弃的购物车
首先创建一个存储过程
AS
DELETE FROM dt_ShoppingCart
WHERE
-- 时间超过了5天
DATEDIFF (dd,DateCreated, GetDate ()) > 5
然后添加一个SQL Server作业。
1.管理->SQL Server代理->作业(按鼠标右键)->新建作业
2.选择作业属性(常规),将新作业命名为ProcessAbandonedShoppingCarts,并启用方框内勾号。
3.选择作业属性(步骤),定义作业步骤名称为Remove,保持步骤的类型为默认选中Transact-SQL Script值,将数据库名称改为dt_Shop.在命令中输入:EXECUTE ShoppingCart_DeleteAbandoned
4.选择作业属性(调度),新建调度->名称[Delete]->启用的方框内是勾号->调度类型设置为反复出现,调频设置为每天凌晨12点
最后还是要分析下Shop.BusinessLogic类库,本来想作出一个新的随笔,发现内容太简单,而且也没有什么知识可以学习的。这里只是给出一个通常例子,其实就是表示层和数据访问层的数据转换。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Shop.Common;
using System.Data;
using Shop.DataAccess.Select;
namespace Shop.BusinessLogic
{
public class ProcessGetProductByID:IBusinessLogic
{
public ProductEntity Product { set; get; }
public DataSet Reslutset { set; get; }
public ProcessGetProductByID()
{ }
#region IBusinessLogic 成员
public void Invoke()
{
ProductSelectByIDData selectproduct = new ProductSelectByIDData();
selectproduct.Product = this.Product;
this.Reslutset=selectproduct.Get();
Product.ProductName = this.Reslutset.Tables[0].Rows[0]["ProductName"].ToString();
Product.ProductDescription = this.Reslutset.Tables[0].Rows[0]["ProductDescription"].ToString();
Product.ProductPrice =Convert.ToDecimal(this.Reslutset.Tables[0].Rows[0]["ProductPrice"].ToString());
Product.ProductImageName =this.Reslutset.Tables[0].Rows[0]["ProductImageName"].ToString();
Product.ProductCategory.ProductCategoryName = this.Reslutset.Tables[0].Rows[0]["ProductCategoryName"].ToString();
}
#endregion
}
}