✅P241_商城业务-购物车-添加购物车
添加购物车
SkuInfoVo
cfmall-cart/src/main/java/com/gyz/cfmall/vo/SkuInfoVo.java
package com.gyz.cfmall.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class SkuInfoVo {
private Long skuId;
/**
* spuId
*/
private Long spuId;
/**
* sku名称
*/
private String skuName;
/**
* sku介绍描述
*/
private String skuDesc;
/**
* 所属分类id
*/
private Long catalogId;
/**
* 品牌id
*/
private Long brandId;
/**
* 默认图片
*/
private String skuDefaultImg;
/**
* 标题
*/
private String skuTitle;
/**
* 副标题
*/
private String skuSubtitle;
/**
* 价格
*/
private BigDecimal price;
/**
* 销量
*/
private Long saleCount;
}
Controller
添加商品到购物车的请求方法
com.gyz.cfmall.controller.CartController#addCartItem
@GetMapping("/addCartItem")
public String addCartItem(@RequestParam("skuId") Long skuId,
@RequestParam("num") Integer num,
Model model){
CartItemVo cartItemVo = cartService.addCartItem(skuId, num);
model.addAttribute("cartItem", cartItemVo);
return "success";
}
Service业务实现
cfmall-cart/src/main/java/com/gyz/cfmall/service/impl/CartServiceImpl.java
@Service
public class CartServiceImpl implements CartService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Resource
private ThreadPoolExecutor executor;
@Resource
private ProductFeignService productFeignService;
private final String CART_PREFIX = "cfmall:cart:";
@Override
public CartItemVo addCartItem(Long skuId, Integer num) throws ExecutionException, InterruptedException {
CartItemVo cartItemVo = new CartItemVo();
CompletableFuture<Void> getSkuInfoFuture = CompletableFuture.runAsync(() -> {
//1、远程查询当前要添加商品的信息
R productSkuInfo = productFeignService.skuInfo(skuId);
SkuInfoVo skuInfo = productSkuInfo.getData("skuInfo", new TypeReference<SkuInfoVo>() {
});
//数据赋值操作
cartItemVo.setSkuId(skuInfo.getSkuId());
cartItemVo.setTitle(skuInfo.getSkuTitle());
cartItemVo.setImage(skuInfo.getSkuDefaultImg());
cartItemVo.setPrice(skuInfo.getPrice());
cartItemVo.setCount(num);
}, executor);
CompletableFuture<Void> getSkuSaleAttrFuture = CompletableFuture.runAsync(() -> {
//2、获取销售属性
List<String> skuSaleAttrValues = productFeignService.getSkuSaleAttrValues(skuId);
cartItemVo.setSkuAttrValues(skuSaleAttrValues);
}, executor);
CompletableFuture.allOf(getSkuInfoFuture, getSkuSaleAttrFuture).get();
BoundHashOperations<String, Object, Object> cartOpts = getCartOpts();
String carItemInfo = JSON.toJSONString(cartItemVo);
cartOpts.put(skuId.toString(), carItemInfo);
return cartItemVo;
}
}
Feign
cfmall-cart/src/main/java/com/gyz/cfmall/feign/ProductFeignService.java
/**
* 根据skuId查询查询销售属性,pms_sku_sale_attr_value表中的信息.
*
* @param skuId
* @return
*/
@GetMapping(value = "/product/skusaleattrvalue/stringList/{skuId}")
List<String> getSkuSaleAttrValues(@PathVariable("skuId") Long skuId);
cfmall-product/src/main/java/com/gyz/cfmall/product/controller/SkuSaleAttrValueController.java
@GetMapping(value = "/stringList/{skuId}")
public List<String> getSkuSaleAttrValues(@PathVariable("skuId") Long skuId) {
List<String> stringList = skuSaleAttrValueService.getSkuSaleAttrValuesAsStringList(skuId);
return stringList;
}
cfmall-product/src/main/java/com/gyz/cfmall/product/service/impl/SkuSaleAttrValueServiceImpl.java
@Override
public List<String> getSkuSaleAttrValuesAsStringList(Long skuId) {
SkuSaleAttrValueDao baseMapper = this.baseMapper;
List<String> stringList = baseMapper.getSkuSaleAttrValuesAsStringList(skuId);
return stringList;
}
cfmall-product/src/main/resources/mapper/product/SkuSaleAttrValueDao.xml
<select id="getSkuSaleAttrValuesAsStringList" resultType="java.lang.String">
SELECT CONCAT(attr_name, ":", attr_value)
FROM pms_sku_sale_attr_value
WHERE sku_id = #{skuId}
</select>
异步编排
配置线程池
cfmall-cart/src/main/java/com/gyz/cfmall/config/ThreadPoolConfigProperties.java
package com.gyz.cfmall.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "cfmall.thread")
@Data
@Component
public class ThreadPoolConfigProperties {
/**
* 核心线程数
*/
private Integer corePoolSize;
/**
* 最大线程数
*/
private Integer maxPoolSize;
/**
* 线程最大空闲时间
*/
private Integer keepAliveTime;
}
cfmall-cart/src/main/java/com/gyz/cfmall/config/MyThreadPoolConfig.java
package com.gyz.cfmall.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
public class MyThreadPoolConfig {
@Bean
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties properties) {
return new ThreadPoolExecutor(
properties.getCorePoolSize(),
properties.getMaxPoolSize(),
properties.getKeepAliveTime(),
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(100000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
}
application.properties
#配置线程池
cfmall.thread.corePoolSize=20
cfmall.thread.maxPoolSize=200
cfmall.thread.keepAliveTime=10
前端页面调整
商品详情界面
加入购物车为绑定单击事件,url改为
**#**
避免跳转并且设置id,为超链接自定义属性,用于存储skuId
cfmall-product/src/main/resources/templates/item.html
<div class="box-btns-two">
<a href="#" id="addToCart" th:attr="skuId=${item.skuInfo.skuId}">
加入购物车
</a>
</div>
为文本框设置id:numInput
cfmall-product/src/main/resources/templates/item.html
<div class="box-btns clear">
<div class="box-btns-one">
<input type="text" name="" id="numInput" value="1"/>
<div class="box-btns-one1">
<div>
<button id="jia">
+
</button>
</div>
//代码省略...
编写单击事件
$(this)
:指当前实例;return false
: 禁止默认行为
cfmall-product/src/main/resources/templates/item.html
$("#addToCart").click(function () {
var num = $("#numInput").val();
var skuId = $(this).attr("skuId");
location.href = "http://cart.cfmall.com/addCartItem?skuId=" + skuId + "&num=" + num;
return false;
});
用户登录判断
cfmall-product/src/main/resources/templates/item.html
成功添加购物车页面
cfmall-cart/src/main/resources/templates/success.html
默认图片的显示
<div class="p-img">
<a href="/static/cart/javascript:;" target="_blank"><img
style="height: 60px;width:60px;" th:src="${cartItem.image}"></a>
</div>
商品详情页跳转以及标题显示
cfmall-cart/src/main/resources/templates/success.html
商品数量显示
cfmall-cart/src/main/resources/templates/success.html