本文共 4526 字,大约阅读时间需要 15 分钟。
1.实现未登录状态的购物车
2.实现登陆状态下的购物车
需求描述:
这幅图主要描述了两个功能:新增商品到购物车、查询购物车。
新增商品:
无论哪种新增,完成后都需要查询购物车列表:
web本地存储主要有两种方式:
LocalStorage的用法
语法非常简单:
localStorage.setItem("key","value"); // 存储数据localStorage.getItem("key"); // 获取数据localStorage.removeItem("key"); // 删除数据
注意:localStorage和SessionStorage都只能保存字符串。
不过,在我们的common.js中,已经对localStorage进行了简单的封装:
addCart(){ ly.verifyUser().then(res=>{ // 已登录发送信息到后台,保存到redis中 }).catch(()=>{ // 未登录保存在浏览器本地的localStorage中 // 1、查询本地购物车 let carts = ly.store.get("carts") || []; let cart = carts.find(c=>c.skuId===this.sku.id); // 2、判断是否存在 if (cart) { // 3、存在更新数量 cart.num += this.num; } else { // 4、不存在,新增 cart = { skuId: this.sku.id, title: this.sku.title, price: this.sku.price, image: this.sku.images, num: this.num, ownSpec: this.ownSpec } carts.push(cart); } // 把carts写回localstorage ly.store.set("carts", carts); // 跳转 window.location.href = "http://www.leyou.com/cart.html"; });}
页面加载时,就应该去查询购物车。
var cartVm = new Vue({ el: "#cartApp", data: { ly, carts: [],// 购物车数据 }, created() { this.loadCarts(); }, methods: { loadCarts() { // 先判断登录状态 ly.verifyUser().then(() => { // 已登录 }).catch(() => { // 未登录 this.carts = ly.store.get("carts") || []; this.selected = this.carts; }) } } components: { shortcut: () => import("/js/pages/shortcut.js") }})
渲染carts的数据到页面
修改数量
删除商品
选中商品
![]()
添加登录校验
购物车系统只负责登录状态的购物车处理,因此需要添加登录校验,我们通过JWT鉴权即可实现。
我们引入之前写的鉴权工具:leyou-auth-common
因为很多接口都需要进行登录,我们直接编写SpringMVC拦截器,进行统一登录校验。同时,我们还要把解析得到的用户信息保存起来,以便后续的接口可以使用。
购物车是一个读写频率很高的数据。因此我们这里选择读写效率比较高的Redis作为购物车存储。
我们的购物车结构是一个双层Map:Map<String,Map<String,String>>
这里我们不访问数据库,而是直接操作Redis
@Servicepublic class CartService { @Autowired private StringRedisTemplate redisTemplate; @Autowired private GoodsClient goodsClient; static final String KEY_PREFIX = "leyou:cart:uid:"; static final Logger logger = LoggerFactory.getLogger(CartService.class); public void addCart(Cart cart) { // 获取登录用户 UserInfo user = LoginInterceptor.getLoginUser(); // Redis的key String key = KEY_PREFIX + user.getId(); // 获取hash操作对象 BoundHashOperationshashOps = this.redisTemplate.boundHashOps(key); // 查询是否存在 Long skuId = cart.getSkuId(); Integer num = cart.getNum(); Boolean boo = hashOps.hasKey(skuId.toString()); if (boo) { // 存在,获取购物车数据 String json = hashOps.get(skuId.toString()).toString(); cart = JsonUtils.parse(json, Cart.class); // 修改购物车数量 cart.setNum(cart.getNum() + num); } else { // 不存在,新增购物车数据 cart.setUserId(user.getId()); // 其它商品信息,需要查询商品服务 Sku sku = this.goodsClient.querySkuById(skuId); cart.setImage(StringUtils.isBlank(sku.getImages()) ? "" : StringUtils.split(sku.getImages(), ",")[0]); cart.setPrice(sku.getPrice()); cart.setTitle(sku.getTitle()); cart.setOwnSpec(sku.getOwnSpec()); } // 将购物车数据写入redis hashOps.put(cart.getSkuId().toString(), JsonUtils.serialize(cart)); }}
购物车页面:cart.html
当跳转到购物车页面,查询购物车列表前,需要判断用户登录状态,
转载地址:http://txxab.baihongyu.com/