From 6fd45be41571dbfa8955440ac92fc4f93758032c Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Wed, 10 Apr 2024 12:53:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=96=B0=E5=A2=9E):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=B4=AD=E7=89=A9=E8=BD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ssyx/common/constant/MessageConstant.java | 1 + service/service-cart/pom.xml | 6 +- .../ssyx/cart/ServiceCartApplication.java | 3 +- .../ssyx/cart/config/Knife4jConfig.java | 54 +++++++++ .../cart/controller/CartApiController.java | 48 +++++++- .../ssyx/cart/service/CartInfoService.java | 30 +++++ .../service/impl/CartInfoServiceImpl.java | 107 ++++++++++++++++++ .../service/module/CartInfoServiceModule.java | 33 ++++++ .../src/main/resources/application-dev.yml | 6 + .../src/main/resources/application.yml | 12 ++ 10 files changed, 295 insertions(+), 5 deletions(-) create mode 100644 service/service-cart/src/main/java/com/atguigu/ssyx/cart/config/Knife4jConfig.java create mode 100644 service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/module/CartInfoServiceModule.java diff --git a/common/service-util/src/main/java/com/atguigu/ssyx/common/constant/MessageConstant.java b/common/service-util/src/main/java/com/atguigu/ssyx/common/constant/MessageConstant.java index b748003..eb39b05 100644 --- a/common/service-util/src/main/java/com/atguigu/ssyx/common/constant/MessageConstant.java +++ b/common/service-util/src/main/java/com/atguigu/ssyx/common/constant/MessageConstant.java @@ -33,4 +33,5 @@ public class MessageConstant { public static final String TOKEN_IS_EMPTY = "token为空"; public static final String DATA_IS_EMPTY = "数据为空"; public static final String STOCK_LESS = "库存不足"; + public static final String SKU_NUM_CANNOT_BE_LESS = "商品数量不能再少了"; } diff --git a/service/service-cart/pom.xml b/service/service-cart/pom.xml index 872bb7e..78723a6 100644 --- a/service/service-cart/pom.xml +++ b/service/service-cart/pom.xml @@ -18,6 +18,10 @@ - + + com.atguigu + service-product-client + 1.0-SNAPSHOT + diff --git a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/ServiceCartApplication.java b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/ServiceCartApplication.java index bb81b8e..7c7a0e7 100644 --- a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/ServiceCartApplication.java +++ b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/ServiceCartApplication.java @@ -13,8 +13,7 @@ import org.springframework.context.annotation.ComponentScan; "com.atguigu.ssyx.cart", }) @EnableDiscoveryClient -// @EnableFeignClients(basePackages = "com.atguigu.ssyx.client") -@EnableFeignClients() +@EnableFeignClients(basePackages = "com.atguigu.ssyx.client") public class ServiceCartApplication { public static void main(String[] args) { SpringApplication.run(ServiceCartApplication.class, args); diff --git a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/config/Knife4jConfig.java b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/config/Knife4jConfig.java new file mode 100644 index 0000000..65080b2 --- /dev/null +++ b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/config/Knife4jConfig.java @@ -0,0 +1,54 @@ +package com.atguigu.ssyx.cart.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; + +import java.util.ArrayList; +import java.util.List; + +@Configuration +@EnableSwagger2WebMvc +public class Knife4jConfig { + @Bean + public Docket adminApiConfig() { + List pars = new ArrayList<>(); + ParameterBuilder tokenPar = new ParameterBuilder(); + tokenPar.name("adminId") + .description("用户token") + .defaultValue("1") + .modelRef(new ModelRef("string")) + .parameterType("header") + .required(false) + .build(); + pars.add(tokenPar.build()); + + return new Docket(DocumentationType.SWAGGER_2) + .groupName("购物车相关接口") + .apiInfo(adminApiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage("com.atguigu.ssyx.activity.controller")) + .paths(PathSelectors.regex("/admin/.*")) + .build() + .globalOperationParameters(pars); + } + + private ApiInfo adminApiInfo() { + return new ApiInfoBuilder() + .title("后台管理系统-API文档") + .description("本文档描述了尚上优选后台系统服务接口定义") + .version("1.0") + .contact(new Contact("atguigu", "http://atguigu.com", "atguigu")) + .build(); + } +} \ No newline at end of file diff --git a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/controller/CartApiController.java b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/controller/CartApiController.java index a47ae09..43cf144 100644 --- a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/controller/CartApiController.java +++ b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/controller/CartApiController.java @@ -1,9 +1,53 @@ package com.atguigu.ssyx.cart.controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import com.atguigu.ssyx.cart.service.CartInfoService; +import com.atguigu.ssyx.common.context.BaseContext; +import com.atguigu.ssyx.common.result.Result; +import com.atguigu.ssyx.model.order.CartInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +@Api(tags = "购物车相关接口") @RestController @RequestMapping("/api/cart") public class CartApiController { + @Autowired + private CartInfoService cartInfoService; + + @ApiOperation(value = "添加购物车") + @GetMapping("addToCart/{skuId}/{skuNum}") + public Result addToCart(@PathVariable Long skuId, @PathVariable Integer skuNum) { + Long userId = BaseContext.getUserId(); + cartInfoService.addToCart(skuId, userId, skuNum); + return Result.success(); + } + + @ApiOperation(value = "删除购物车内容") + @DeleteMapping("deleteCart/{skuId}") + public Result deleteCart(@PathVariable Long skuId) { + Long userId = BaseContext.getUserId(); + cartInfoService.deleteCart(skuId, userId); + return Result.success(); + } + + @ApiOperation(value = "清空购物车") + @DeleteMapping("deleteAllCart") + public Result deleteAllCart(HttpServletRequest request) { + Long userId = BaseContext.getUserId(); + cartInfoService.deleteAllCart(userId); + return Result.success(); + } + + @ApiOperation(value = "批量删除购物车") + @PostMapping("batchDeleteCart") + public Result batchDeleteCart(@RequestBody List skuIdList, HttpServletRequest request) { + Long userId = BaseContext.getUserId(); + cartInfoService.batchDeleteCart(userId); + return Result.success(); + } } diff --git a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/CartInfoService.java b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/CartInfoService.java index e20e707..cb7f479 100644 --- a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/CartInfoService.java +++ b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/CartInfoService.java @@ -2,4 +2,34 @@ package com.atguigu.ssyx.cart.service; public interface CartInfoService { + /** + * * 添加购物车 + * + * @param skuId 商品id + * @param userId 用户id + * @param skuNum 商品数量 + */ + void addToCart(Long skuId, Long userId, Integer skuNum); + + /** + * * 删除购物车内容 + * + * @param skuId 商品id + * @param userId 用户id + */ + void deleteCart(Long skuId, Long userId); + + /** + * * 清空购物车 + * + * @param userId 用户id + */ + void deleteAllCart(Long userId); + + /** + * * 批量删除购物车 + * + * @param userId 用户id + */ + void batchDeleteCart(Long userId); } diff --git a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/impl/CartInfoServiceImpl.java b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/impl/CartInfoServiceImpl.java index 2fdd535..df9bf0a 100644 --- a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/impl/CartInfoServiceImpl.java +++ b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/impl/CartInfoServiceImpl.java @@ -1,8 +1,115 @@ package com.atguigu.ssyx.cart.service.impl; import com.atguigu.ssyx.cart.service.CartInfoService; +import com.atguigu.ssyx.cart.service.module.CartInfoServiceModule; +import com.atguigu.ssyx.client.product.ProductFeignClient; +import com.atguigu.ssyx.common.constant.MessageConstant; +import com.atguigu.ssyx.common.exception.BunnyException; +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; + @Service public class CartInfoServiceImpl implements CartInfoService { + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private CartInfoServiceModule module; + @Autowired + private ProductFeignClient productFeignClient; + + /** + * * 添加购物车 + * + * @param skuId 商品id + * @param userId 用户id + * @param skuNum 商品数量 + */ + @Override + public void addToCart(Long skuId, Long userId, Integer skuNum) { + CartInfo cartInfo = null; + // 因为购物车数据存储在REdis中 + String cartKey = module.getCartKey(userId); + BoundHashOperations hashOperations = redisTemplate.boundHashOps(cartKey); + // 根据第一步查询的结果,得到skuId+skuNum关系 + if (Boolean.TRUE.equals(hashOperations.hasKey(skuId))) { + cartInfo = hashOperations.get(skuId); + int currentSkuNum = cartInfo.getSkuNum() + skuNum; + if (currentSkuNum <= 1) throw new BunnyException(MessageConstant.SKU_NUM_CANNOT_BE_LESS); + + // 更新cartInfo对象 + cartInfo.setSkuNum(currentSkuNum); + cartInfo.setCurrentBuyNum(currentSkuNum); + // 判断商品不能大于限购数量 + if (currentSkuNum > cartInfo.getPerLimit()) throw new BunnyException(ResultCodeEnum.SKU_LIMIT_ERROR); + // 更新其他值,加入购物车商品默认选中 + cartInfo.setIsChecked(1); + cartInfo.setUpdateTime(new Date()); + } else { + skuNum = 1; + cartInfo = new CartInfo(); + SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId).getData(); + if (skuInfo == null) { + throw new BunnyException(ResultCodeEnum.DATA_ERROR); + } + 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()); + } + + hashOperations.put(skuId.toString(), cartInfo); + module.setCartKeyExpire(cartKey); + } + + /** + * * 删除购物车内容 + * + * @param skuId 商品id + * @param userId 用户id + */ + @Override + public void deleteCart(Long skuId, Long userId) { + + } + + /** + * * 清空购物车 + * + * @param userId 用户id + */ + @Override + public void deleteAllCart(Long userId) { + + } + + /** + * * 批量删除购物车 + * + * @param userId 用户id + */ + @Override + public void batchDeleteCart(Long userId) { + + } } diff --git a/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/module/CartInfoServiceModule.java b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/module/CartInfoServiceModule.java new file mode 100644 index 0000000..8f318ec --- /dev/null +++ b/service/service-cart/src/main/java/com/atguigu/ssyx/cart/service/module/CartInfoServiceModule.java @@ -0,0 +1,33 @@ +package com.atguigu.ssyx.cart.service.module; + +import com.atguigu.ssyx.common.constant.RedisConst; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +@Component +public class CartInfoServiceModule { + @Autowired + private RedisTemplate redisTemplate; + + /** + * * 获取购物车的id + * + * @param userId 用户id + * @return 购物车的key + */ + public String getCartKey(Long userId) { + return RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX; + } + + /** + * * 过期时间 + * + * @param key Redis中的key + */ + public void setCartKeyExpire(String key) { + redisTemplate.expire(key, RedisConst.USER_CART_EXPIRE, TimeUnit.SECONDS); + } +} diff --git a/service/service-sys/src/main/resources/application-dev.yml b/service/service-sys/src/main/resources/application-dev.yml index 314bbeb..976f536 100644 --- a/service/service-sys/src/main/resources/application-dev.yml +++ b/service/service-sys/src/main/resources/application-dev.yml @@ -9,6 +9,12 @@ bunny: username: root password: "02120212" + redis: + host: 47.120.65.66 + port: 6379 + database: 3 + password: "02120212" + nacos: server-addr: z-bunny.cn:8848 discovery: diff --git a/service/service-sys/src/main/resources/application.yml b/service/service-sys/src/main/resources/application.yml index b28bf7b..df13690 100644 --- a/service/service-sys/src/main/resources/application.yml +++ b/service/service-sys/src/main/resources/application.yml @@ -14,6 +14,18 @@ spring: username: ${bunny.datasource.username} password: ${bunny.datasource.password} + redis: + host: ${bunny.redis.host} + port: ${bunny.redis.port} + database: ${bunny.redis.database} + password: ${bunny.redis.password} + lettuce: + pool: + max-active: 20 #最大连接数 + max-wait: -1 #最大阻塞等待时间(负数表示没限制) + max-idle: 5 #最大空闲 + min-idle: 0 #最小空闲 + cloud: sentinel: log: