1.创建购物车服务
1.1.创建购物车服务模块
gmall-cart
1.2.域名映射及网关配置
192.168.139.10 cart.gmall.com
spring:
cloud:
gateway:
route:
- id: gmall_cart_route
uri: lb://gmall-cart
predicates:
- Host=cart.gmall.com
1.3.Nginx动静分离
1.3.1.静态资源
1.3.2.模板页面
- cartList.html
- success.html
修改模板页面静态资源链接地址,以 /static/cart/ 开头
2.购物车需求
2.1.需求描述
-
用户可以在登录状态下将商品添加到购物车【登录购物车/在线购物车】
- 数据库
- MongoDB
- Redis(采用)
登录以后,会将离线购物车的数据全部合并,并清空临时购物车
-
用户可以在未登录状态下将商品添加到购物车【游客购物车/离线购物车】
- Local Storage
- Cookie
- Redis(采用)
浏览器即使关闭,下次进入,临时购物车数据都在
-
用户可以使用购物车一起结算下单
-
用户可以查询自己的购物车
-
用户可以在购物车中修改购买商品的数量
-
用户可以在购物车中删除商品
-
在购物车中展示商品优惠信息
-
提示购物车商品价格变化
2.2.数据结构
每一个购物项信息,都是一个对象,基本字段包括
{
skuId: 1
check: true,
title: "Apple iPhone 12",
defaultImage: "",
price: 9299,
count: 1,
totalPrice: 9299,
skuSaleVO: { ... }
}
另外,购物车中不止一条数据,因此最终会是对象的数组
[
{ ... },{ ... },{ ... }
]
综上,购物车结构是一个双层Map: Map<String, Map<String,String>>
- 第一层Map,key是用户id
- 第二层Map,key是购物车中商品id,value是购物项数据
2.2.1.购物车VO
CartVO
package com.atguigu.gmall.cart.vo;
import java.math.BigDecimal;
import java.util.List;
/**
* 购物车 {@link CartVO}
*
* @author zhangwen
* @email: 1466787185@qq.com
*/
public class CartVO {
/**
* 购物项
*/
private List<CartItemVO> items;
/**
* 商品数量
*/
private Integer countNum;
/**
* 商品类型数量
*/
private Integer countType;
/**
* 商品总价
*/
private BigDecimal totalAmount;
/**
* 减免价格
*/
private BigDecimal reduce;
public CartVO() {
reduce = new BigDecimal("0");
}
public List<CartItemVO> getItems() {
return items;
}
public void setItems(List<CartItemVO> items) {
this.items = items;
}
/**
* 计算商品总数量
* @return
*/
public Integer getCountNum() {
int count = 0;
if (items != null && items.size() > 0) {
for (CartItemVO item : items) {
count += item.getCount();
}
}
return count;
}
/**
* 计算商品类型数量
* @return
*/
public Integer getCountType() {
int count = 0;
if (items != null && items.size() > 0) {
for (CartItemVO item : items) {
count += 1;
}
}
return count;
}
/**
* 计算商品总金额
* @return
*/
public BigDecimal getTotalAmount() {
BigDecimal amount = new BigDecimal("0");
// 计算购物项总价
if (items != null && items.size() > 0) {
for (CartItemVO item : items) {
// 只有勾选的商品才计算总价
if (item.getCheck()) {
BigDecimal totalPrice = item.getTotalPrice();
amount = amount.add(totalPrice);
}
}
}
// 减去优惠总价
amount = amount.subtract(getReduce());
return amount;
}
public BigDecimal getReduce() {
return reduce;
}
public void setReduce(BigDecimal reduce) {
this.reduce = reduce;
}
}
CartItemVO
package com.atguigu.gmall.cart.vo;
import java.math.BigDecimal;
import java.util.List;
/**
* 购物项 {@link CartItemVO}
*
* @author zhangwen
* @email: 1466787185@qq.com
*/
public class CartItemVO {
private Long skuId;
private Boolean check;
private String title;
private String image;
private List<String> skuAttr;
private BigDecimal price;
private Integer count;
private BigDecimal totalPrice;
public CartItemVO() {
check = true;
}
public Long getSkuId() {
return skuId;
}
public void setSkuId(Long skuId) {
this.skuId = skuId;
}
public Boolean getCheck() {
return check;
}
public void setCheck(Boolean check) {
this.check = check;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public List<String> getSkuAttr() {
return skuAttr;
}
public void setSkuAttr(List<String> skuAttr) {
this.skuAttr = skuAttr;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
/**
* 计算购物车当前项商品总价
* @return
*/
public BigDecimal getTotalPrice() {
return price.multiply(new BigDecimal("" + count));
}
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}
}