分布式高级篇(七) - 商城业务 - 购物车

购物车

环境搭建

  • 修改本地etc文件
1
复制代码cart.mall.com

image-20210202091824760

  • 拷贝静态资源到nginx

image-20210202093854707

  • 将两个HTML页面,拷贝到购物车服务的templates文件夹下,并修改两个html文件中的静态资源引用路径

image-20210202094315588

image-20210202094445426

  • 配置网关路由

image-20210202100620321

  • 页面效果

image-20210202102813795

购物车需求

需求描述

  • 用户可以在登录状态下将商品添加到购物车【登录购物车 / 在线购物车】
+ 放入数据库 (购物车读写都是高并发,不适合使用 mysql)
+ MongoDB (并不能带来很高的性能提升)
+ 放入 Redis(采用)


登录以后,会将临时购物车的数据全部合并到登录的购物车信息中,并**清空临时购物车**
  • 用户可以在未登录状态下将商品添加到购物车【游客购物车 / 离线购物车 / 临时购物车】
+ 放入 localstorage (客户端存储,后台不存,虽然后台压力减小,但是无法应用到大数据分析,进行精准分析、推荐)
+ cookie
+ WebSQL
+ 放入 Redis (采用)


即使关闭浏览器,下次进入,**临时购物车**的数据都在
  • 用户可以使用购物车一起结算下单
  • 用户给购物车添加商品
  • 用户可以查询自己的购物车
  • 用户可以在购物车中修改购买商品的数量
  • 用户可以在购物车中删除商品
  • 选中 / 不选中商品
  • 在购物车中展示商品优惠信息

数据结构

  • 购物项

image-20210202105052199

  • 每一个购物项信息,都对应一个对象,基本字段包括
1
2
3
4
5
6
7
8
9
10
arduino复制代码{
skuId:123321, //商品id
check:true, //是否被选中
title:"Apple iphone...",
defaultImage: "xxx",
price:5998.00
count:1,
totalPrice:13678.00
skuSaleVo:{} //销售属性的值
}

另外购物车中不止一条数据,因此最终会是对象的数组,即:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
arduino复制代码[
{
skuId:123321, //商品id
check:true, //是否被选中
title:"Apple iphone...",
defaultImage: "xxx",
price:5998.00
count:1,
totalPrice:13678.00
skuSaleVo:{} //销售属性的值
},
{
skuId:111222, //商品id
check:true, //是否被选中
title:"Apple iphone...",
defaultImage: "xxx",
price:3398.00
count:10,
totalPrice:44678.00
skuSaleVo:{} //销售属性的值
}
]
  • Redis 有五种不同数据结构,这里选择哪一种比较合适呢?Map<String,List>>
+ 首先不同用户应该有独立的购物车,因此购物车应该以用户id作为 key 来存储,Value是用户的所有购物车信息。这样看来基本的 k-v 结构就可以了
+ 但是,我们对购物车中的商品进行增、删、改操作,基本都需要根据商品id进行判断,为了后期方便处理,我们购物车也应该是 k-v 结构,key是商品id,value 才是这个商品的购物车信息
+ 总上所述,我们购物车结构是一个双层 Map:Map<String,Map<String,CartItemInfo>>
    - 第一层 Map,key 是用户 id
    - 第二层 Map,key是购物车中商品 id,值是购物项数据![image-20210202111245926](https://gitee.com/songjianzaina/juejin_p10/raw/master/img/b0244f51d70bb11f4abfe7373a64e7d8b0ca51332fc3f4c7508d2a0285b8a7ab)

流程

编写购物车和购物项的VO

需要计算的属性,必须重写它的get方法,保证每次获取属性都会进行计算

image-20210202113359902

1
2
3
4
5
6
7
sql复制代码浏览器有一个cookie;user-key:标识用户身份,一个月后过期;
如果第一次使用jd的购物车功能,都会给一个临时的用户身份
浏览器保存,以后的每次访问都会带上
登录:session有
未登录:按照cookie里带来的user-key来做
第一次:如果没有临时用户,帮忙创建一个临时用户
--> 创建一个拦截器
拦截器
1
复制代码在执行目标方法之前,判断用户的登录状态。并封装传递给controller目标请求

添加配置让拦截器生效

image-20210202143646638

ThreadLocal:同一个线程共享数据(*)

核心原理:是一个Map,以线程为key,同一个线程可以取到相同的数据,不同线程无法共享

image-20210202140832369

效果演示

  • 未登录 – 临时用户
    • 查看购物车
    • 加入购物车
    • redis 中key为 user-key
  • 已经登录 – 登录用户
    • 会将临时用户购物车合并进用户购物车
    • 购物项增减、勾选、删除

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%