diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 14f2070..de73cb1 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -20,6 +20,7 @@ + @@ -35,6 +36,7 @@ + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 71fa137..aa991e1 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -16,6 +16,7 @@ + diff --git a/guigu-ssyx-parent/service/pom.xml b/guigu-ssyx-parent/service/pom.xml index cc512f3..d01cdd6 100644 --- a/guigu-ssyx-parent/service/pom.xml +++ b/guigu-ssyx-parent/service/pom.xml @@ -19,6 +19,7 @@ service-activity service-user service-home + service-cart diff --git a/guigu-ssyx-parent/service/service-cart/Dockerfile b/guigu-ssyx-parent/service/service-cart/Dockerfile new file mode 100644 index 0000000..9264976 --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/Dockerfile @@ -0,0 +1,5 @@ +FROM openjdk:8-jdk-alpine +LABEL authors="yovinchen" +VOLUME /tmp +ADD ./target/service-activity.jar service-cart.jar +ENTRYPOINT ["java","-jar","/service-cart.jar", "&"] diff --git a/guigu-ssyx-parent/service/service-cart/pom.xml b/guigu-ssyx-parent/service/service-cart/pom.xml new file mode 100644 index 0000000..5acc8e6 --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + com.atguigu + service + 1.0-SNAPSHOT + + + service-cart + + + 8 + 8 + UTF-8 + + + + com.atguigu + service-product-client + 1.0-SNAPSHOT + compile + + + com.atguigu + service-product-client + 1.0-SNAPSHOT + compile + + + + diff --git a/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/ServiceCartApplication.java b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/ServiceCartApplication.java new file mode 100644 index 0000000..3570907 --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/ServiceCartApplication.java @@ -0,0 +1,23 @@ +package com.atguigu.ssyx; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * ClassName: ServiceCartApplication + * Package: com.atguigu.ssyx + * + * @author yovinchen + * @Create 2023/10/8 22:26 + */ +@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源自动配置 +@EnableDiscoveryClient +@EnableFeignClients +public class ServiceCartApplication { + public static void main(String[] args) { + SpringApplication.run(ServiceCartApplication.class, args); + } +} diff --git a/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/controller/CartApiController.java b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/controller/CartApiController.java new file mode 100644 index 0000000..6cf964f --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/controller/CartApiController.java @@ -0,0 +1,59 @@ +package com.atguigu.ssyx.cart.controller; + +import com.atguigu.ssyx.cart.service.CartInfoService; +import com.atguigu.ssyx.common.auth.AuthContextHolder; +import com.atguigu.ssyx.common.result.Result; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * ClassName: CartApiController + * Package: com.atguigu.ssyx.cart.controller + * + * @author yovinchen + * @Create 2023/10/8 22:32 + */ +@RestController +@RequestMapping("/api/cart") +public class CartApiController { + + @Autowired + private CartInfoService cartInfoService; + + //添加内容:当前登录用户id,skuId,商品数量 + @ApiOperation(value = "添加商品到购物车") + @GetMapping("addToCart/{skuId}/{skuNum}") + public Result addToCart(@PathVariable("skuId") Long skuId, @PathVariable("skuNum") Integer skuNum) { + //获取当前登录用户Id + Long userId = AuthContextHolder.getUserId(); + cartInfoService.addToCart(userId, skuId, skuNum); + return Result.ok(null); + } + + @ApiOperation(value = "根据skuId删除购物车") + @DeleteMapping("deleteCart/{skuId}") + public Result deleteCart(@PathVariable("skuId") Long skuId) { + Long userId = AuthContextHolder.getUserId(); + cartInfoService.deleteCart(skuId, userId); + return Result.ok(null); + } + + @ApiOperation(value = "清空购物车") + @DeleteMapping("deleteAllCart") + public Result deleteAllCart() { + Long userId = AuthContextHolder.getUserId(); + cartInfoService.deleteAllCart(userId); + return Result.ok(null); + } + + @ApiOperation(value = "批量删除购物车 多个skuId") + @DeleteMapping("batchDeleteCart") + public Result batchDeleteCart(@RequestBody List skuIdList) { + Long userId = AuthContextHolder.getUserId(); + cartInfoService.batchDeleteCart(skuIdList, userId); + return Result.ok(null); + } +} diff --git a/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/CartInfoService.java b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/CartInfoService.java new file mode 100644 index 0000000..9821ac5 --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/CartInfoService.java @@ -0,0 +1,44 @@ +package com.atguigu.ssyx.cart.service; + +import java.util.List; + +/** + * ClassName: CartInfoService + * Package: com.atguigu.ssyx.cart.service + * + * @author yovinchen + * @Create 2023/10/8 22:33 + */ +public interface CartInfoService { + /** + * 添加商品到购物车 + * + * @param userId + * @param skuId + * @param skuNum + */ + void addToCart(Long userId, Long skuId, Integer skuNum); + + /** + * 根据skuId删除购物车 + * + * @param skuId + * @param userId + */ + void deleteCart(Long skuId, Long userId); + + /** + * 清空购物车 + * + * @param userId + */ + void deleteAllCart(Long userId); + + /** + * 批量删除购物车 + * + * @param skuIdList + * @param userId + */ + void batchDeleteCart(List skuIdList, Long userId); +} diff --git a/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/impl/CartInfoServiceImpl.java b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/impl/CartInfoServiceImpl.java new file mode 100644 index 0000000..8250061 --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/impl/CartInfoServiceImpl.java @@ -0,0 +1,171 @@ +package com.atguigu.ssyx.cart.service.impl; + +import com.atguigu.ssyx.cart.service.CartInfoService; +import com.atguigu.ssyx.client.product.ProductFeignClient; +import com.atguigu.ssyx.common.constant.RedisConst; +import com.atguigu.ssyx.common.exception.SsyxException; +import com.atguigu.ssyx.common.result.ResultCodeEnum; +import com.atguigu.ssyx.enums.SkuType; +import com.atguigu.ssyx.model.order.CartInfo; +import com.atguigu.ssyx.model.product.SkuInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundHashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * ClassName: CartInfoServiceImpl + * Package: com.atguigu.ssyx.cart.service.impl + * + * @author yovinchen + * @Create 2023/10/8 22:34 + */ +@Service +public class CartInfoServiceImpl implements CartInfoService { + + @Autowired + private ProductFeignClient productFeignClient; + + @Autowired + private RedisTemplate redisTemplate; + + + //返回购物车在redis的key + private String getCartKey(Long userId) { + return RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX; + } + + //设置key 过期时间 + private void setCartKeyExpire(String key) { + redisTemplate.expire(key, RedisConst.USER_CART_EXPIRE, TimeUnit.SECONDS); + } + + /** + * 添加商品到购物车 + * + * @param userId + * @param skuId + * @param skuNum + */ + @Override + public void addToCart(Long userId, Long skuId, Integer skuNum) { +//1 因为购物车数据存储到redis里面, + // 从redis里面根据key获取数据,这个key包含userId + String cartKey = this.getCartKey(userId); + BoundHashOperations hashOperations = redisTemplate.boundHashOps(cartKey); + + //2 根据第一步查询出来的结果,得到是skuId + skuNum关系 + CartInfo cartInfo = null; + //目的:判断是否是第一次添加这个商品到购物车 + // 进行判断,判断结果里面,是否有skuId + if (hashOperations.hasKey(skuId.toString())) { + //3 如果结果里面包含skuId,不是第一次添加 + //3.1 根据skuId,获取对应数量,更新数量 + cartInfo = hashOperations.get(skuId.toString()); + //把购物车存在商品之前数量获取数量,在进行数量更新操作 + Integer currentSkuNum = cartInfo.getSkuNum() + skuNum; + if (currentSkuNum < 1) { + return; + } + + //更新cartInfo对象 + cartInfo.setSkuNum(currentSkuNum); + cartInfo.setCurrentBuyNum(currentSkuNum); + + //判断商品数量不能大于限购数量 + Integer perLimit = cartInfo.getPerLimit(); + if (currentSkuNum > perLimit) { + throw new SsyxException(ResultCodeEnum.SKU_LIMIT_ERROR); + } + + //更新其他值 + cartInfo.setIsChecked(1); + cartInfo.setUpdateTime(new Date()); + } else { + //4 如果结果里面没有skuId,就是第一次添加 + //4.1 直接添加 + skuNum = 1; + + //远程调用根据skuId获取skuInfo + SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId); + if (skuInfo == null) { + throw new SsyxException(ResultCodeEnum.DATA_ERROR); + } + + //封装cartInfo对象 + cartInfo = new CartInfo(); + cartInfo.setSkuId(skuId); + cartInfo.setCategoryId(skuInfo.getCategoryId()); + cartInfo.setSkuType(skuInfo.getSkuType()); + cartInfo.setIsNewPerson(skuInfo.getIsNewPerson()); + cartInfo.setUserId(userId); + cartInfo.setCartPrice(skuInfo.getPrice()); + cartInfo.setSkuNum(skuNum); + cartInfo.setCurrentBuyNum(skuNum); + cartInfo.setSkuType(SkuType.COMMON.getCode()); + cartInfo.setPerLimit(skuInfo.getPerLimit()); + cartInfo.setImgUrl(skuInfo.getImgUrl()); + cartInfo.setSkuName(skuInfo.getSkuName()); + cartInfo.setWareId(skuInfo.getWareId()); + cartInfo.setIsChecked(1); + cartInfo.setStatus(1); + cartInfo.setCreateTime(new Date()); + cartInfo.setUpdateTime(new Date()); + } + + //5 更新redis缓存 + hashOperations.put(skuId.toString(), cartInfo); + + //6 设置有效时间 + this.setCartKeyExpire(cartKey); + } + + /** + * 根据skuId删除购物车 + * + * @param skuId + * @param userId + */ + @Override + public void deleteCart(Long skuId, Long userId) { + BoundHashOperations hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId)); + if (hashOperations.hasKey(skuId.toString())) { + hashOperations.delete(skuId.toString()); + } + } + + /** + * 清空购物车 + * + * @param userId + */ + @Override + public void deleteAllCart(Long userId) { + String cartKey = this.getCartKey(userId); + BoundHashOperations hashOperations = redisTemplate.boundHashOps(cartKey); + List cartInfoList = hashOperations.values(); + for (CartInfo cartInfo : cartInfoList) { + hashOperations.delete(cartInfo.getSkuId() + .toString()); + } + } + + /** + * 批量删除购物车 + * + * @param skuIdList + * @param userId + */ + @Override + public void batchDeleteCart(List skuIdList, Long userId) { + String cartKey = this.getCartKey(userId); + BoundHashOperations hashOperations = redisTemplate.boundHashOps(cartKey); + skuIdList.forEach(skuId -> { + hashOperations.delete(skuId.toString()); + }); + } +} diff --git a/guigu-ssyx-parent/service/service-cart/src/main/resources/application-dev.yml b/guigu-ssyx-parent/service/service-cart/src/main/resources/application-dev.yml new file mode 100644 index 0000000..d685efb --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/src/main/resources/application-dev.yml @@ -0,0 +1,29 @@ +server: + port: 8208 + +feign: + sentinel: + enabled: true + client: + config: + default: #配置全局的feign的调用超时时间 如果 有指定的服务配置 默认的配置不会生效 + connectTimeout: 30000 # 指定的是 消费者 连接服务提供者的连接超时时间 是否能连接 单位是毫秒 + readTimeout: 50000 # 指定的是调用服务提供者的 服务 的超时时间() 单位是毫秒 +spring: + main: + allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册 + redis: + host: 82.157.68.223 + port: 6379 + database: 0 + timeout: 1800000 + password: + lettuce: + pool: + max-active: 20 #最大连接数 + max-wait: -1 #最大阻塞等待时间(负数表示没限制) + max-idle: 5 #最大空闲 + min-idle: 0 #最小空闲 + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 diff --git a/guigu-ssyx-parent/service/service-cart/src/main/resources/application.yml b/guigu-ssyx-parent/service/service-cart/src/main/resources/application.yml new file mode 100644 index 0000000..6321d93 --- /dev/null +++ b/guigu-ssyx-parent/service/service-cart/src/main/resources/application.yml @@ -0,0 +1,11 @@ +spring: + application: + name: service-cart + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 82.157.68.223:8848 + username: nacos + password: nacos