feat(新增): 添加购物车

This commit is contained in:
bunny 2024-04-10 12:53:25 +08:00
parent 4a5477af0f
commit 6fd45be415
10 changed files with 295 additions and 5 deletions

View File

@ -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 = "商品数量不能再少了";
}

View File

@ -18,6 +18,10 @@
</properties>
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service-product-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -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);

View File

@ -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<Parameter> 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();
}
}

View File

@ -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<CartInfo> 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<CartInfo> deleteCart(@PathVariable Long skuId) {
Long userId = BaseContext.getUserId();
cartInfoService.deleteCart(skuId, userId);
return Result.success();
}
@ApiOperation(value = "清空购物车")
@DeleteMapping("deleteAllCart")
public Result<CartInfo> deleteAllCart(HttpServletRequest request) {
Long userId = BaseContext.getUserId();
cartInfoService.deleteAllCart(userId);
return Result.success();
}
@ApiOperation(value = "批量删除购物车")
@PostMapping("batchDeleteCart")
public Result<CartInfo> batchDeleteCart(@RequestBody List<Long> skuIdList, HttpServletRequest request) {
Long userId = BaseContext.getUserId();
cartInfoService.batchDeleteCart(userId);
return Result.success();
}
}

View File

@ -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);
}

View File

@ -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<String, Object> 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<String, String, CartInfo> 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) {
}
}

View File

@ -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<String, Object> 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);
}
}

View File

@ -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:

View File

@ -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: