实现购物车功能(新增、查询、删除、清空、修改)

一、新增sku到购物车

sku的官方解释:

SKU全称为Stock Keeping Unit(库存量单位),即库存进出计量的基本单元,可以是以件,盒,托盘等为单位。 SKU这是对于大型连锁超市DC(配送中心)物流管理的一个必要的方法。 现在已经被引申为产品统一编号的简称,每种产品均对应有唯一的SKU号。

前言

我们开发完成了显示商品详情的功能后,可以通过选中具体规格之后要确定购买的sku信息,再点击"添加到购物车"按钮,就应该将选中的sku信息保存在购物车中

业务逻辑分析

1. 判断用户是否登录,只有登陆后才能将商品新增到购物车

2. 验证购物车信息的完整性(SpringValidation)

3. 业务逻辑层要判断新增的sku是否在当前用户的购物车列表中已经存在

     如果不存在是新增sku流程

     如果已经存在,是修改数量的流程

开发持久层

按上面业务逻辑,持久层要开发多个方法

1. 判断当前登录用户购物车中是否包含指定sku商品的方法

2. 新增sku到购物车中的方法

3. 修改购物车中指定sku数量的方法

在mapper包中创建OmsCartMapper接口,编写代码如下

@Repository
public interface OmsCartMapper{
    // 判断当前用户购物车中是否已经包含指定的商品
    OmsCart selectExistsCart(@Param("userId") Long userId,
                             @Param("skuId") Long skuId);
    // 新增sku信息到购物车
    int saveCart(OmsCart omsCart);

    // 修改购物车中sku商品的数量
    int updateQuantityById(OmsCart omsCart);
}

对应的OmsCartMapper.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.tedu.mall.order.mapper.OmsCartMapper">

    <!--    通用查询映射结果    -->
    <resultMap id="BaseResultMap" type="cn.tedu.mall.pojo.order.model.OmsCart">
        <id column="id" property="id" />
        <result column="user_id" property="userId" />
        <result column="sku_id" property="skuId" />
        <result column="title" property="title" />
        <result column="main_picture" property="mainPicture" />
        <result column="price" property="price" />
        <result column="quantity" property="quantity" />
        <result column="gmt_create" property="gmtCreate" />
        <result column="gmt_modified" property="gmtModified" />
        <result column="bar_Code" property="barCode" />
        <result column="data" property="data" />
    </resultMap>
    
    <!--    定义查询omsCart表时使用的列名sql片段    -->
    <sql id="SimpleQueryFields">
        <if test="true">
            id,
            user_id,
            sku_id,
            title,
            main_picture,
            price,
            quantity,
            gmt_create,
            gmt_modified
        </if>
    </sql>

    <!--  判断当前用户购物车中是否已经包含指定的商品  -->
    <select id="selectExistsCart" resultMap="BaseResultMap">
        select
            <include refid="SimpleQueryFields" />
        from 
            oms_cart
        where
            user_id=#{userId}
        and
            sku_id=#{skuId}
    </select>

    <!--  新增sku信息到购物车  -->
    <insert id="saveCart" useGeneratedKeys="true" keyProperty="id">
        insert into oms_cart(
            user_id,
            sku_id,
            title,
            main_picture,
            price,
            quantity
        ) values (
            #{userId},
            #{skuId},
            #{title},
            #{mainPicture},
            #{price},
            #{quantity}
        )
    </insert>
    
    <!--  修改购物车中sku商品的数量   -->
    <update id="updateQuantityById">
        update
            oms_cart
        set
            quantity=#{quantity}
        where
            id=#{id}
    </update>
</mapper>
        

开发业务逻辑层

创建OmsCartServiceImpl类实现IOmsCartService接口

实现其中方法,先实现新增购物车的方法即可

在编写业务逻辑层具体代码之前,现在该类中编写一个从SpringSecurity上下文中获取用户信息的方法

@Service
@Slf4j
public class OmsCartServiceImpl implements IOmsCartService{

    @Autowired
    private OmsCartMapper omsCartMapper;

    @Override
    public void addCart(CartAddDTO cartDTO){
        // 要查询购物车中是否有指定商品之前,必须确定用户的Id
        Long userId = getUserId();
        // 根据用户Id和商品skuId,查询商品信息
        OmsCart omsCart = omsCartMapper.selectExistsCart(userId,cartDTO.getSkuId());
        // 判断该商品是否存在
        if(omsCart == null){
            // 如果omsCart为null,表示当前用户没有将这个商品新增到购物车
            // 所以执行新增操作,新增操作需要一个OmsCart对象
            OmsCart newCart = new OmsCart();
            // 将参数CartAddDTO对象中的同名属性赋值给newCart
            BeanUtils.copyProperties(cartDTO,newCart);
            // CartAddDTO中没有userId属性,需要单独赋值
            newCart.setUserId(userId);
            // 执行新增操作
            omsCartMapper.saveCart(newCart);
        }else{
            // 如果omsCart不是null,表示当前用户已经将这个商品新增到购物车中了
            // 我们需要做的就是将这次新增的数量和原有的数量相加,保存到数据库中
            // 我们写的mapper方法是直接修改商品数量的值
            // 所以要在java代码层面完成本次业务数量的相加操作
            omsCart.setQuantity(omsCart.getQuantity() + cartDTO.getQuantity());
            // 确定了数量之后,直接调用修改购物车数量方法即可
            omsCartMapper.updateQuantityById(omsCart);
        }
}

    @Override
    public JsonPage<CartStandardVO> listCart(Integer page,Integer pageSize){
        return null;
    }

    @Override
    public void removeCart(Long[] ids){

    }

    @Override
    public void removeAllCarts(){
    
    }

    @Override
    public void removeUserCarts(OmsCart omsCCart){
    
    }

    @Override
    public void updateQuantity(CartUpdateDTO cartUpdateDTO){

    }
    
    // 业务逻辑层中有获得当前登录用户信息的需求
    // 我们的项目会在控制器方法运行前运行的过滤器中,解析前端传入的JWT
    // 将解析获得的用户信息保存在SpringSecurity上下文中
    // 这里可以编写方法从SpringSecurity上下文中获得用户信息
    public CsmallAuthenticationInfo getUserInfo(){
        // 编写SpringSecurity上下文中获得用户信息的代码
        UsernamePasswordAuthenticationToken authenticationToken = 
            (UsernamePasswordAuthenticationToken)
                SecurityContextHolder.getContext().getAuthentication();
        // 为了逻辑严谨性,判断一下SpringSecurity上下文中的信息是不是null
        if(authenticationToken == null){
            throw new CoolSharkServiceException(
                ResponseCode.UNAUTHORIZED,"您没有登录!");
        }
        // 确定authenticationToken不为null
        // 就可以从中获得用户信息了
        CsmallAuthenticationInfo csmallAuthenticationInfo = 
            (CsmallAuthenticationInfo)authenticationToken.getCredentials();
        // 返回
        return csmallAuthenticationInfo;
}
        // 业务逻辑层中的方法实际上都只需要用户的id即可
        // 我们可以再编写一个方法,从用户对象中获得id
        public Long getUserId(){
            return getUserInfo().getId();
        }
}

开发控制层

创建OmsCartController

@RestController
@RequestMapping("/oms/cart")
@Api(tags = "购物车管理模块")
public class OmsCartController{
    
    @Autowired
    private IOmsCartSerivce omsCartService;
    
