基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖微信小程序端(十二)

购物车相关

  • 1.添加购物车
    • 1.1 需求分析和设计
      • 1.1.1 产品原型
      • 1.1.2 接口设计
      • 1.1.3 表设计
    • 1.2 代码开发
      • 1.2.1 DTO设计
      • 1.2.2 Controller层
      • 1.2.3 Service层接口
      • 1.2.4 Service层实现类
      • 1.2.5 Mapper层
  • 2. 查看购物车
    • 2.1 需求分析和设计
      • 2.1.1 产品原型
      • 2.1.2 接口设计
    • 2.2 代码开发
      • 2.2.1 Controller层
      • 2.2.2 Service层接口
      • 2.2.3 Service层实现类
    • 2.3 功能测试
  • 3. 清空购物车
    • 3.1 需求分析和设计
      • 3.1.1 产品原型
      • 3.1.2 接口设计
    • 3.2 代码开发
      • 3.2.1 Controller层
      • 3.2.2 Service层接口
      • 3.2.3 Service层实现类
      • 3.2.4 Mapper层

1.添加购物车

1.1 需求分析和设计

1.1.1 产品原型

用户可以将菜品或者套餐添加到购物车。对于菜品来说,如果设置了口味信息,则需要选择规格后才能加入购物车;对于套餐来说,可以直接点击+将当前套餐加入购物车。在购物车中可以修改菜品和套餐的数量,也可以清空购物车。

效果图:

在这里插入图片描述

1.1.2 接口设计

通过上述原型图,设计出对应的添加购物车接口。
在这里插入图片描述

说明:添加购物车时,有可能添加菜品,也有可能添加套餐。故传入参数要么是菜品id,要么是套餐id。

1.1.3 表设计

用户的购物车数据,也是需要保存在数据库中的,购物车对应的数据表为shopping_cart表,具体表结构如下:

字段名数据类型说明备注
idbigint主键自增
namevarchar(32)商品名称冗余字段
imagevarchar(255)商品图片路径冗余字段
user_idbigint用户id逻辑外键
dish_idbigint菜品id逻辑外键
setmeal_idbigint套餐id逻辑外键
dish_flavorvarchar(50)菜品口味
numberint商品数量
amountdecimal(10,2)商品单价冗余字段
create_timedatetime创建时间

说明:

  • 购物车数据是关联用户的,在表结构中,我们需要记录,每一个用户的购物车数据是哪些
  • 菜品列表展示出来的既有套餐,又有菜品,如果用户选择的是套餐,就保存套餐ID(setmeal_id),如果用户选择的是菜品,就保存菜品ID(dish_id)
  • 对同一个菜品/套餐,如果选择多份不需要添加多条记录,增加数量number即可

1.2 代码开发

1.2.1 DTO设计

根据添加购物车接口的参数设计DTO:

在这里插入图片描述

在sky-pojo模块,ShoppingCartDTO.java已定义

package com.sky.dto;

import lombok.Data;
import java.io.Serializable;

@Data
public class ShoppingCartDTO implements Serializable {

    private Long dishId;
    private Long setmealId;
    private String dishFlavor;

}

1.2.2 Controller层

根据添加购物车接口创建ShoppingCartController:

package com.sky.controller.user;


/**
 * 购物车
 */
@RestController
@RequestMapping("/user/shoppingCart")
@Slf4j
@Api(tags = "C端-购物车接口")
public class ShoppingCartController {

    @Autowired
    private ShoppingCartService shoppingCartService;

    /**
     * 添加购物车
     * @param shoppingCartDTO
     * @return
     */
    @PostMapping("/add")
    @ApiOperation("添加购物车")
    public Result<String> add(@RequestBody ShoppingCartDTO shoppingCartDTO){
        log.info("添加购物车:{}", shoppingCartDTO);
        shoppingCartService.addShoppingCart(shoppingCartDTO);//后绪步骤实现
        return Result.success();
    }
}

1.2.3 Service层接口

创建ShoppingCartService接口:

package com.sky.service;

public interface ShoppingCartService {

    /**
     * 添加购物车
     * @param shoppingCartDTO
     */
    void addShoppingCart(ShoppingCartDTO shoppingCartDTO);
}

1.2.4 Service层实现类

创建ShoppingCartServiceImpl实现类,并实现add方法:

package com.sky.service.impl;

@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    
    /**
     * 添加购物车
     *
     * @param shoppingCartDTO
     */
    public void addShoppingCart(ShoppingCartDTO shoppingCartDTO) {
        ShoppingCart shoppingCart = new ShoppingCart();
        BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);
        //只能查询自己的购物车数据
        shoppingCart.setUserId(BaseContext.getCurrentId());

        //判断当前商品是否在购物车中
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);

        if (shoppingCartList != null && shoppingCartList.size() == 1) {
            //如果已经存在,就更新数量,数量加1
            shoppingCart = shoppingCartList.get(0);
            shoppingCart.setNumber(shoppingCart.getNumber() + 1);
            shoppingCartMapper.updateNumberById(shoppingCart);
        } else {
            //如果不存在,插入数据,数量就是1

            //判断当前添加到购物车的是菜品还是套餐
            Long dishId = shoppingCartDTO.getDishId();
            if (dishId != null) {
                //添加到购物车的是菜品
                Dish dish = dishMapper.getById(dishId);
                shoppingCart.setName(dish.getName());
                shoppingCart.setImage(dish.getImage());
                shoppingCart.setAmount(dish.getPrice());
            } else {
                //添加到购物车的是套餐
                Setmeal setmeal = setmealMapper.getById(shoppingCartDTO.getSetmealId());
                shoppingCart.setName(setmeal.getName());
                shoppingCart.setImage(setmeal.getImage());
                shoppingCart.setAmount(setmeal.getPrice());
            }
            shoppingCart.setNumber(1);
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCartMapper.insert(shoppingCart);
        }
    }
}

1.2.5 Mapper层

创建ShoppingCartMapper接口:

package com.sky.mapper;

@Mapper
public interface ShoppingCartMapper {
    /**
     * 条件查询
     *
     * @param shoppingCart
     * @return
     */
    List<ShoppingCart> list(ShoppingCart shoppingCart);

    /**
     * 更新商品数量
     *
     * @param shoppingCart
     */
    @Update("update shopping_cart set number = #{number} where id = #{id}")
    void updateNumberById(ShoppingCart shoppingCart);

    /**
     * 插入购物车数据
     *
     * @param shoppingCart
     */
    @Insert("insert into shopping_cart (name, user_id, dish_id, setmeal_id, dish_flavor, number, amount, image, create_time) " +
            " values (#{name},#{userId},#{dishId},#{setmealId},#{dishFlavor},#{number},#{amount},#{image},#{createTime})")
    void insert(ShoppingCart shoppingCart);

}

创建ShoppingCartMapper.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="com.sky.mapper.ShoppingCartMapper">
    <select id="list" parameterType="ShoppingCart" resultType="ShoppingCart">
        select * from shopping_cart
        <where>
            <if test="userId != null">
                and user_id = #{userId}
            </if>
            <if test="dishId != null">
                and dish_id = #{dishId}
            </if>
            <if test="setmealId != null">
                and setmeal_id = #{setmealId}
            </if>
            <if test="dishFlavor != null">
                and dish_flavor = #{dishFlavor}
            </if>
        </where>
        order by create_time desc
    </select>
</mapper>

2. 查看购物车

2.1 需求分析和设计

2.1.1 产品原型

当用户添加完菜品和套餐后,可进入到购物车中,查看购物中的菜品和套餐。

2.1.2 接口设计

在这里插入图片描述

2.2 代码开发

2.2.1 Controller层

在ShoppingCartController中创建查看购物车的方法:

	/**
     * 查看购物车
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("查看购物车")
    public Result<List<ShoppingCart>> list(){
        return Result.success(shoppingCartService.showShoppingCart());
    }

2.2.2 Service层接口

在ShoppingCartService接口中声明查看购物车的方法:

	/**
     * 查看购物车
     * @return
     */
    List<ShoppingCart> showShoppingCart();

2.2.3 Service层实现类

在ShoppingCartServiceImpl中实现查看购物车的方法:

	/**
     * 查看购物车
     * @return
     */
    public List<ShoppingCart> showShoppingCart() {
        return shoppingCartMapper.list(ShoppingCart.
                                       builder().
                                       userId(BaseContext.getCurrentId()).
                                       build());
    }

2.3 功能测试

在这里插入图片描述

3. 清空购物车

3.1 需求分析和设计

3.1.1 产品原型

当点击清空按钮时,会把购物车中的数据全部清空。
在这里插入图片描述

