package com.alatus.mall.cart.service.impl; import com.alatus.common.utils.R; import com.alatus.mall.cart.feign.ProductFeignService; import com.alatus.mall.cart.interceptor.CartInterceptor; import com.alatus.mall.cart.service.CartService; import com.alatus.mall.cart.vo.CartItem; import com.alatus.mall.cart.vo.SkuInfoVo; import com.alatus.mall.cart.vo.UserInfoTo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.BoundHashOperations; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ThreadPoolExecutor; @Slf4j @Service public class CartServiceImpl implements CartService { @Autowired private StringRedisTemplate redisTemplate; @Autowired private ProductFeignService productFeignService; @Autowired private ThreadPoolExecutor threadPoolExecutor; private final String CART_PREFIX = "alatusmall:cart:"; @Override public CartItem addToCart(Long skuId, Integer num) { BoundHashOperations<String, Object, Object> cartOps = getCartOps(); CartItem cartItem = new CartItem(); // 查询商品服务目前添加的商品信息 CompletableFuture<Void> getSkuInfo = CompletableFuture.runAsync(() -> { R info = productFeignService.info(skuId); if (info.getCode() == 0) { SkuInfoVo skuInfo = info.get("skuInfo", new TypeReference<SkuInfoVo>() { }); cartItem.setCheck(true); cartItem.setCount(num); cartItem.setImage(skuInfo.getSkuDefaultImg()); cartItem.setTitle(skuInfo.getSkuTitle()); cartItem.setSkuId(skuId); cartItem.setPrice(skuInfo.getPrice()); } }, threadPoolExecutor); CompletableFuture<Void> getSkuAttrValues = CompletableFuture.runAsync(() -> { // 远程查询sku的组合信息 List<String> skuSaleAttrValues = productFeignService.getSkuSaleAttrValues(skuId); cartItem.setSkuAttr(skuSaleAttrValues); }, threadPoolExecutor); cartOps.put(skuId,JSON.toJSONString(cartItem)); CompletableFuture.allOf(getSkuInfo,getSkuAttrValues); return cartItem; } // 获取我们要操作的购物车 private BoundHashOperations<String, Object, Object> getCartOps(){ UserInfoTo userInfoTo = CartInterceptor.threadLocal.get(); // 用户已登录 String cartKey = ""; if(userInfoTo.getUserId()!=null){ cartKey = CART_PREFIX + userInfoTo.getUserId(); } // 用户未登录 else{ cartKey = CART_PREFIX + userInfoTo.getUserKey(); } BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(cartKey); return operations; } }
package com.alatus.mall.cart.service.impl; import com.alatus.common.utils.R; import com.alatus.mall.cart.feign.ProductFeignService; import com.alatus.mall.cart.interceptor.CartInterceptor; import com.alatus.mall.cart.service.CartService; import com.alatus.mall.cart.vo.CartItem; import com.alatus.mall.cart.vo.SkuInfoVo; import com.alatus.mall.cart.vo.UserInfoTo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.BoundHashOperations; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ThreadPoolExecutor; @Slf4j @Service public class CartServiceImpl implements CartService { @Autowired private StringRedisTemplate redisTemplate; @Autowired private ProductFeignService productFeignService; @Autowired private ThreadPoolExecutor threadPoolExecutor; private final String CART_PREFIX = "alatusmall:cart:"; @Override public CartItem addToCart(Long skuId, Integer num) { BoundHashOperations<String, Object, Object> cartOps = getCartOps(); CartItem cartItem = new CartItem(); // 查询商品服务目前添加的商品信息 CompletableFuture<Void> getSkuInfo = CompletableFuture.runAsync(() -> { R info = productFeignService.info(skuId); if (info.getCode() == 0) { SkuInfoVo skuInfo = info.get("skuInfo", new TypeReference<SkuInfoVo>() { }); cartItem.setCheck(true); cartItem.setCount(num); cartItem.setImage(skuInfo.getSkuDefaultImg()); cartItem.setTitle(skuInfo.getSkuTitle()); cartItem.setSkuId(skuId); cartItem.setPrice(skuInfo.getPrice()); } }, threadPoolExecutor); CompletableFuture<Void> getSkuAttrValues = CompletableFuture.runAsync(() -> { // 远程查询sku的组合信息 List<String> skuSaleAttrValues = productFeignService.getSkuSaleAttrValues(skuId); cartItem.setSkuAttr(skuSaleAttrValues); }, threadPoolExecutor); cartOps.put(skuId,JSON.toJSONString(cartItem)); CompletableFuture.allOf(getSkuInfo,getSkuAttrValues); return cartItem; } // 获取我们要操作的购物车 private BoundHashOperations<String, Object, Object> getCartOps(){ UserInfoTo userInfoTo = CartInterceptor.threadLocal.get(); // 用户已登录 String cartKey = ""; if(userInfoTo.getUserId()!=null){ cartKey = CART_PREFIX + userInfoTo.getUserId(); } // 用户未登录 else{ cartKey = CART_PREFIX + userInfoTo.getUserKey(); } BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(cartKey); return operations; } }
package com.alatus.mall.product.app; import java.util.Arrays; import java.util.List; import java.util.Map; import com.alatus.mall.product.entity.SkuSaleAttrValueEntity; import com.alatus.mall.product.service.SkuSaleAttrValueService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.R; /** * sku销售属性&值 * * @author Alatus * @email 1571345941@qq.com * @date 2024-06-08 16:06:24 */ @RestController @RequestMapping("/product/skusaleattrvalue") public class SkuSaleAttrValueController { @Autowired private SkuSaleAttrValueService skuSaleAttrValueService; @GetMapping("/stringlist/{skuId}") public List<String> getSkuSaleAttrValues(@PathVariable("skuId") Long skuId){ return skuSaleAttrValueService.getSkuSaleAttrValuesAsStringList(skuId); } /** * 列表 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = skuSaleAttrValueService.queryPage(params); return R.ok().put("page", page); } /** * 信息 */ @RequestMapping("/info/{id}") public R info(@PathVariable("id") Long id){ SkuSaleAttrValueEntity pmsSkuSaleAttrValue = skuSaleAttrValueService.getById(id); return R.ok().put("pmsSkuSaleAttrValue", pmsSkuSaleAttrValue); } /** * 保存 */ @RequestMapping("/save") public R save(@RequestBody SkuSaleAttrValueEntity pmsSkuSaleAttrValue){ skuSaleAttrValueService.save(pmsSkuSaleAttrValue); return R.ok(); } /** * 修改 */ @RequestMapping("/update") public R update(@RequestBody SkuSaleAttrValueEntity pmsSkuSaleAttrValue){ skuSaleAttrValueService.updateById(pmsSkuSaleAttrValue); return R.ok(); } /** * 删除 */ @RequestMapping("/delete") public R delete(@RequestBody Long[] ids){ skuSaleAttrValueService.removeByIds(Arrays.asList(ids)); return R.ok(); } }
package com.alatus.mall.product.app; import java.util.Arrays; import java.util.List; import java.util.Map; import com.alatus.mall.product.entity.SkuSaleAttrValueEntity; import com.alatus.mall.product.service.SkuSaleAttrValueService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.alatus.common.utils.PageUtils; import com.alatus.common.utils.R; /** * sku销售属性&值 * * @author Alatus * @email 1571345941@qq.com * @date 2024-06-08 16:06:24 */ @RestController @RequestMapping("/product/skusaleattrvalue") public class SkuSaleAttrValueController { @Autowired private SkuSaleAttrValueService skuSaleAttrValueService; @GetMapping("/stringlist/{skuId}") public List<String> getSkuSaleAttrValues(@PathVariable("skuId") Long skuId){ return skuSaleAttrValueService.getSkuSaleAttrValuesAsStringList(skuId); } /** * 列表 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = skuSaleAttrValueService.queryPage(params); return R.ok().put("page", page); } /** * 信息 */ @RequestMapping("/info/{id}") public R info(@PathVariable("id") Long id){ SkuSaleAttrValueEntity pmsSkuSaleAttrValue = skuSaleAttrValueService.getById(id); return R.ok().put("pmsSkuSaleAttrValue", pmsSkuSaleAttrValue); } /** * 保存 */ @RequestMapping("/save") public R save(@RequestBody SkuSaleAttrValueEntity pmsSkuSaleAttrValue){ skuSaleAttrValueService.save(pmsSkuSaleAttrValue); return R.ok(); } /** * 修改 */ @RequestMapping("/update") public R update(@RequestBody SkuSaleAttrValueEntity pmsSkuSaleAttrValue){ skuSaleAttrValueService.updateById(pmsSkuSaleAttrValue); return R.ok(); } /** * 删除 */ @RequestMapping("/delete") public R delete(@RequestBody Long[] ids){ skuSaleAttrValueService.removeByIds(Arrays.asList(ids)); return R.ok(); } }
package com.alatus.mall.product.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 ThreadConfig { @Bean public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties threadPoolConfigProperties){ // 核心线程数,最大线程数,保持时间,单位,阻塞队列(类型和数量),线程池工厂,阻塞策略 return new ThreadPoolExecutor(threadPoolConfigProperties.getCoreSize(), threadPoolConfigProperties.getMaxSize(), threadPoolConfigProperties.getKeepAliveTime(), TimeUnit.SECONDS, new LinkedBlockingDeque<>(threadPoolConfigProperties.getBlockingDeque()), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); } }
package com.alatus.mall.product.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 ThreadConfig { @Bean public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties threadPoolConfigProperties){ // 核心线程数,最大线程数,保持时间,单位,阻塞队列(类型和数量),线程池工厂,阻塞策略 return new ThreadPoolExecutor(threadPoolConfigProperties.getCoreSize(), threadPoolConfigProperties.getMaxSize(), threadPoolConfigProperties.getKeepAliveTime(), TimeUnit.SECONDS, new LinkedBlockingDeque<>(threadPoolConfigProperties.getBlockingDeque()), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); } }
package com.alatus.mall.product.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @ConfigurationProperties(prefix = "alatusmall.thread") @Component @Data public class ThreadPoolConfigProperties { private Integer coreSize; private Integer maxSize; private Integer keepAliveTime; private Integer blockingDeque; }
package com.alatus.mall.product.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @ConfigurationProperties(prefix = "alatusmall.thread") @Component @Data public class ThreadPoolConfigProperties { private Integer coreSize; private Integer maxSize; private Integer keepAliveTime; private Integer blockingDeque; }
package com.alatus.mall.product.service; import com.alatus.mall.product.entity.SkuSaleAttrValueEntity; import com.alatus.mall.product.vo.SkuItemSaleAttrVo; import com.baomidou.mybatisplus.extension.service.IService; import com.alatus.common.utils.PageUtils; import java.util.List; import java.util.Map; /** * sku销售属性&值 * * @author Alatus * @email 1571345941@qq.com * @date 2024-06-08 16:06:24 */ public interface SkuSaleAttrValueService extends IService<SkuSaleAttrValueEntity> { PageUtils queryPage(Map<String, Object> params); List<SkuItemSaleAttrVo> getSaleAttrsBySpuId(Long spuId); List<String> getSkuSaleAttrValuesAsStringList(Long skuId); }
package com.alatus.mall.product.service; import com.alatus.mall.product.entity.SkuSaleAttrValueEntity; import com.alatus.mall.product.vo.SkuItemSaleAttrVo; import com.baomidou.mybatisplus.extension.service.IService; import com.alatus.common.utils.PageUtils; import java.util.List; import java.util.Map; /** * sku销售属性&值 * * @author Alatus * @email 1571345941@qq.com * @date 2024-06-08 16:06:24 */ public interface SkuSaleAttrValueService extends IService<SkuSaleAttrValueEntity> { PageUtils queryPage(Map<String, Object> params); List<SkuItemSaleAttrVo> getSaleAttrsBySpuId(Long spuId); List<String> getSkuSaleAttrValuesAsStringList(Long skuId); }
package com.alatus.mall.product.service.impl; import com.alatus.mall.product.dao.SkuSaleAttrValueDao; import com.alatus.mall.product.entity.SkuSaleAttrValueEntity; import com.alatus.mall.product.service.SkuSaleAttrValueService; import com.alatus.mall.product.vo.SkuItemSaleAttrVo; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; 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("pmsSkuSaleAttrValueService") public class SkuSaleAttrValueServiceImpl extends ServiceImpl<SkuSaleAttrValueDao, SkuSaleAttrValueEntity> implements SkuSaleAttrValueService { @Override public PageUtils queryPage(Map<String, Object> params) { IPage<SkuSaleAttrValueEntity> page = this.page( new Query<SkuSaleAttrValueEntity>().getPage(params), new QueryWrapper<SkuSaleAttrValueEntity>() ); return new PageUtils(page); } @Override public List<SkuItemSaleAttrVo> getSaleAttrsBySpuId(Long spuId) { List<SkuItemSaleAttrVo> skuItemSaleAttrVos = this.baseMapper.getSaleAttrsBySpuId(spuId); return skuItemSaleAttrVos; } @Override public List<String> getSkuSaleAttrValuesAsStringList(Long skuId) { return this.baseMapper.getSkuSaleAttrValuesAsStringList(skuId); } }
package com.alatus.mall.product.service.impl;
import com.alatus.mall.product.dao.SkuSaleAttrValueDao;
import com.alatus.mall.product.entity.SkuSaleAttrValueEntity;
import com.alatus.mall.product.service.SkuSaleAttrValueService;
import com.alatus.mall.product.vo.SkuItemSaleAttrVo;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
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("pmsSkuSaleAttrValueService")
public class SkuSaleAttrValueServiceImpl extends ServiceImpl<SkuSaleAttrValueDao, SkuSaleAttrValueEntity> implements SkuSaleAttrValueService {@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<SkuSaleAttrValueEntity> page = this.page(
new Query<SkuSaleAttrValueEntity>().getPage(params),
new QueryWrapper<SkuSaleAttrValueEntity>()
);return new PageUtils(page);
}@Override
public List<SkuItemSaleAttrVo> getSaleAttrsBySpuId(Long spuId) {
List<SkuItemSaleAttrVo> skuItemSaleAttrVos = this.baseMapper.getSaleAttrsBySpuId(spuId);
return skuItemSaleAttrVos;
}@Override
public List<String> getSkuSaleAttrValuesAsStringList(Long skuId) {
return this.baseMapper.getSkuSaleAttrValuesAsStringList(skuId);
}
}
package com.alatus.mall.product.dao; import com.alatus.mall.product.entity.SkuSaleAttrValueEntity; import com.alatus.mall.product.vo.Attr; import com.alatus.mall.product.vo.SkuItemSaleAttrVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * sku销售属性&值 * * @author Alatus * @email 1571345941@qq.com * @date 2024-06-08 16:06:24 */ @Mapper public interface SkuSaleAttrValueDao extends BaseMapper<SkuSaleAttrValueEntity> { List<SkuItemSaleAttrVo> getSaleAttrsBySpuId(@Param("spuId") Long spuId); List<String> getSkuSaleAttrValuesAsStringList(@Param("skuId")Long skuId); }
package com.alatus.mall.product.dao; import com.alatus.mall.product.entity.SkuSaleAttrValueEntity; import com.alatus.mall.product.vo.Attr; import com.alatus.mall.product.vo.SkuItemSaleAttrVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * sku销售属性&值 * * @author Alatus * @email 1571345941@qq.com * @date 2024-06-08 16:06:24 */ @Mapper public interface SkuSaleAttrValueDao extends BaseMapper<SkuSaleAttrValueEntity> { List<SkuItemSaleAttrVo> getSaleAttrsBySpuId(@Param("spuId") Long spuId); List<String> getSkuSaleAttrValuesAsStringList(@Param("skuId")Long skuId); }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.alatus.mall.product.dao.SkuSaleAttrValueDao"> <!-- 可根据自己的需求,是否要使用 --> <resultMap type="com.alatus.mall.product.entity.SkuSaleAttrValueEntity" id="skuSaleAttrValueMap"> <result property="id" column="id"/> <result property="skuId" column="sku_id"/> <result property="attrId" column="attr_id"/> <result property="attrName" column="attr_name"/> <result property="attrValue" column="attr_value"/> <result property="attrSort" column="attr_sort"/> </resultMap> <resultMap id="Attr" type="com.alatus.mall.product.vo.SkuItemSaleAttrVo"> <result column="attr_id" property="attrId"></result> <result column="attr_name" property="attrName"></result> <collection property="attrValues" ofType="com.alatus.mall.product.vo.AttrValueWithSkuIdVo"> <result column="attr_value" property="attrValue"></result> <result column="sku_ids" property="skuIds"></result> </collection> </resultMap> <select id="getSaleAttrsBySpuId" resultMap="Attr"> SELECT ssav.`attr_id`,ssav.`attr_name`,ssav.`attr_value`,GROUP_CONCAT(DISTINCT info.`sku_id`) sku_ids FROM pms_sku_info info LEFT JOIN pms_sku_sale_attr_value AS ssav ON info.`sku_id` = ssav.`sku_id` WHERE info.`spu_id` = #{spuId} GROUP BY ssav.`attr_id`,ssav.`attr_name`,ssav.`attr_value` </select> <select id="getSkuSaleAttrValuesAsStringList" resultType="java.lang.String"> select CONCAT(attr_name,";",attr_value) from pms_sku_info info where sku_id = #{skuId} </select> </mapper>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.alatus.mall.product.dao.SkuSaleAttrValueDao"> <!-- 可根据自己的需求,是否要使用 --> <resultMap type="com.alatus.mall.product.entity.SkuSaleAttrValueEntity" id="skuSaleAttrValueMap"> <result property="id" column="id"/> <result property="skuId" column="sku_id"/> <result property="attrId" column="attr_id"/> <result property="attrName" column="attr_name"/> <result property="attrValue" column="attr_value"/> <result property="attrSort" column="attr_sort"/> </resultMap> <resultMap id="Attr" type="com.alatus.mall.product.vo.SkuItemSaleAttrVo"> <result column="attr_id" property="attrId"></result> <result column="attr_name" property="attrName"></result> <collection property="attrValues" ofType="com.alatus.mall.product.vo.AttrValueWithSkuIdVo"> <result column="attr_value" property="attrValue"></result> <result column="sku_ids" property="skuIds"></result> </collection> </resultMap> <select id="getSaleAttrsBySpuId" resultMap="Attr"> SELECT ssav.`attr_id`,ssav.`attr_name`,ssav.`attr_value`,GROUP_CONCAT(DISTINCT info.`sku_id`) sku_ids FROM pms_sku_info info LEFT JOIN pms_sku_sale_attr_value AS ssav ON info.`sku_id` = ssav.`sku_id` WHERE info.`spu_id` = #{spuId} GROUP BY ssav.`attr_id`,ssav.`attr_name`,ssav.`attr_value` </select> <select id="getSkuSaleAttrValuesAsStringList" resultType="java.lang.String"> select CONCAT(attr_name,";",attr_value) from pms_sku_info info where sku_id = #{skuId} </select> </mapper>
package com.alatus.mall.cart.feign; import com.alatus.common.utils.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @FeignClient("Mall-product") public interface ProductFeignService { @RequestMapping("/product/skuinfo/info/{skuId}") R info(@PathVariable("skuId") Long skuId); @GetMapping("/product/skusaleattrvalue/stringlist/{skuId}") List<String> getSkuSaleAttrValues(@PathVariable("skuId") Long skuId); }
package com.alatus.mall.cart.feign; import com.alatus.common.utils.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @FeignClient("Mall-product") public interface ProductFeignService { @RequestMapping("/product/skuinfo/info/{skuId}") R info(@PathVariable("skuId") Long skuId); @GetMapping("/product/skusaleattrvalue/stringlist/{skuId}") List<String> getSkuSaleAttrValues(@PathVariable("skuId") Long skuId); }