    @PostMapping("/add")
    @Apioperation("新增购物车信息")
    // 在程序运行控制方法前,已经运行了过滤器中解析JWT的代码,
    // 解析正确的话,用户信息已经保存在了SpringSecurity上下文中
    // 酷鲨商城前台用户登录时,我们编写的代码会向用户信息中固定设置一个ROLE_user的角色
    // 下面的注解,主要目的是判断用户是否登录,权限统一都是ROLE_user
    // 如果用户没有登录,是无法运行控制方法的!401错误
    @PreAuthorize("hasAuthority('ROLE_user')")
    // @Validated注解是激活SpringValidation框架用的
    // 参数CartAddDTO中,各个属性设置了验证规则,如果有参数值不符合规则
    // 会抛出BindException异常,之后会运行统一异常处理类中专门的方法,控制器方法终止
    public JsonResult addCart(@Validated CartAddDTO cartAddDTO){
        omsCartService.addCart(cartAddDTO);
        return JsonResult.ok("新增sku到购物车完成!");
    }
}

测试

先启动Nacos/Seata

启动passport/order

sso: 10002

order: 10005

先访问10002前台用户登录获得JWT 用户名jackson密码123456

先登录看到JWT然后复制JWT

转到10005 order模块 文档管理->全局参数设置->添加参数

参数名:Authorization

参数值:Bearer [粘贴JWT]

然后刷新当前10005的界面

然后进行发送请求即可成功

二、开发查询购物车功能

开发持久层

OmsCartMapper添加方法如下

// 根据用户id查询购物车中sku信息
List<CartStandardVO> selectCartsByUserId(Long userId);

OmsCartMapper.xml添加对应内容

<!-- 根据用户id查询购物车中sku信息  -->
<!--
    我们使用resultType声明返回类型时
    Mybatis内置按驼峰命名法自动生成列名对属性名的映射
    列名              属性名
    id                 id
    user_id            userId
    main_picture       mainPicture
    title              title
-->
<select id="selectCartsByUserId"
        resultType="cn.tedu.mall.pojo.order.vo.CartStandardVO">
    select
        <include refid="SimpleQueryFields" />
    from
        oms_cart
    where
        user_id=#{id}
</select>

开发业务逻辑层

OmsCartServiceImpl业务实现

返回值支持分页结果,按分页条件查询

@Override
public JsonPage<CartStandardVO> listCarts(Integer page,Integer pageSize){
    // 从SpringSecurity上下文中获得用户id
    Long userId = getUserId();
    // 要想执行分页查询,先设置分页条件
    PageHelper.startPage(page,pageSize);
    // 设置完分页条件执行的查询,会自动在sql语句后添加limit关键字
    List<CartStandardVO> list = omsCartMapper.selectCartsByUserId(userId);
    // list是分页数据,实例化PageInfo对象将分页数据传入,转成JsonPage返回
    return JsonPage.restPage(new pageInfo<>(list));
}

开发控制层

下面开发控制层,调用方法进行测试

OmsCartController添加方法如下

@GetMapping("/list")
@ApiOperation("根据用户Id分页查询购物车sku列表")
@ApiImplicitParams({
        @ApiImplicitParam(value = "页码", name = "page", example = "1"),
        @ApiImplicitParam(value = "每页条数", name = "pageSize", example = "10")
})
@PreAuthorize("hasAuthority('ROLE_user')")
public JsonResult<JsonPage<CartStandardVO>> listCartsByPage(
   // 控制器方法中的参数可以使用@RequestParam注解来赋默认值
   // WebConsts是我们自己编写的常量类,DEFAULT_PAGE:1 DEFAULT_PAGE_SIZE:20
   @RequestParam(required = false,defaultValue = WebConsts.DEFAULT_PAGE)
   Integer page,
   @RequestParam(required = false,defaultValue = WebConsts.DEFAULT_PAGE_SIZE)
   Integer pageSize){
    JsonPage<CartStandardVO> jsonPage=
            omsCartService.listCarts(page, pageSize);
    return JsonResult.ok(jsonPage);

}

在上面测试了新增购物车环境的基础上

重启order模块再次测试

三、删除/清空购物车

持久层

我们删除购物车的功能支持同时删除一个或多个购物车中的商品

基本思路就是将要删除的购物车商品的id数组传入到Mapper中进行删除

在OmsCartMapper中添加方法

// 根据用户选中的一个或多个id,删除购物车中的商品(批量删除操作)
int deleteCartsByIds(Long[] ids);