3.1.2 接口设计

在这里插入图片描述

3.2 代码开发

3.2.1 Controller层

在ShoppingCartController中创建清空购物车的方法:

	/**
     * 清空购物车商品
     * @return
     */
    @DeleteMapping("/clean")
    @ApiOperation("清空购物车商品")
    public Result<String> clean(){
        shoppingCartService.cleanShoppingCart();
        return Result.success();
    }

3.2.2 Service层接口

在ShoppingCartService接口中声明清空购物车的方法:

	/**
     * 清空购物车商品
     */
    void cleanShoppingCart();

3.2.3 Service层实现类

在ShoppingCartServiceImpl中实现清空购物车的方法:

	/**
     * 清空购物车商品
     */
    public void cleanShoppingCart() {
        shoppingCartMapper.deleteByUserId(BaseContext.getCurrentId());
    }

3.2.4 Mapper层

在ShoppingCartMapper接口中创建删除购物车数据的方法:

	/**
     * 根据用户id删除购物车数据
     *
     * @param userId
     */
    @Delete("delete from shopping_cart where user_id = #{userId}")
    void deleteByUserId(Long userId);

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/325416.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(001)window 使用 OpenObserve

文章目录 安装上传数据报错附录 安装 1.下载安装包&#xff1a; 2. window 设置环境变量&#xff1a; ZO_ETCD_COMMAND_TIMEOUT 600 ZO_ETCD_CONNECT_TIMEOUT 600 ZO_ETCD_LOCK_WAIT_TIMEOUT 600 ZO_INGEST_ALLOWED_UPTO 10000 ZO_ROOT_USER_EMAIL 422615924qq.com ZO_…

Linux网络--- SSH服务

一、ssh服务简介 1、什么是ssh SSH&#xff08;Secure Shell&#xff09;是一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程复制等功能。SSH 协议对通信双方的数据传输进行了加密处理&#xff0c;其中包括用户登录时输入的用户口令&#xff0c;SSH 为建立在…

Spring使用注解管理Bean

引入lib包 Spring对Bean管理的常用注解 Component组件(作用在类上) Spring中提供了Component的三个衍生注解:(功能在目前为止是一致的) Controller WEB层 Service 业务层 Repository 持久层 属性注入的注解:(使用注解注入的方式,可以不用提供set方法) Value 用于注入普…

powershell的help

打开win10 的powershell窗口&#xff0c;输入help命令&#xff0c;可以得到如下说明&#xff1a; 有了help系统&#xff0c;可以方便地了解关于powershell的详细说明。

Java异常处理--异常处理的方式2:throws

文章目录 一、方式2&#xff1a;声明抛出异常类型&#xff08;throws&#xff09;二、throws基本格式三、 throws 使用举例&#xff08;1&#xff09;针对于编译时异常1、案例12、案例2 &#xff08;2&#xff09;针对于运行时异常 四、 方法重写中throws的要求&#xff08;1&a…

当代大学生是怎么被废掉的?

中式教育以应试为核心&#xff0c;强调知识的灌输和学生被动接受。随着社会的发展&#xff0c;中式教育的短板逐渐显现&#xff0c;创新能力的缺乏、对记忆的过度依赖、忽视个体差异等问题日益突出。 建议所有大学生都能去看看《上海交通大学生存手册》&#xff0c;它道出了中…

AbstractHttpMessageConverter + easyexcell优雅下载附件

介绍 AbstractHttpMessageConverter 是 Spring 框架中用于处理 HTTP 消息转换的抽象基类。它用于处理来自 HTTP 请求的消息,并将其转换为特定的 Java 对象,或者将 Java 对象转换为 HTTP 响应消息。 这个抽象类允许开发人员创建自定义的 HTTP 消息转换器,以便在 Spring MVC…

如何提高发电机组带载能力

发电机组的带载能力是指其在一定时间内能够稳定运行的最大负载。提高发电机组的带载能力&#xff0c;不仅可以提高其工作效率&#xff0c;还可以延长其使用寿命。 优化发电机组的设计&#xff1a;通过改进发电机组的设计&#xff0c;可以提高其带载能力。例如&#xff0c;可以采…

MongoDB面试系列-01

1. MongoDB 是什么&#xff1f; MongoDB是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。再高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。MongoDB旨在给Web应用提供可扩展的高性能数据存储解决方案。 MongoDB将数据存储…

