|
|
|
@ -31,211 +31,452 @@ import java.util.List;
|
|
|
|
|
*/
|
|
|
|
|
@Service
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class CartServiceImpl implements ICartService{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// CartServiceImpl类实现了ICartService接口,意味着它需要实现该接口中定义的所有方法,
|
|
|
|
|
// 这个类主要负责处理购物车相关的具体业务逻辑,例如添加商品到购物车、更新购物车中商品数量等操作,
|
|
|
|
|
// 通过调用其他组件(如CartMapper、ProductClient、CommonCacheUtil等)来协同完成业务功能,并将结果以ServerResponse的形式返回给上层调用者(如控制层)。
|
|
|
|
|
public class CartServiceImpl implements ICartService {
|
|
|
|
|
|
|
|
|
|
// 通过Spring的依赖注入机制,自动注入CartMapper接口的实现类对象。
|
|
|
|
|
// CartMapper用于与数据库进行交互,执行如查询、插入、更新、删除购物车相关记录等数据库操作,
|
|
|
|
|
// 在这里的各个购物车业务方法中会频繁调用它来完成持久化层面的工作,实现业务逻辑与数据访问的分离。
|
|
|
|
|
@Autowired
|
|
|
|
|
private CartMapper cartMapper;
|
|
|
|
|
|
|
|
|
|
// 同样通过依赖注入注入ProductClient对象。
|
|
|
|
|
// ProductClient通常是用于和外部的商品服务进行通信的客户端,比如在购物车业务中,需要获取商品的详细信息(是否下架、库存情况等)时,
|
|
|
|
|
// 就会通过这个客户端去调用商品服务提供的接口来获取相应数据,实现不同微服务之间的协作。
|
|
|
|
|
@Autowired
|
|
|
|
|
private ProductClient productClient;
|
|
|
|
|
|
|
|
|
|
// 注入CommonCacheUtil对象,用于与缓存系统进行交互操作。
|
|
|
|
|
// 在处理购物车业务时,可能会频繁用到商品相关信息,通过缓存可以减少重复查询数据库的次数,提高系统性能。
|
|
|
|
|
// 例如先从缓存中查找商品信息,如果缓存中不存在再去查询数据库,并将查询到的数据存入缓存供后续使用。
|
|
|
|
|
@Autowired
|
|
|
|
|
private CommonCacheUtil commonCacheUtil;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现ICartService接口中定义的添加商品到购物车的方法。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,它是确定购物车归属的关键,若该值为null,表示用户未登录,不符合添加商品到购物车的前置条件,
|
|
|
|
|
* 此时会抛出SnailmallException异常,由上层(如控制层)进行捕获并处理,告知客户端用户未登录的情况。
|
|
|
|
|
* @param productId 要添加到购物车的商品的唯一标识符,若为null,说明传入的参数不完整,无法明确要添加的具体商品,
|
|
|
|
|
* 会返回一个表示参数不正确的ServerResponse对象给客户端,提示用户修正参数。
|
|
|
|
|
* @param count 要添加到购物车的商品数量,同样不能为null,若为null则也返回参数不正确的提示响应,代表了此次操作中对应商品添加的具体数量。
|
|
|
|
|
* @return 返回一个ServerResponse对象,该对象封装了添加商品到购物车操作的结果信息,
|
|
|
|
|
* 如果操作成功,其内部会包含代表成功的数据(在这里是构建好的CartVo对象,包含了购物车相关详细信息,例如商品列表、总价等内容),
|
|
|
|
|
* 若操作失败,则包含相应的错误提示消息等内容,方便调用者(比如控制层)根据返回结果判断操作是否成功,并将相应信息返回给前端展示给用户或者进行其他后续处理。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse add(Integer userId, Integer productId, Integer count) {
|
|
|
|
|
//1.校验参数
|
|
|
|
|
if(userId == null){
|
|
|
|
|
// 1. 校验参数
|
|
|
|
|
// 首先检查用户ID是否为null,如果为null,意味着用户没有登录,这不符合添加商品到购物车的业务要求,所以抛出SnailmallException异常,
|
|
|
|
|
// 异常信息为"用户未登陆",后续在合适的地方(比如控制层)可以捕获这个异常并返回相应提示给客户端,告知用户需要先登录才能进行添加操作。
|
|
|
|
|
if (userId == null) {
|
|
|
|
|
throw new SnailmallException("用户未登陆");
|
|
|
|
|
}
|
|
|
|
|
if(productId == null || count == null){
|
|
|
|
|
// 接着检查商品ID和商品数量是否为null,如果这两个参数中有任何一个为null,说明传入的参数不符合要求,无法准确执行添加商品的操作,
|
|
|
|
|
// 此时返回一个通过ServerResponse.createByErrorMessage方法创建的表示参数不正确的响应对象给客户端,提示用户检查并修正传入的参数。
|
|
|
|
|
if (productId == null || count == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("参数不正确");
|
|
|
|
|
}
|
|
|
|
|
//2.校验商品
|
|
|
|
|
String productStr = commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX+productId);
|
|
|
|
|
|
|
|
|
|
// 2. 校验商品
|
|
|
|
|
// 尝试从缓存中获取商品信息,缓存的键是通过Constants.PRODUCT_TOKEN_PREFIX加上商品ID拼接而成的,
|
|
|
|
|
// 这样可以根据不同的商品ID来准确地在缓存中查找对应的商品缓存数据,提高获取商品信息的效率,避免频繁访问数据库。
|
|
|
|
|
String productStr = commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX + productId);
|
|
|
|
|
Product product = null;
|
|
|
|
|
if(productStr == null){
|
|
|
|
|
// 如果从缓存中获取到的商品信息字符串为null,说明缓存中不存在该商品的相关信息,此时需要通过ProductClient去远程调用商品服务来查询商品详情。
|
|
|
|
|
if (productStr == null) {
|
|
|
|
|
// 调用ProductClient的queryProduct方法,传入商品ID作为参数,向商品服务发起查询请求,获取包含商品信息的ServerResponse对象。
|
|
|
|
|
ServerResponse response = productClient.queryProduct(productId);
|
|
|
|
|
// 从ServerResponse对象中获取其包含的商品数据部分(可能是一个Object类型的对象,具体内容由商品服务返回的数据结构决定)。
|
|
|
|
|
Object object = response.getData();
|
|
|
|
|
// 使用JsonUtil工具类的obj2String方法将获取到的商品数据对象转换为字符串形式,方便后续进行反序列化操作。
|
|
|
|
|
String objStr = JsonUtil.obj2String(object);
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(objStr,Product.class);
|
|
|
|
|
}else {
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(productStr,Product.class);
|
|
|
|
|
// 再通过JsonUtil的Str2Obj方法将字符串形式的商品信息反序列化为Product对象,以便后续在业务逻辑中使用商品的各个属性进行相关判断和操作。
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(objStr, Product.class);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果缓存中存在商品信息字符串,则直接使用JsonUtil的Str2Obj方法将其反序列化为Product对象,避免了再次远程查询商品服务的开销。
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(productStr, Product.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(product == null){
|
|
|
|
|
// 如果经过上述步骤获取到的商品对象为null,说明商品不存在,可能是商品ID有误或者商品已经被彻底删除等原因,
|
|
|
|
|
// 此时返回一个通过ServerResponse.createByErrorMessage方法创建的表示商品不存在的响应对象给客户端,告知用户无法添加不存在的商品到购物车。
|
|
|
|
|
if (product == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("商品不存在");
|
|
|
|
|
}
|
|
|
|
|
if(!product.getStatus().equals(Constants.Product.PRODUCT_ON)){
|
|
|
|
|
// 检查商品的状态是否为Constants.Product.PRODUCT_ON(这个常量应该是在业务中定义好的,表示商品处于正常可售卖状态的标识),
|
|
|
|
|
// 如果商品状态不等于这个正常可售卖状态标识,说明商品可能已经下架或者被删除了,不应该再添加到购物车中,
|
|
|
|
|
// 所以返回一个表示商品下架或者删除的错误提示响应对象给客户端。
|
|
|
|
|
if (!product.getStatus().equals(Constants.Product.PRODUCT_ON)) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("商品下架或者删除");
|
|
|
|
|
}
|
|
|
|
|
//3.根据商品或者购物车,购物车存在则增加商品数量即可,不存在则创建新的购物车,一个用户对应一个购物车
|
|
|
|
|
Cart cart = cartMapper.selectByUserIdProductId(userId,productId);
|
|
|
|
|
if (cart == null){
|
|
|
|
|
|
|
|
|
|
// 3. 根据商品或者购物车,购物车存在则增加商品数量即可,不存在则创建新的购物车,一个用户对应一个购物车
|
|
|
|
|
// 通过CartMapper的selectByUserIdProductId方法,根据传入的用户ID和商品ID去数据库中查询购物车中是否已经存在该商品的记录,
|
|
|
|
|
// 如果不存在(即查询返回的Cart对象为null),则表示该用户的购物车中还没有添加过这个商品,需要创建一个新的购物车记录。
|
|
|
|
|
Cart cart = cartMapper.selectByUserIdProductId(userId, productId);
|
|
|
|
|
if (cart == null) {
|
|
|
|
|
// 创建一个新的Cart对象,用于表示要插入到数据库中的购物车记录信息。
|
|
|
|
|
Cart cartItem = new Cart();
|
|
|
|
|
// 设置新购物车记录的用户ID,关联到对应的用户,表示这个购物车是属于哪个用户的。
|
|
|
|
|
cartItem.setUserId(userId);
|
|
|
|
|
// 设置商品ID,明确购物车中存放的是哪个商品。
|
|
|
|
|
cartItem.setProductId(productId);
|
|
|
|
|
// 设置商品数量,即此次要添加到购物车的商品数量。
|
|
|
|
|
cartItem.setQuantity(count);
|
|
|
|
|
// 设置商品的选中状态,这里设置为Constants.Cart.CHECKED(应该是在业务中定义好的表示选中的常量),表示默认添加到购物车后商品是选中状态,具体选中含义可根据业务逻辑确定,比如是否参与总价计算等。
|
|
|
|
|
cartItem.setChecked(Constants.Cart.CHECKED);
|
|
|
|
|
|
|
|
|
|
// 通过CartMapper的insert方法将新创建的购物车记录插入到数据库中,该方法会返回受影响的行数,正常插入成功应该返回1,
|
|
|
|
|
// 如果返回值为0,表示插入操作失败,可能是数据库出现问题或者其他原因导致插入不成功,此时返回一个表示添加购物车失败的错误提示响应对象给客户端。
|
|
|
|
|
int resultCount = cartMapper.insert(cartItem);
|
|
|
|
|
if(resultCount == 0){
|
|
|
|
|
if (resultCount == 0) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("添加购物车失败");
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
cart.setQuantity(cart.getQuantity()+count);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果购物车中已经存在该商品的记录,说明之前已经添加过这个商品到购物车了,此时只需要更新商品的数量即可,
|
|
|
|
|
// 将原有的商品数量加上此次要添加的数量,更新Cart对象中的quantity属性。
|
|
|
|
|
cart.setQuantity(cart.getQuantity() + count);
|
|
|
|
|
// 通过CartMapper的updateByPrimaryKeySelective方法,根据更新后的Cart对象去更新数据库中对应的购物车记录,
|
|
|
|
|
// 这个方法会根据Cart对象中不为null的属性来更新数据库相应字段,返回受影响的行数,若返回0则表示更新失败,同样返回添加购物车失败的提示响应给客户端。
|
|
|
|
|
int resultCount = cartMapper.updateByPrimaryKeySelective(cart);
|
|
|
|
|
if(resultCount == 0){
|
|
|
|
|
if (resultCount == 0) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("添加购物车失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//构建购物车信息,返回给前端,并且要检查库存
|
|
|
|
|
CartVo cartVo = getCartVoLimit(userId,true);
|
|
|
|
|
|
|
|
|
|
// 构建购物车信息,返回给前端,并且要检查库存
|
|
|
|
|
// 调用getCartVoLimit方法来构建包含购物车详细信息的CartVo对象,这个方法内部会进一步处理购物车中商品的各种信息,
|
|
|
|
|
// 比如获取商品的详细信息(可能再次从缓存或远程查询商品服务获取更详细数据)、判断库存情况、计算购物车商品的总价等操作,
|
|
|
|
|
// 最后返回一个表示操作成功且包含构建好的CartVo对象的ServerResponse对象给客户端,告知用户添加商品到购物车操作成功,并将购物车的详细信息返回给前端展示给用户。
|
|
|
|
|
CartVo cartVo = getCartVoLimit(userId, true);
|
|
|
|
|
return ServerResponse.createBySuccess(cartVo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现ICartService接口中定义的更新购物车中某个商品数量的方法。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是哪个用户的购物车中的商品数量需要更新,是操作的关键依据,若为null则不符合业务逻辑(但此处未做处理,可根据实际情况完善),
|
|
|
|
|
* 类型为整数类型,在整个购物车业务体系中关联到具体的用户账户。
|
|
|
|
|
* @param productId 要更新数量的商品的唯一标识符,若为null,说明没有明确要更新数量的具体商品,无法进行更新操作,
|
|
|
|
|
* 会返回一个表示参数错误的ServerResponse对象给客户端,提示用户传入正确的商品ID参数,类型为整数类型,用于在购物车记录中准确找到对应的商品。
|
|
|
|
|
* @param count 要更新为的商品数量,同样不能为null,若为null则返回参数错误的提示响应,代表了更新后该商品在购物车中应有的具体数量,类型为整数类型。
|
|
|
|
|
* @return 返回一个ServerResponse对象,该对象封装了更新购物车商品数量操作的结果信息,
|
|
|
|
|
* 如果操作成功,内部包含代表成功的数据(即构建好的CartVo对象,包含了更新数量后购物车的详细信息,例如商品列表、总价等情况),
|
|
|
|
|
* 若操作失败,则包含相应的错误提示消息等内容,方便调用者(如控制层)根据返回结果判断操作是否成功,并进行相应的处理(如返回给前端提示信息等)。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse update(Integer userId, Integer productId, Integer count) {
|
|
|
|
|
if(productId == null || count == null){
|
|
|
|
|
// 首先对传入的参数进行校验,如果商品ID或者商品数量为null,说明参数不符合要求,无法进行更新操作,
|
|
|
|
|
// 此时返回一个通过ServerResponse.createByErrorMessage方法创建的表示参数错误的响应对象给客户端,提示用户修正传入的参数。
|
|
|
|
|
if (productId == null || count == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("参数错误");
|
|
|
|
|
}
|
|
|
|
|
Cart cart = cartMapper.selectByUserIdProductId(userId,productId);
|
|
|
|
|
if(cart == null){
|
|
|
|
|
|
|
|
|
|
// 通过CartMapper的selectByUserIdProductId方法,根据传入的用户ID和商品ID去数据库中查询购物车中是否存在对应的商品记录,
|
|
|
|
|
// 如果不存在(即查询返回的Cart对象为null),说明要更新数量的商品在购物车中不存在,无法进行更新操作,
|
|
|
|
|
// 此时返回一个表示购物车不存在的错误提示响应对象给客户端,告知用户无法进行更新。
|
|
|
|
|
Cart cart = cartMapper.selectByUserIdProductId(userId, productId);
|
|
|
|
|
if (cart == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("购物车不存在");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果找到了对应的购物车商品记录,将Cart对象中的quantity属性设置为新传入的商品数量值,准备更新数据库中的对应记录。
|
|
|
|
|
cart.setQuantity(count);
|
|
|
|
|
// 通过CartMapper的updateByPrimaryKeySelective方法,根据更新后的Cart对象去更新数据库中对应的购物车记录,
|
|
|
|
|
// 该方法会根据Cart对象中不为null的属性来更新数据库相应字段,返回受影响的行数,若返回0则表示更新失败,返回一个表示更新购物车失败的错误提示响应给客户端。
|
|
|
|
|
int updateCount = cartMapper.updateByPrimaryKeySelective(cart);
|
|
|
|
|
if(updateCount == 0){
|
|
|
|
|
if (updateCount == 0) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("更新购物车失败");
|
|
|
|
|
}
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId,true);
|
|
|
|
|
|
|
|
|
|
// 调用getCartVoLimit方法构建包含更新后购物车详细信息的CartVo对象,这个方法会进一步处理购物车商品的相关信息(如获取商品详情、判断库存、计算总价等),
|
|
|
|
|
// 最后返回一个表示操作成功且包含构建好的CartVo对象的ServerResponse对象给客户端,告知用户更新购物车商品数量操作成功,并将购物车的详细信息返回给前端展示给用户。
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId, true);
|
|
|
|
|
return ServerResponse.createBySuccess(cartVo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现ICartService接口中定义的从购物车中删除指定商品的方法。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是哪个用户的购物车进行商品删除操作,若为null不符合业务逻辑(此处未做额外处理,可按需完善),
|
|
|
|
|
* 通过它能精准定位到对应用户的购物车记录,类型为整数类型。
|
|
|
|
|
* @param productIds 表示要删除的商品的标识信息,格式为以逗号分隔的字符串,例如"1,2,3"表示要删除ID为1、2、3的商品,
|
|
|
|
|
* 若为空字符串或者格式不符合要求(无法解析出有效的商品ID列表)则返回表示参数错误的响应,类型为字符串类型。
|
|
|
|
|
* @return 返回一个ServerResponse对象,该对象封装了删除购物车商品操作的结果信息,
|
|
|
|
|
* 如果操作成功,内部包含代表成功的数据(即构建好的CartVo对象,包含了删除商品后购物车的详细信息,例如剩余商品列表、总价等情况),
|
|
|
|
|
* 若操作失败,则包含相应的错误提示消息等内容,方便调用者(如控制层)根据返回结果判断操作是否成功,并进行相应的处理(如返回给前端提示信息等)。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse delete(Integer userId, String productIds) {
|
|
|
|
|
// 使用Google Guava库的Splitter工具类,按照逗号(",")将传入的商品ID字符串(productIds)分割成一个字符串列表,
|
|
|
|
|
// 这样就能方便地获取到要删除的各个商品的ID,以便后续批量操作数据库中对应的购物车商品记录。
|
|
|
|
|
List<String> productIdList = Splitter.on(",").splitToList(productIds);
|
|
|
|
|
if(CollectionUtils.isEmpty(productIdList)){
|
|
|
|
|
// 通过Apache Commons Collections的CollectionUtils工具类检查分割后的商品ID列表是否为空,
|
|
|
|
|
// 如果为空,说明传入的参数不符合要求,无法准确执行删除操作,此时返回一个表示参数错误的ServerResponse对象给客户端,提示用户修正传入的参数。
|
|
|
|
|
if (CollectionUtils.isEmpty(productIdList)) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("参数错误");
|
|
|
|
|
}
|
|
|
|
|
int rowCount = cartMapper.deleteByProductIds(userId,productIdList);
|
|
|
|
|
if(rowCount == 0){
|
|
|
|
|
|
|
|
|
|
// 调用CartMapper的deleteByProductIds方法,根据用户ID和要删除的商品ID列表从数据库中删除对应的购物车商品记录,
|
|
|
|
|
// 该方法会返回受影响的行数,即实际删除的记录条数,正常情况下如果成功删除了对应的商品记录,返回值应该大于0。
|
|
|
|
|
int rowCount = cartMapper.deleteByProductIds(userId, productIdList);
|
|
|
|
|
// 如果返回值为0,表示没有实际删除任何记录,可能是因为要删除的商品已经不存在于购物车中了,
|
|
|
|
|
// 此时返回一个表示商品已经不存在于购物车中,请勿重复删除的ServerResponse对象给客户端,告知用户当前操作情况。
|
|
|
|
|
if (rowCount == 0) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("此商品已经不存在于购物车中,请勿重复删除");
|
|
|
|
|
}
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId,false);
|
|
|
|
|
|
|
|
|
|
// 调用getCartVoLimit方法构建包含删除商品后购物车详细信息的CartVo对象,这个方法会进一步处理购物车商品的相关信息(如获取剩余商品详情、计算总价等),
|
|
|
|
|
// 最后返回一个表示操作成功且包含构建好的CartVo对象的ServerResponse对象给客户端,告知用户删除购物车商品操作成功,并将购物车的详细信息返回给前端展示给用户。
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId, false);
|
|
|
|
|
return ServerResponse.createBySuccess(cartVo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现ICartService接口中定义的查询购物车列表信息的方法。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是查询哪个用户的购物车列表,类型为整数类型,是定位具体购物车数据的关键依据。
|
|
|
|
|
* @return 返回一个ServerResponse对象,该对象封装了查询购物车列表操作的结果信息,
|
|
|
|
|
* 如果操作成功,内部包含代表成功的数据(即构建好的CartVo对象,包含了购物车的详细商品列表、总价等信息),
|
|
|
|
|
* 方便调用者(如控制层)根据返回结果将购物车信息展示给客户端(如前端页面展示购物车内容等)。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse list(Integer userId) {
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId,false);
|
|
|
|
|
// 直接调用getCartVoLimit方法构建包含购物车详细信息的CartVo对象,这个方法内部会处理购物车商品的相关信息(如获取商品详情、判断库存、计算总价等),
|
|
|
|
|
// 最后返回一个表示操作成功且包含构建好的CartVo对象的ServerResponse对象给客户端,告知用户查询购物车列表操作成功,并将购物车的详细信息返回给前端展示给用户。
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId, false);
|
|
|
|
|
return ServerResponse.createBySuccess(cartVo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现ICartService接口中定义的设置购物车中商品的选中或未选中状态的方法。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是哪个用户的购物车进行商品选中状态设置操作,类型为整数类型,明确操作对应的购物车归属。
|
|
|
|
|
* @param checked 表示商品要设置的选中状态,可能是用整数表示(例如Constants.Cart.CHECKED表示选中,Constants.Cart.UN_CHECKED表示未选中,具体由业务定义),类型为整数类型,用于传递要设置的具体状态值。
|
|
|
|
|
* @param productId 要设置选中状态的商品的唯一标识符,若为null则表示对购物车中所有商品进行操作(根据具体业务逻辑而定),用于在购物车中定位具体的商品,类型为整数类型。
|
|
|
|
|
* @return 返回一个ServerResponse对象,该对象封装了设置商品选中状态操作的结果信息,
|
|
|
|
|
* 如果操作成功,内部包含代表成功的数据(即构建好的CartVo对象,包含了更新后的购物车相关信息,如商品选中状态改变后的购物车总价等情况),
|
|
|
|
|
* 方便调用者根据返回结果判断操作是否成功,并进行相应的处理(如返回给前端提示信息等)。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse selectOrUnSelect(Integer userId, int checked, Integer productId) {
|
|
|
|
|
cartMapper.selectOrUnSelectProduct(userId,checked,productId);
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId,false);
|
|
|
|
|
// 调用CartMapper的selectOrUnSelectProduct方法,根据用户ID、要设置的选中状态以及商品ID(如果不为null则针对特定商品,为null则针对所有商品,具体看业务逻辑实现)来更新数据库中购物车商品的选中状态记录,
|
|
|
|
|
// 此方法无返回值,它直接执行数据库更新操作,将对应的购物车商品记录的选中状态字段更新为传入的checked值。
|
|
|
|
|
cartMapper.selectOrUnSelectProduct(userId, checked, productId);
|
|
|
|
|
|
|
|
|
|
// 调用getCartVoLimit方法构建包含更新后购物车详细信息的CartVo对象,这个方法会进一步处理购物车商品的相关信息(如获取商品详情、判断库存、计算总价等),
|
|
|
|
|
// 最后返回一个表示操作成功且包含构建好的CartVo对象的ServerResponse对象给客户端,告知用户设置商品选中状态操作成功,并将购物车的详细信息返回给前端展示给用户。
|
|
|
|
|
CartVo cartVo = this.getCartVoLimit(userId, false);
|
|
|
|
|
return ServerResponse.createBySuccess(cartVo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现ICartService接口中定义的查询购物车中商品总数量的方法。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是哪个用户的购物车进行商品数量统计,若为null,按照业务逻辑返回数量为0的成功响应,类型为整数类型,作为统计的范围限定依据。
|
|
|
|
|
* @return 返回一个ServerResponse<Integer>对象,该对象封装了查询购物车商品数量操作的结果信息,
|
|
|
|
|
* 如果操作成功,其泛型部分的整数表示购物车中商品的总数量,同时ServerResponse对象本身还包含操作的状态码、提示消息等内容,
|
|
|
|
|
* 方便调用者(如控制层)根据返回结果判断操作是否成功,并获取购物车商品数量的具体数值进行展示或其他相关业务处理。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse<Integer> get_cart_product_count(Integer userId) {
|
|
|
|
|
if(userId == null){
|
|
|
|
|
// 首先判断用户ID是否为null,如果为null,按照业务逻辑,直接返回一个表示操作成功且数据部分为0的ServerResponse对象,
|
|
|
|
|
// 意味着如果用户未登录或者传入的用户ID无效等情况,默认购物车商品数量为0,告知调用者当前情况。
|
|
|
|
|
if (userId == null) {
|
|
|
|
|
return ServerResponse.createBySuccess(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用CartMapper的selectCartProductCount方法,传入用户ID作为参数,去查询数据库中对应用户购物车中商品的总数量,
|
|
|
|
|
// 然后返回一个表示操作成功且数据部分为查询到的商品数量的ServerResponse<Integer>对象给客户端,方便调用者获取并使用这个数量信息。
|
|
|
|
|
return ServerResponse.createBySuccess(cartMapper.selectCartProductCount(userId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现ICartService接口中定义的清空购物车的方法。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是哪个用户的购物车进行清空操作,类型为整数类型,明确操作对应的购物车归属。
|
|
|
|
|
* @return 返回一个ServerResponse对象,该对象封装了清空购物车操作的结果信息,
|
|
|
|
|
* 如果操作成功,包含表示成功的提示消息(如这里的"清除购物车成功"),方便调用者(如控制层)根据返回结果判断操作是否成功,并进行相应的处理(如返回给前端提示信息等)。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse removeCart(Integer userId) {
|
|
|
|
|
// 首先通过CartMapper的selectCartByUserId方法,根据用户ID去查询数据库中该用户购物车中的所有商品记录,返回一个包含多个Cart对象的列表,代表购物车中的所有商品信息。
|
|
|
|
|
List<Cart> cartList = cartMapper.selectCartByUserId(userId);
|
|
|
|
|
for(Cart cart:cartList){
|
|
|
|
|
|
|
|
|
|
// 遍历查询到的购物车商品记录列表,对于每一条购物车记录,调用CartMapper的deleteByPrimaryKey方法,根据购物车记录的主键(ID)从数据库中删除对应的记录,
|
|
|
|
|
// 这样就实现了逐个删除购物车中的所有商品记录,达到清空购物车的目的。
|
|
|
|
|
for (Cart cart : cartList) {
|
|
|
|
|
cartMapper.deleteByPrimaryKey(cart.getId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回一个表示操作成功且包含提示消息"清除购物车成功"的ServerResponse对象给客户端,告知用户购物车已成功清空,方便调用者(如控制层)将这个消息返回给前端展示给用户。
|
|
|
|
|
return ServerResponse.createBySuccessMessage("清除购物车成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 比较通用的构建购物车的方法
|
|
|
|
|
* @param userId
|
|
|
|
|
* @return
|
|
|
|
|
* 比较通用的构建购物车的方法,用于组装包含购物车详细信息的CartVo对象,会综合考虑商品信息、库存情况、选中状态等来构建完整的购物车视图数据。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是哪个用户的购物车信息需要构建,类型为整数类型,是获取相关数据的关键依据。
|
|
|
|
|
* @param isJudgeStock 一个布尔类型的参数,用于决定是否需要判断商品的库存情况,有些业务接口在构建购物车信息时不需要考虑库存,
|
|
|
|
|
* 通过这个参数可以灵活控制是否执行库存相关的判断和处理逻辑,true表示需要判断库存,false表示不需要判断库存。
|
|
|
|
|
* @return 返回一个CartVo对象,该对象包含了购物车的详细信息,如购物车商品列表(CartProductVo列表)、购物车总价、全选状态以及图片主机地址等信息,
|
|
|
|
|
* 方便在其他业务方法中作为返回数据提供给上层调用者(如控制层),进而展示给客户端(前端页面)使用。
|
|
|
|
|
*/
|
|
|
|
|
private CartVo getCartVoLimit(Integer userId,boolean isJudgeStock) {
|
|
|
|
|
private CartVo getCartVoLimit(Integer userId, boolean isJudgeStock) {
|
|
|
|
|
// 创建一个新的CartVo对象,用于组装最终要返回的购物车详细信息,这个对象将包含购物车的各种关键信息,如商品列表、总价、全选状态等内容。
|
|
|
|
|
CartVo cartVo = new CartVo();
|
|
|
|
|
|
|
|
|
|
// 创建一个空的CartProductVo列表,用于存放购物车中各个商品的详细信息对象,后续会遍历购物车记录,将每个商品的详细信息封装成CartProductVo对象后添加到这个列表中。
|
|
|
|
|
List<CartProductVo> cartProductVoList = Lists.newArrayList();
|
|
|
|
|
|
|
|
|
|
// 通过CartMapper的selectCartByUserId方法,根据传入的用户ID去查询数据库中该用户购物车中的所有商品记录,返回一个包含多个Cart对象的列表,代表购物车中的所有商品信息。
|
|
|
|
|
List<Cart> cartList = cartMapper.selectCartByUserId(userId);
|
|
|
|
|
|
|
|
|
|
// 初始化购物车总价为0,使用BigDecimal类型来精确表示金额,避免浮点数运算的精度问题,后续会根据购物车中选中商品的价格和数量来累加计算总价。
|
|
|
|
|
BigDecimal cartTotalPrice = new BigDecimal("0");
|
|
|
|
|
if(CollectionUtils.isNotEmpty(cartList)){
|
|
|
|
|
//1.遍历购物车,一条购物车记录对应一个商品,这些购物车共同对应到一个用户userId
|
|
|
|
|
for(Cart cart:cartList){
|
|
|
|
|
|
|
|
|
|
// 判断查询到的购物车商品记录列表是否不为空,如果不为空,说明该用户购物车中有商品,需要进一步处理这些商品的详细信息,进行购物车信息的构建。
|
|
|
|
|
if (CollectionUtils.isNotEmpty(cartList)) {
|
|
|
|
|
// 1. 遍历购物车,一条购物车记录对应一个商品,这些购物车共同对应到一个用户userId
|
|
|
|
|
// 开始遍历购物车商品记录列表,对于每一条购物车记录(代表一个商品在购物车中的信息),进行如下操作,构建对应的CartProductVo对象来封装商品详细信息,并添加到购物车商品列表中。
|
|
|
|
|
for (Cart cart : cartList) {
|
|
|
|
|
CartProductVo cartProductVo = new CartProductVo();
|
|
|
|
|
// 设置CartProductVo对象的ID,一般可以使用购物车记录的主键ID作为其唯一标识,方便后续在一些业务逻辑中对特定商品信息进行定位和操作。
|
|
|
|
|
cartProductVo.setId(cart.getId());
|
|
|
|
|
// 设置CartProductVo对象的用户ID,关联到对应的用户,确保商品信息所属的用户明确,与传入的参数userId对应。
|
|
|
|
|
cartProductVo.setUserId(cart.getUserId());
|
|
|
|
|
// 设置CartProductVo对象的商品ID,明确这个商品信息对应的具体商品,与购物车记录中的商品ID保持一致。
|
|
|
|
|
cartProductVo.setProductId(cart.getProductId());
|
|
|
|
|
//2.从redis中获取商品,获取不到则feign获取并且重置进redis中
|
|
|
|
|
String productStr = commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX+cart.getProductId());
|
|
|
|
|
|
|
|
|
|
// 2. 从redis中获取商品,获取不到则feign获取并且重置进redis中
|
|
|
|
|
// 尝试从缓存(这里假设使用Redis缓存,通过CommonCacheUtil工具类操作)中获取商品信息,缓存的键是通过Constants.PRODUCT_TOKEN_PREFIX加上购物车记录中商品的ID拼接而成的,
|
|
|
|
|
// 这样可以根据不同的商品ID准确地在缓存中查找对应的商品缓存数据,提高获取商品信息的效率,避免频繁访问数据库。
|
|
|
|
|
String productStr = commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX + cart.getProductId());
|
|
|
|
|
Product product = null;
|
|
|
|
|
if(productStr == null){
|
|
|
|
|
// 如果从缓存中获取到的商品信息字符串为null,说明缓存中不存在该商品的相关信息,此时需要通过ProductClient去远程调用商品服务来查询商品详情。
|
|
|
|
|
if (productStr == null) {
|
|
|
|
|
ServerResponse response = productClient.queryProduct(cart.getProductId());
|
|
|
|
|
Object object = response.getData();
|
|
|
|
|
String objStr = JsonUtil.obj2String(object);
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(objStr,Product.class);
|
|
|
|
|
}else {
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(productStr,Product.class);
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(objStr, Product.class);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果缓存中存在商品信息字符串,则直接使用JsonUtil的Str2Obj方法将其反序列化为Product对象,避免了再次远程查询商品服务的开销。
|
|
|
|
|
product = (Product) JsonUtil.Str2Obj(productStr, Product.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(product != null){
|
|
|
|
|
// 如果成功获取到了商品对象(即product不为null),说明获取到了商品的详细信息,接下来可以设置CartProductVo对象中与商品相关的各种属性值。
|
|
|
|
|
if (product!= null) {
|
|
|
|
|
// 设置CartProductVo对象的商品主图片路径,从获取到的商品对象中获取主图片路径属性值,方便前端根据这个路径展示商品的主图片。
|
|
|
|
|
cartProductVo.setProductMainImage(product.getMainImage());
|
|
|
|
|
// 设置CartProductVo对象的商品名称,从商品对象中获取商品名称属性值,用于在前端展示商品的名称信息。
|
|
|
|
|
cartProductVo.setProductName(product.getName());
|
|
|
|
|
// 设置CartProductVo对象的商品副标题,从商品对象中获取副标题属性值,可在前端展示商品的补充说明信息,如卖点、优惠等相关内容。
|
|
|
|
|
cartProductVo.setProductSubtitle(product.getSubtitle());
|
|
|
|
|
// 设置CartProductVo对象的商品状态,从商品对象中获取商品状态属性值,用于前端展示商品是否可购买等状态信息(例如是否下架等情况)。
|
|
|
|
|
cartProductVo.setProductStatus(product.getStatus());
|
|
|
|
|
// 设置CartProductVo对象的商品价格,从商品对象中获取商品价格属性值,用于后续计算商品总价等操作,注意这里价格使用BigDecimal类型保证精度。
|
|
|
|
|
cartProductVo.setProductPrice(product.getPrice());
|
|
|
|
|
// 设置CartProductVo对象的商品库存,从商品对象中获取商品库存属性值,用于判断库存是否足够等相关业务逻辑处理。
|
|
|
|
|
cartProductVo.setProductStock(product.getStock());
|
|
|
|
|
//3.判断这个商品的库存,有些接口不需要再去判断库存了,所以根据传进来的isJudgeStock这个boolean参数来决定是否判断库存
|
|
|
|
|
|
|
|
|
|
// 3. 判断这个商品的库存,有些接口不需要再去判断库存了,所以根据传进来的isJudgeStock这个boolean参数来决定是否判断库存
|
|
|
|
|
int buyLimitCount = 0;
|
|
|
|
|
if (isJudgeStock){
|
|
|
|
|
if(product.getStock() > cart.getQuantity()){
|
|
|
|
|
//4.库存是够的
|
|
|
|
|
if (isJudgeStock) {
|
|
|
|
|
// 如果需要判断库存(即isJudgeStock为true),则比较商品的库存数量和购物车中该商品的数量,判断库存是否足够。
|
|
|
|
|
if (product.getStock() > cart.getQuantity()) {
|
|
|
|
|
// 4. 库存是够的
|
|
|
|
|
// 如果商品库存大于购物车中该商品的数量,说明库存充足,购买数量可以按照购物车中记录的数量来确定,将购买数量设置为购物车中的商品数量。
|
|
|
|
|
buyLimitCount = cart.getQuantity();
|
|
|
|
|
// 设置CartProductVo对象的限制数量标识为Constants.Cart.LIMIT_NUM_SUCCESS(应该是业务中定义好的表示数量限制成功,即库存足够的
|
|
|
|
|
// 在构建购物车信息的方法中,针对每个购物车商品记录,根据库存情况设置相关属性,并计算商品总价等信息,以下是继续添加注释后的详细内容。
|
|
|
|
|
|
|
|
|
|
// 如果库存足够,设置CartProductVo对象的限制数量标识为表示库存足够的常量值,意味着当前商品在购物车中的数量是可购买的数量,没有受到库存限制。
|
|
|
|
|
cartProductVo.setLimitQuantity(Constants.Cart.LIMIT_NUM_SUCCESS);
|
|
|
|
|
}else {
|
|
|
|
|
//5.库存不够了,则返回当前最大库存
|
|
|
|
|
} else {
|
|
|
|
|
// 5. 库存不够了,则返回当前最大库存
|
|
|
|
|
// 当商品库存小于或等于购物车中该商品的数量时,说明库存不足,此时将购买数量设置为商品当前的库存数量,即用户最多只能购买库存剩余的数量。
|
|
|
|
|
buyLimitCount = product.getStock();
|
|
|
|
|
// 设置CartProductVo对象的限制数量标识为Constants.Cart.LIMIT_NUM_FAIL(应该是业务中定义好的表示数量限制失败,即库存不足的标识),
|
|
|
|
|
// 用于前端展示等场景告知用户该商品库存不足,可能无法按照购物车中原本设置的数量购买。
|
|
|
|
|
cartProductVo.setLimitQuantity(Constants.Cart.LIMIT_NUM_FAIL);
|
|
|
|
|
// 创建一个新的Cart对象,用于更新购物车中该商品的记录,因为库存不足,需要将购物车中记录的商品数量更新为实际可购买的库存数量。
|
|
|
|
|
Cart cartItem = new Cart();
|
|
|
|
|
// 设置新Cart对象的ID为当前购物车商品记录的ID,确保更新的是正确的购物车商品记录。
|
|
|
|
|
cartItem.setId(cart.getId());
|
|
|
|
|
// 设置新Cart对象的商品数量为前面计算得到的可购买的库存数量(buyLimitCount),准备更新数据库中的购物车记录。
|
|
|
|
|
cartItem.setQuantity(buyLimitCount);
|
|
|
|
|
// 通过CartMapper的updateByPrimaryKeySelective方法,根据更新后的Cart对象去更新数据库中对应的购物车记录,
|
|
|
|
|
// 这个方法会根据Cart对象中不为null的属性来更新数据库相应字段,以确保购物车中的商品数量与实际库存情况相符。
|
|
|
|
|
cartMapper.updateByPrimaryKeySelective(cartItem);
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不需要判断库存(即isJudgeStock为false),则直接将购买数量设置为购物车中原本记录的商品数量,不考虑库存是否足够的情况,可能适用于某些特定业务场景,比如仅查看购物车信息而不涉及购买操作时。
|
|
|
|
|
buyLimitCount = cart.getQuantity();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//6.购买的数量已经是确定的了,下面就可以直接计算价格了
|
|
|
|
|
// 6. 购买的数量已经是确定的了,下面就可以直接计算价格了
|
|
|
|
|
// 设置CartProductVo对象的商品数量为前面确定好的购买数量(buyLimitCount),这个数量将用于后续计算该商品在购物车中的总价。
|
|
|
|
|
cartProductVo.setQuantity(buyLimitCount);
|
|
|
|
|
cartProductVo.setProductTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(),buyLimitCount));
|
|
|
|
|
// 使用BigDecimalUtil工具类的mul方法(应该是自定义的用于BigDecimal类型乘法运算的工具方法,确保精度),
|
|
|
|
|
// 传入商品价格的double值(通过调用product.getPrice().doubleValue()获取)和购买数量(buyLimitCount),计算得到该商品在购物车中的总价,
|
|
|
|
|
// 并设置到CartProductVo对象的ProductTotalPrice属性中,方便后续汇总购物车总价以及展示给用户查看商品的价格明细。
|
|
|
|
|
cartProductVo.setProductTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(), buyLimitCount));
|
|
|
|
|
// 设置CartProductVo对象的商品选中状态,从购物车记录中获取商品的选中状态(cart.getChecked())并赋值给CartProductVo对象,
|
|
|
|
|
// 用于前端展示商品是否被选中以及参与购物车总价计算等相关业务逻辑(例如只有选中的商品总价才会累加到购物车总价中)。
|
|
|
|
|
cartProductVo.setProductChecked(cart.getChecked());
|
|
|
|
|
}
|
|
|
|
|
//7.选中的,就加入到总价中
|
|
|
|
|
if(cart.getChecked() == Constants.Cart.CHECKED){
|
|
|
|
|
cartTotalPrice = BigDecimalUtil.add(cartTotalPrice.doubleValue(),cartProductVo.getProductTotalPrice().doubleValue());
|
|
|
|
|
// 7. 选中的,就加入到总价中
|
|
|
|
|
// 判断购物车记录中该商品的选中状态是否为Constants.Cart.CHECKED(表示已选中),如果是,则将该商品的总价累加到购物车总价(cartTotalPrice)中。
|
|
|
|
|
// 通过BigDecimalUtil工具类的add方法(同样是自定义的用于BigDecimal类型加法运算的工具方法,保证精度),
|
|
|
|
|
// 传入当前购物车总价的double值(cartTotalPrice.doubleValue())和该商品的总价(cartProductVo.getProductTotalPrice().doubleValue())进行累加计算,
|
|
|
|
|
// 更新购物车总价,以得到所有选中商品的总价信息。
|
|
|
|
|
if (cart.getChecked() == Constants.Cart.CHECKED) {
|
|
|
|
|
cartTotalPrice = BigDecimalUtil.add(cartTotalPrice.doubleValue(), cartProductVo.getProductTotalPrice().doubleValue());
|
|
|
|
|
}
|
|
|
|
|
// 将构建好的包含该商品详细信息的CartProductVo对象添加到购物车商品列表(cartProductVoList)中,完成一个商品信息的处理,后续继续遍历其他购物车商品记录进行同样的操作。
|
|
|
|
|
cartProductVoList.add(cartProductVo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置CartVo对象的购物车总价属性(CartTotalPrice)为前面计算得到的购物车总价(cartTotalPrice),方便将购物车总价信息传递给上层调用者(如控制层)展示给用户查看整个购物车的商品总价情况。
|
|
|
|
|
cartVo.setCartTotalPrice(cartTotalPrice);
|
|
|
|
|
// 设置CartVo对象的购物车商品列表属性(CartProductVoList)为前面构建好的包含所有商品详细信息的列表(cartProductVoList),
|
|
|
|
|
// 这样在前端展示购物车信息时,可以遍历这个列表展示每个商品的各项信息(如名称、价格、数量、选中状态等)。
|
|
|
|
|
cartVo.setCartProductVoList(cartProductVoList);
|
|
|
|
|
// 调用getAllCheckedStatus方法(下面定义的用于判断购物车中商品是否全选的方法),传入用户ID作为参数,获取购物车中商品的全选状态(是否所有商品都被选中),
|
|
|
|
|
// 并设置到CartVo对象的AllChecked属性中,方便前端展示购物车全选按钮的状态以及进行全选、取消全选等相关业务逻辑操作。
|
|
|
|
|
cartVo.setAllChecked(this.getAllCheckedStatus(userId));
|
|
|
|
|
cartVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix","http://img.oursnail.cn/"));
|
|
|
|
|
log.info("购物车列表内容为:{}",cartVo);
|
|
|
|
|
// 通过PropertiesUtil工具类的getProperty方法(应该是用于读取配置文件中属性值的工具方法),尝试获取配置文件中名为"ftp.server.http.prefix"的属性值,
|
|
|
|
|
// 如果获取不到,则使用默认值"http://img.oursnail.cn/"作为图片主机地址,这个地址通常用于前端展示购物车中商品图片时拼接图片的具体路径,
|
|
|
|
|
// 例如商品主图片路径可能是相对路径,通过拼接这个图片主机地址可以得到完整的可访问的图片URL,方便前端正确展示商品图片。
|
|
|
|
|
cartVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix", "http://img.oursnail.cn/"));
|
|
|
|
|
// 使用日志记录器记录购物车列表的详细内容,方便在开发、调试以及运行过程中查看购物车信息的构建情况,排查可能出现的问题,例如购物车总价计算错误、商品信息缺失等情况。
|
|
|
|
|
log.info("购物车列表内容为:{}", cartVo);
|
|
|
|
|
// 最后返回构建好的包含完整购物车详细信息的CartVo对象,供上层调用者(如在其他业务方法中)使用,例如将其包装在ServerResponse对象中返回给控制层,进而展示给前端页面。
|
|
|
|
|
return cartVo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 0-未勾选,1-已勾选,所以我就找有没有未勾选的商品,找到就说明没有全选
|
|
|
|
|
* 0 - 未勾选,1 - 已勾选,所以我就找有没有未勾选的商品,找到就说明没有全选
|
|
|
|
|
* 此方法用于判断给定用户的购物车中商品是否全部被选中,通过查询购物车中已选中商品的状态数量来判断。
|
|
|
|
|
* 如果查询到的已选中商品的状态数量为0,意味着没有商品被选中,即购物车中的商品不是全选状态,返回false;
|
|
|
|
|
* 否则说明购物车中至少有一个商品被选中,返回true表示全选状态(这里根据业务逻辑中对于全选的定义来判断,具体业务可能有所不同,可按需调整)。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的唯一标识符,用于确定是哪个用户的购物车进行全选状态判断,类型为整数类型,是定位具体购物车数据的关键依据。
|
|
|
|
|
* @return 返回一个布尔值,表示购物车中商品是否处于全选状态,true表示全选,false表示未全选。
|
|
|
|
|
*/
|
|
|
|
|
private Boolean getAllCheckedStatus(Integer userId) {
|
|
|
|
|
if(userId == null){
|
|
|
|
|
// 首先判断用户ID是否为null,如果为null,按照业务逻辑,直接返回false,表示无法判断全选状态或者默认不是全选状态(可根据实际业务含义调整),
|
|
|
|
|
// 例如在未登录或者传入无效用户ID的情况下,不认为购物车是全选状态。
|
|
|
|
|
if (userId == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 调用CartMapper的selectCartCheckedStatusByUserId方法,传入用户ID作为参数,去查询数据库中该用户购物车中已选中商品的状态数量,
|
|
|
|
|
// 这里返回值的具体含义可能根据业务逻辑而定,例如返回的是已选中商品的记录条数等,只要返回值不为0,就表示有商品被选中。
|
|
|
|
|
return cartMapper.selectCartCheckedStatusByUserId(userId) == 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|