OmsCartMapper.xml新增代码

<!-- 根据用户选中的一个或多个id,删除购物车中的商品(批量删除操作)  -->
<!--  collection属性,编写的值是数组时,可以写array或ids  -->
<delete id="deleteCartsByIds" >
    delete from
        oms_cart
    where 
        id in
    <foreach collection="array" item="id" separator=","
                        open="(" close=")">
        #{id}
    </foreach>
            
</delete>

业务逻辑层

OmsCartServiceImpl添加方法

// 支持批量删除购物车中sku商品的方法
@Override
public void removeCart(Long[] ids) {
    // 调用mapper中批量删除的方法即可
    int rows=omsCartMapper.deleteCartsByIds(ids);
    if(rows==0){
        throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,
                "您要删除的商品已经删除了!");
    }
}

控制层

OmsCartController

@PostMapping("/delete")
@ApiOperation("根据id数组删除购物车中的sku信息")
@ApiImplicitParam(value = "包含要删除id的数组",name = "ids",
                            required = true, dataType = "array")
// 当@PreAuthorize注解后面要判断的权限内容以ROLE_开头时
// 表示我们判断的内容是SpringSecurity框架约定的角色
// 我们可以在@PreAuthorize注解()里使用hasRole来简化对角色的判断
// hasRole('user')这样的判断会检查当前登录用户是否有ROLE_user这个角色
// 也就是会自动在user前加ROLE_来判断
// @PreAuthorize("hasAuthority('ROLE_user')")
@PreAuthorize("hasRole('user')")
public JsonResult removeCartsByIds(Long[] ids){
    omsCartService.removeCart(ids);
    return JsonResult.ok("删除完成!");
}

重启Order模块,测试删除功能

四、清空当前登录用户购物车的功能

OmsCartMapper

// 清空指定用户购物车中所有sku商品
int deleteCartsByUserId(Long userId);

OmsCartMapper.xml

<!--  清空指定用户购物车中所有sku商品  -->
<delete id="deleteCartsByUserId">
    delete from
        oms_cart
    where
        user_id=#{userId}
</delete>

OmsCartServiceImpl

@Override
public void removeAllCarts() {
    Long userId=getUserId();
    int rows=omsCartMapper.deleteCartsByUserId(userId);
    if(rows==0){
        throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,
                "您的购物车已经是空的了!");
    }
}

OmsCartController

@PostMapping("/delete/all")
@ApiOperation("清空当前登录用户的购物车")
@PreAuthorize("hasRole('user')")
public JsonResult removeCartsByUserId(){
    omsCartService.removeAllCarts();
    return JsonResult.ok("购物车已清空");
}

测试

五、修改购物车的商品数量

开发修改购物车数量的业务逻辑层

因为之前开发新增购物车功能时,我们已经完成了修改购物车数量的持久层,所以不需要再编写了,直接从业务层开始

OmsCartServiceImpl

//  修改购物车中商品数量的业务逻辑层方法
@Override
public void updateQuantity(CartUpdateDTO cartUpdateDTO) {
    // 因为执行修改mapper方法要求的参数是OmsCart
    // 所以要先实例化OmsCart类型对象
    OmsCart omsCart=new OmsCart();
    // 然后将参数cartUpdateDTO的同名属性赋值到omsCart中
    BeanUtils.copyProperties(cartUpdateDTO,omsCart);
    // omsCart被赋必要值之后,直接调用mapper方法即可
    omsCartMapper.updateQuantityById(omsCart);
}

控制层OmsCartController

@PostMapping("/update/quantity")
@ApiOperation("修改购物车中sku数量")
@PreAuthorize("hasRole('user')")
public JsonResult updateQuantity(@Validated CartUpdateDTO cartUpdateDTO){
    omsCartService.updateQuantity(cartUpdateDTO);
    return JsonResult.ok("修改完成!");
}

重启order测试清空和修改购物车数量的功能

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿码德乌斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值