手把手教你学会接口自动化系列十五-如何用python操作excel的单元格自动化测试之前的准备工作

接上篇,我们都知道可以读取到sheet页了,下来就是读取sheet页下面的单元格数据 我们实践起来吧。 第一种方式是通过坐标的方式,比如我要取下面这个单元格的数据,如下: 这个数据位于Excel的B列第8行,所以对于excel来说就是坐标为B8。 代码如下: # !/usr/bin/env pytho…

LLM:Scaling Laws for Neural Language Models (中)

核心结论 1&#xff1a;LLM模型的性能主要与计算量C&#xff0c;模型参数量N和数据大小D三者相关&#xff0c;而与模型的具体结构 (层数/深度/宽度) 基本无关。三者满足: C ≈ 6ND 2. 为了提升模型性能&#xff0c;模型参数量N和数据大小D需要同步放大&#xff0c;但模型和数…

【生态适配】亚信安慧AntDB数据库与契约锁完成兼容互认

日前&#xff0c;亚信安慧AntDB数据库与上海亘岩网络科技有限公司&#xff08;简称:契约锁&#xff09;研发的契约锁电子签章产品完成兼容互认。经过双方团队的严格测试&#xff0c;亚信安慧AntDB数据库与契约锁&#xff08;V4&#xff09;完全兼容&#xff0c;整体运行稳定高效…

一天吃透Spring面试八股文

目录&#xff1a; Spring的优点Spring 用到了哪些设计模式&#xff1f;什么是AOP&#xff1f;AOP有哪些实现方式&#xff1f;Spring AOP的实现原理JDK动态代理和CGLIB动态代理的区别&#xff1f;Spring AOP相关术语Spring通知有哪些类型&#xff1f;什么是IOC&#xff1f;IOC的…

L1-027 出租(Java)

下面是新浪微博上曾经很火的一张图&#xff1a; 一时间网上一片求救声&#xff0c;急问这个怎么破。其实这段代码很简单&#xff0c;index数组就是arr数组的下标&#xff0c;index[0]2 对应 arr[2]1&#xff0c;index[1]0 对应 arr[0]8&#xff0c;index[2]3 对应 arr[3]0&…

鸿蒙开发之手势Pan

Entry Component struct OfficialPanGesturePage {State message: string 默认只左右移动State offsetX: number 0State offsetY: number 0State positionX: number 0State positionY: number 0//默认pan的参数&#xff0c;1根手指&#xff0c;左右方向private panOption:…

什么是泛域名证书?有免费的吗?

泛域名证书&#xff08;Wildcard SSL Certificate&#xff09;是一种用于加密多个子域名的SSL证书。与传统的SSL证书只能覆盖单个域名或特定子域不同&#xff0c;泛域名证书具有更广泛的适用性&#xff0c;可以涵盖一个域名下的所有子域。 泛域名证书的主要特点是通配符&#x…

华为数通方向HCIP-DataCom H12-831题库(判断题:1-20)

第01题 为了加快IS-IS网络中链路故障的感知速度,可以将IS-IS与BFD联动 正确 错误 答案:正确 解析: OSPF和IS-IS都可以设置与BFD联动加速链路故障检测 ,使用BFD时,可以实现毫秒级别的链路切换,所以使用IS–IS与BFD联动,可以加快IS–IS的感知速度 第02题 在OSPF中ABR会将…

关于整型提升与截断的一道题目

关于整型提升与截断&#xff0c;可以看我的博客 C语言&#xff1a;整型提升_c语言整形提升-CSDN博客 C语言&#xff1a;截断整型提升算数转换练习_c语言unsigned-CSDN博客 一、题目 二、题解 char a101截断 由于101是整型数据&#xff0c;需要32比特位存储空间&#xff0c;…

1.12号网络

1 网络发展历史 1.1 APRAnet阶段 阿帕网&#xff0c;是Interne的最早雏形 不能互联不同类型的计算机和不同类型的操作系统 没有纠错功能 1.2 TCP/IP两个协议阶段 什么是协议 在计算机网络中&#xff0c;要做到有条不紊的交换数据&#xff0c;需要遵循一些事先约定好的规则…

Java多线程并发篇----第十六篇

系列文章目录 文章目录 系列文章目录前言一、线程等待(wait)二、线程睡眠(sleep)三、线程让步(yield)四、线程中断(interrupt)五、Join 等待其他线程终止前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这…