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