package com.alatus.mall.product.service.impl;
import com.alatus.mall.product.CartItem;
import com.alatus.mall.product.UserInfoTo;
import com.alatus.mall.product.dao.SkuInfoDao;
import com.alatus.mall.product.entity.SkuImagesEntity;
import com.alatus.mall.product.entity.SkuInfoEntity;
import com.alatus.mall.product.entity.SpuInfoDescEntity;
import com.alatus.mall.product.service.*;
import com.alatus.mall.product.vo.SkuItemSaleAttrVo;
import com.alatus.mall.product.vo.SkuItemVo;
import com.alatus.mall.product.vo.SpuItemAttrGroupVo;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.Query;
@Service("pmsSkuInfoService")
@RabbitListener(queues = "helloJava")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {
@Autowired
private SkuImagesService skuImagesService;
@Autowired
private SpuInfoDescService spuInfoDescService;
@Autowired
private AttrGroupService attrGroupService;
@Autowired
private SkuSaleAttrValueService skuSaleAttrValueService;
@Autowired
private ThreadPoolExecutor threadPoolExecutor;
@Override
public PageUtils queryPage(Map<String, Object> params) {
QueryWrapper<SkuInfoEntity> queryWrapper = new QueryWrapper<>();
String key = (String) params.get("key");
if(!StringUtils.isEmpty(key) && !"0".equalsIgnoreCase(key)){
queryWrapper.and((wrapper) -> {
wrapper.eq("sku_id",key).or().like("sku_name",key);
});
}
String catelogId = (String) params.get("catelogId");
if(!StringUtils.isEmpty(catelogId) && !"0".equalsIgnoreCase(catelogId)){
queryWrapper.eq("catalog_id",catelogId);
}
String brandId = (String) params.get("brandId");
if(!StringUtils.isEmpty(brandId) && !"0".equalsIgnoreCase(brandId)){
queryWrapper.eq("brand_id",brandId);
}
String min = (String) params.get("min");
if(!StringUtils.isEmpty(min) && !"0".equalsIgnoreCase(min)){
queryWrapper.ge("price",min);
}
String max = (String) params.get("max");
if(!StringUtils.isEmpty(max) && !"0".equalsIgnoreCase(max)){
try{
BigDecimal maxPrice = new BigDecimal(max);
if(maxPrice.compareTo(new BigDecimal("0")) == 1){
queryWrapper.le("price",max);
}
}
catch (Exception e){
e.printStackTrace();
}
}
IPage<SkuInfoEntity> page = this.page(
new Query<SkuInfoEntity>().getPage(params),
queryWrapper
);
return new PageUtils(page);
}
@Override
public void saveSkuInfo(SkuInfoEntity skuInfoEntity) {
this.baseMapper.insert(skuInfoEntity);
}
@Override
public List<SkuInfoEntity> getSkusBySpuId(Long spuId) {
return this.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id",spuId));
}
// 同一个消息只会有一个人收到,并不会导致重复消费
// 消息接收,需要一个消息处理完,才能消费第二条
@RabbitHandler
public void getInfo(Message message, UserInfoTo userInfoTo, Channel channel){
// 这里的消息是AMQP核心包的消息
// 消息体
byte[] body = message.getBody();
// 消息头属性
MessageProperties messageProperties = message.getMessageProperties();
System.out.println(userInfoTo);
}
@RabbitHandler
public void getInfo1(Message message, CartItem cartItem, Channel channel){
// 这里的消息是AMQP核心包的消息
// 消息体
byte[] body = message.getBody();
// 消息头属性
MessageProperties messageProperties = message.getMessageProperties();
System.out.println(cartItem);
}
@Override
public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
SkuItemVo skuItemVo = new SkuItemVo();
// 设置基本信息
CompletableFuture<SkuInfoEntity> skuInfo = CompletableFuture.supplyAsync(() -> {
SkuInfoEntity skuInfoEntity = getById(skuId);
skuItemVo.setInfo(skuInfoEntity);
return skuInfoEntity;
}, threadPoolExecutor);
CompletableFuture<Void> skuImages = CompletableFuture.runAsync(() -> {
// 设置sku的图片信息
List<SkuImagesEntity> images = skuImagesService.getBySkuId(skuId);
skuItemVo.setImages(images);
}, threadPoolExecutor);
CompletableFuture<Void> saleAttr = skuInfo.thenAcceptAsync((res) -> {
// 设置spu的销售属性组合
List<SkuItemSaleAttrVo> skuItemSaleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
skuItemVo.setSaleAttr(skuItemSaleAttrVos);
}, threadPoolExecutor);
CompletableFuture<Void> spuDesc = skuInfo.thenAcceptAsync((res) -> {
// 获取spu的介绍
SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getById(res.getSpuId());
skuItemVo.setDesc(spuInfoDesc);
}, threadPoolExecutor);
CompletableFuture<Void> spuAttrGroup = skuInfo.thenAcceptAsync((res) -> {
// 获取SPU的规格参数信息
List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
skuItemVo.setGroupAttrs(attrGroupVos);
}, threadPoolExecutor);
// 等待所有任务完成后会返回数据
CompletableFuture.allOf(skuInfo,skuImages,saleAttr,spuDesc,spuAttrGroup).get();
return skuItemVo;
}
}
package com.alatus.mall.product.service.impl;
import com.alatus.mall.product.CartItem;
import com.alatus.mall.product.UserInfoTo;
import com.alatus.mall.product.dao.SkuInfoDao;
import com.alatus.mall.product.entity.SkuImagesEntity;
import com.alatus.mall.product.entity.SkuInfoEntity;
import com.alatus.mall.product.entity.SpuInfoDescEntity;
import com.alatus.mall.product.service.*;
import com.alatus.mall.product.vo.SkuItemSaleAttrVo;
import com.alatus.mall.product.vo.SkuItemVo;
import com.alatus.mall.product.vo.SpuItemAttrGroupVo;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.Query;
@Service("pmsSkuInfoService")
@RabbitListener(queues = "helloJava")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {
@Autowired
private SkuImagesService skuImagesService;
@Autowired
private SpuInfoDescService spuInfoDescService;
@Autowired
private AttrGroupService attrGroupService;
@Autowired
private SkuSaleAttrValueService skuSaleAttrValueService;
@Autowired
private ThreadPoolExecutor threadPoolExecutor;
@Override
public PageUtils queryPage(Map<String, Object> params) {
QueryWrapper<SkuInfoEntity> queryWrapper = new QueryWrapper<>();
String key = (String) params.get("key");
if(!StringUtils.isEmpty(key) && !"0".equalsIgnoreCase(key)){
queryWrapper.and((wrapper) -> {
wrapper.eq("sku_id",key).or().like("sku_name",key);
});
}
String catelogId = (String) params.get("catelogId");
if(!StringUtils.isEmpty(catelogId) && !"0".equalsIgnoreCase(catelogId)){
queryWrapper.eq("catalog_id",catelogId);
}
String brandId = (String) params.get("brandId");
if(!StringUtils.isEmpty(brandId) && !"0".equalsIgnoreCase(brandId)){
queryWrapper.eq("brand_id",brandId);
}
String min = (String) params.get("min");
if(!StringUtils.isEmpty(min) && !"0".equalsIgnoreCase(min)){
queryWrapper.ge("price",min);
}
String max = (String) params.get("max");
if(!StringUtils.isEmpty(max) && !"0".equalsIgnoreCase(max)){
try{
BigDecimal maxPrice = new BigDecimal(max);
if(maxPrice.compareTo(new BigDecimal("0")) == 1){
queryWrapper.le("price",max);
}
}
catch (Exception e){
e.printStackTrace();
}
}
IPage<SkuInfoEntity> page = this.page(
new Query<SkuInfoEntity>().getPage(params),
queryWrapper
);
return new PageUtils(page);
}
@Override
public void saveSkuInfo(SkuInfoEntity skuInfoEntity) {
this.baseMapper.insert(skuInfoEntity);
}
@Override
public List<SkuInfoEntity> getSkusBySpuId(Long spuId) {
return this.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id",spuId));
}
// 同一个消息只会有一个人收到,并不会导致重复消费
// 消息接收,需要一个消息处理完,才能消费第二条
@RabbitHandler
public void getInfo(Message message, UserInfoTo userInfoTo, Channel channel){
// 这里的消息是AMQP核心包的消息
// 消息体
byte[] body = message.getBody();
// 消息头属性
MessageProperties messageProperties = message.getMessageProperties();
System.out.println(userInfoTo);
}
@RabbitHandler
public void getInfo1(Message message, CartItem cartItem, Channel channel){
// 这里的消息是AMQP核心包的消息
// 消息体
byte[] body = message.getBody();
// 消息头属性
MessageProperties messageProperties = message.getMessageProperties();
System.out.println(cartItem);
}
@Override
public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
SkuItemVo skuItemVo = new SkuItemVo();
// 设置基本信息
CompletableFuture<SkuInfoEntity> skuInfo = CompletableFuture.supplyAsync(() -> {
SkuInfoEntity skuInfoEntity = getById(skuId);
skuItemVo.setInfo(skuInfoEntity);
return skuInfoEntity;
}, threadPoolExecutor);
CompletableFuture<Void> skuImages = CompletableFuture.runAsync(() -> {
// 设置sku的图片信息
List<SkuImagesEntity> images = skuImagesService.getBySkuId(skuId);
skuItemVo.setImages(images);
}, threadPoolExecutor);
CompletableFuture<Void> saleAttr = skuInfo.thenAcceptAsync((res) -> {
// 设置spu的销售属性组合
List<SkuItemSaleAttrVo> skuItemSaleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
skuItemVo.setSaleAttr(skuItemSaleAttrVos);
}, threadPoolExecutor);
CompletableFuture<Void> spuDesc = skuInfo.thenAcceptAsync((res) -> {
// 获取spu的介绍
SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getById(res.getSpuId());
skuItemVo.setDesc(spuInfoDesc);
}, threadPoolExecutor);
CompletableFuture<Void> spuAttrGroup = skuInfo.thenAcceptAsync((res) -> {
// 获取SPU的规格参数信息
List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
skuItemVo.setGroupAttrs(attrGroupVos);
}, threadPoolExecutor);
// 等待所有任务完成后会返回数据
CompletableFuture.allOf(skuInfo,skuImages,saleAttr,spuDesc,spuAttrGroup).get();
return skuItemVo;
}
}
package com.alatus.mall.cart.web;
import com.alatus.mall.cart.service.CartService;
import com.alatus.mall.cart.vo.Cart;
import com.alatus.mall.cart.vo.CartItem;
import com.alatus.mall.cart.vo.UserInfoTo;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.math.BigDecimal;
import java.util.concurrent.ExecutionException;
@Controller
public class CartController {
@Autowired
private CartService cartService;
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private AmqpAdmin amqpAdmin;
@GetMapping("/sendMessage")
public void sendMessage(){
for (int i = 0; i < 10; i++) {
if(i % 2 == 0){
UserInfoTo userInfoTo = new UserInfoTo();
userInfoTo.setUserKey("2323");
userInfoTo.setUserId(1L);
rabbitTemplate.convertAndSend("helloWorld","hello",userInfoTo);
}
else{
CartItem cartItem = new CartItem();
cartItem.setCount(1);
cartItem.setCheck(true);
cartItem.setPrice(new BigDecimal(1000));
rabbitTemplate.convertAndSend("helloWorld","hello",cartItem);
}
}
}
@GetMapping("/cart.html")
public String cartListPage(Model model) throws ExecutionException, InterruptedException {
Cart cart = cartService.getCart();
model.addAttribute("cart",cart);
return "cartList";
}
@GetMapping("/deleteItem")
public String deleteItem(@RequestParam("skuId")Long skuId){
cartService.deleteItem(skuId);
return "redirect:http://cart.alatusmall.com/cart.html";
}
@GetMapping("/createExchange")
public void createExchange() throws InterruptedException {
// 声明交换机
DirectExchange directExchange = new DirectExchange("helloWorld",true,false);
amqpAdmin.declareExchange(directExchange);
// 队列不能有排他性,要都能连接到这个队列才是正确的
Queue helloJava = new Queue("helloJava", true, false,false);
amqpAdmin.declareQueue(helloJava);
Thread.sleep(2000);
Binding binding = new Binding("helloJava", Binding.DestinationType.QUEUE,"helloWorld","hello",null);
amqpAdmin.declareBinding(binding);
}
@GetMapping("/countItem")
public String countItem(@RequestParam("skuId") Long skuId, @RequestParam("num") Integer num){
cartService.changeItemCount(skuId,num);
return "redirect:http://cart.alatusmall.com/cart.html";
}
@GetMapping("/addToCart")
public String addToCart(@RequestParam("skuId") Long skuId, @RequestParam("num") Integer num, RedirectAttributes model) throws ExecutionException, InterruptedException {
if(num > 0){
cartService.addToCart(skuId,num);
// RedirectAttributes的addAttribute会自动拼串,自动以参数的形式携带数据
// RedirectAttributes的addFlashAttribute()会保存在session里面,但是仅可以取一次值
model.addAttribute("skuId",skuId);
return "redirect:http://cart.alatusmall.com/addToCartSuccess.html";
}
return "redirect:http://cart.alatusmall.com/addToCartSuccess.html";
}
@GetMapping("/checkItem")
public String checkItem(@RequestParam("skuId")Long skuId,@RequestParam("check")Integer check){
cartService.checkItem(skuId,check);
return "redirect:http://cart.alatusmall.com/cart.html";
}
@GetMapping("/addToCartSuccess.html")
public String addToCartSuccessPage(@RequestParam("skuId")Long skuId,Model model){
CartItem cartItem = cartService.getCartItem(skuId);
model.addAttribute("item",cartItem);
return "success";
}
}
package com.alatus.mall.cart.web;
import com.alatus.mall.cart.service.CartService;
import com.alatus.mall.cart.vo.Cart;
import com.alatus.mall.cart.vo.CartItem;
import com.alatus.mall.cart.vo.UserInfoTo;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.math.BigDecimal;
import java.util.concurrent.ExecutionException;
@Controller
public class CartController {
@Autowired
private CartService cartService;
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private AmqpAdmin amqpAdmin;
@GetMapping("/sendMessage")
public void sendMessage(){
for (int i = 0; i < 10; i++) {
if(i % 2 == 0){
UserInfoTo userInfoTo = new UserInfoTo();
userInfoTo.setUserKey("2323");
userInfoTo.setUserId(1L);
rabbitTemplate.convertAndSend("helloWorld","hello",userInfoTo);
}
else{
CartItem cartItem = new CartItem();
cartItem.setCount(1);
cartItem.setCheck(true);
cartItem.setPrice(new BigDecimal(1000));
rabbitTemplate.convertAndSend("helloWorld","hello",cartItem);
}
}
}
@GetMapping("/cart.html")
public String cartListPage(Model model) throws ExecutionException, InterruptedException {
Cart cart = cartService.getCart();
model.addAttribute("cart",cart);
return "cartList";
}
@GetMapping("/deleteItem")
public String deleteItem(@RequestParam("skuId")Long skuId){
cartService.deleteItem(skuId);
return "redirect:http://cart.alatusmall.com/cart.html";
}
@GetMapping("/createExchange")
public void createExchange() throws InterruptedException {
// 声明交换机
DirectExchange directExchange = new DirectExchange("helloWorld",true,false);
amqpAdmin.declareExchange(directExchange);
// 队列不能有排他性,要都能连接到这个队列才是正确的
Queue helloJava = new Queue("helloJava", true, false,false);
amqpAdmin.declareQueue(helloJava);
Thread.sleep(2000);
Binding binding = new Binding("helloJava", Binding.DestinationType.QUEUE,"helloWorld","hello",null);
amqpAdmin.declareBinding(binding);
}
@GetMapping("/countItem")
public String countItem(@RequestParam("skuId") Long skuId, @RequestParam("num") Integer num){
cartService.changeItemCount(skuId,num);
return "redirect:http://cart.alatusmall.com/cart.html";
}
@GetMapping("/addToCart")
public String addToCart(@RequestParam("skuId") Long skuId, @RequestParam("num") Integer num, RedirectAttributes model) throws ExecutionException, InterruptedException {
if(num > 0){
cartService.addToCart(skuId,num);
// RedirectAttributes的addAttribute会自动拼串,自动以参数的形式携带数据
// RedirectAttributes的addFlashAttribute()会保存在session里面,但是仅可以取一次值
model.addAttribute("skuId",skuId);
return "redirect:http://cart.alatusmall.com/addToCartSuccess.html";
}
return "redirect:http://cart.alatusmall.com/addToCartSuccess.html";
}
@GetMapping("/checkItem")
public String checkItem(@RequestParam("skuId")Long skuId,@RequestParam("check")Integer check){
cartService.checkItem(skuId,check);
return "redirect:http://cart.alatusmall.com/cart.html";
}
@GetMapping("/addToCartSuccess.html")
public String addToCartSuccessPage(@RequestParam("skuId")Long skuId,Model model){
CartItem cartItem = cartService.getCartItem(skuId);
model.addAttribute("item",cartItem);
return "success";
}
}