开发小技巧系列文章,是本人对过往平台系统的设计开发及踩坑的记录与总结,给初入平台系统开发的开发人员提供参考与帮助
01 什么是购物车?
购物车,是购物平台(网上商城)必备的功能,像京东、淘宝、当当都有这样的功能,那购物车是怎么实现的,做过商城的小伙伴应该知道,未做过商城的小伙伴可能就不知道,为了让初入商城开发的小伙伴了解这块怎么做,从程序开发的角度来讨论一下这个场景,包括:
- 购物车的混合存储;
- 用户在没有登录商城的情况,如何来实现加入购物车
- 登录后怎么进行合并。
在讨论加入购物车功能之前,先了解下购物车的数据结构(表),如果在京东淘宝购买过商品,购物车是必不可少(PS:如果不知道,赶紧打开京东APP看看),不懂的小伙伴可能会对呈现的商品/商家信息之多而不知所措(一头雾水)。
那么购物车的对象(表)应该包含那些信息呢?商品、商家、价格、优惠活动、券等吗?当然不是(为什么不是,这里需要一篇长文章才能说清楚,暂时先说下结果)。
(图:京东APP的购物车)
02 购物车的结构
先来看看之前电商项目使用的购物车的结构(此处忽略一些细节,只列关键的属性):
id : 主键
member_id : 会员ID
product_id : SPU ID(商品ID)
sku_id : 商品规格ID
qty : 数量(加购的数量),正整数
join_price : 加入购物车时的价格(用于比对后来价格的变化,也可以不要)
created_time : 记录创建时间
revised_time : 记录修改时间
revisor : 修改人
这是当时开发商城设计的购物车的结构,可能跟小伙伴所在的每个公司的实际情况有出入,多些字段或者少些字段,但基本信息都是一样,离不开who(谁)、what(什么商品及数量)、when(什么时间)这几个要素。
03 未登录加购物车?
也许有些小伙伴会说,用户未登录,引导用户去登录不就行了,何必搞得这么复杂,其实这里涉及到用户体验的问题。点击加购物车时,引导用户跳至登录,用户填写账号信息后登录,再跳回当前面,再去点击加入购物车的操作,这里面多了2次步操作,会给用户一种强迫的感觉,体验比较差,那么有没有更好的处理方式?
如果有在各大电商平台下单买过东西(PC端网站系统),并细心留意操作的话,会发现在未登录的情况下,是可以点击加入购物车,并且也在购物车列表中的,那是怎么做的呢?
04 cookie临时购物车
可能聪明的小伙伴已经想到了,可以使用浏览器本地cookie来存储,只要本地的cookie缓存未被清除,可以一直暂存着。没错,这个小伙伴答对了,使用cookie来存储用户未登录时加入购物车的数据是一种解决方案(想一想,cookie最大可以存储多少字符)。cookie的存储,其实就是一串字符串,需要定义一定的结构,比如:
采用','作为属性的分隔,采用';'作为不同sku的分隔。
比如有:sku : 0011, 数量:2
sku : 0012, 数量:3
结果为:0011,2;0012,3 这样子一长串。
那还有没有其他解决办法吗?
当然是有的,采用 cookie来存储,是属于“客户端存储”的临时购物车,也可以采用“服务端存储”的临时购物车。
05 LocalStorage临时购物车
由于在cookie中存储数据时,一般是通过字符串拼接的方式来存储,不太好进行增加与删除,一般场景下比较少用。可以用另外一种改进的方式来存储,使用浏览器的LocalStorage来存储,LocalStorage为标准的键值对(Key-Value,简称KV)数据类型,操作起来简单与方便。
if(!window.localStorage){
alert("浏览器支持localstorage");
return false;
}else{
var storage=window.localStorage;
//写入a字段
storage["a"]=1;
//写入b字段
storage.a=1;
//写入c字段
storage.setItem("c",3);
console.log(typeof storage["a"]);
console.log(typeof storage["b"]);
console.log(typeof storage["c"]);
}
关于localstorage相关资料及介绍,可以参考:
HTML5 LocalStorage 本地存储 www.cnblogs.com/xiaowei0705…
MDN - Window.localStorage developer.mozilla.org/zh-CN/docs/…
06 后端临时购物车
前面介绍的这2种方式都是基于客户端来存储,可能对于某些业务场景来说,还是希望后端(服务端)能记录这些未登录的用户的加购数据,也可以跟这些加购的数据来进行商品的热度分析等。
采用服务端来存储加购数据,要怎么做呢? 仔细想想也不复杂,无非就是按购物车的结构再临时存储一份数据,还是CRUD的操作(CURD是永远的神),服务端存储的话,可以使用数据库表来存储(如果用户量不大的话,没有高并发的问题),也可以采用redis来存储(适合高并发,或者购物车数据不重要的场景下)。
- 数据表来存储,可以按前面的数据结构来设计;
- redis存储,有2种:
- 可以采用hash结构,key 是临时用户标识,value是购物车数据。
- 一种就是每个临时用户一个hash,里面的key就是skuId, value就是数量。
PS:这2种方式哪种更好,使用的小伙伴可以自己思考
至于未登录用户的标志(token),可以在访问商城时分配一个临时的(能全局唯一就可以, 可以服务端生成,也可以客户端生成),在加入购物车的时候提交到后台(当作用户ID),前后操作保持一致的token。
当然,临时加入购物车的数据不会太多(小伙伴可以想为什么?),用户不会一直无聊地在那里加入(除了测试/或者恶意外),要么不想购买就关闭程序,要么登录系统,进行购买操作。
07 购物车合并
用户登录系统后,就需要将前面临时存储的购物车数据,跟用户现有的购物车数据进行合并。如果是客户存储的,就要调用接口回传,后台接收到数据后,将数据持久化到登录用户的购物车中;如果是服务端临时存储的,也要调用接口将临时token回传,让服务端进行数据合并,重新给用户返回新的购物车列表数据。
一般按sku_id与现存的sku_id进行对比,如果正式购物车存在,则将临时购物车的加购数量,加到正式的sku_id的qty上。如果sku_id不存在正式的购物车上,则插入新的记录(sku_id, qty, user_id等)。
关于电商购物车的功能,临时购物车的实现,登录后购物车数据的合并,是不是清晰很多了呢,实际上数据存储没这么复杂,而复杂是在购物车列表数据的展示(涉及到多种数据的组装),这个后面可以来讲讲
文章来源于本人的公众号,ID:技术老男孩,欢迎关注。