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

news2025/1/8 5:50:39

购物车相关

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安科瑞电动汽车充电桩运维平台 ——安科瑞 顾烊宇

充电桩其功能类似于加油站里面的加油机&#xff0c;可以固定在地面或墙壁&#xff0c;安装于公共建筑&#xff08;公共楼宇、商场、公共停车场等&#xff09;和居民小区停车场或充电站内&#xff0c;可以根据不同的电压等级为各种型号的电动汽车充电。充电桩的输入端与交流电网…

HCIA 网络基础:

应用层 抽象语言-->编码 表示层 编码-->二进制 会话层 建立会话&#xff0c;提供绘画地址。 应用于程序内部进行区分&#xff0c;没有统一标准 上三层主要是软件层面&#xff08;应用 程序处理数据&#xff09; 下四层主要负责数据传输 传输层 端口号 分段 &#xff…

PHP+MySQL组合开发:微信小程序万能建站源码系统 附带完整的搭建教程

随着移动互联网的快速发展&#xff0c;微信小程序已成为企业进行移动营销的重要工具。然而&#xff0c;对于许多中小企业和个人开发者来说&#xff0c;开发一个功能完善、用户体验良好的小程序是一项复杂的任务。罗峰给大家分享一款微信小程序万能建站源码系统。该系统采用PHPM…

C++设计模式-- 2.代理模式 和 外观模式

文章目录 代理模式外观模式角色和职责代码演示一&#xff1a;代码演示二&#xff1a;外观模式适用场景 代理模式 代理模式的定义&#xff1a;为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合 或不能直接引用另一个对象&#xff0c;而代…

Controller层自定义注解拦截request请求校验

一、背景 笔者工作中遇到一个需求&#xff0c;需要开发一个注解&#xff0c;放在controller层的类或者方法上&#xff0c;用以校验请求参数中(不管是url还是body体内&#xff0c;都要检查&#xff0c;有token参数&#xff0c;且符合校验规则就放行)是否传了一个token的参数&am…

旧衣回收小程序搭建:降低企业成本,提高回收效率!

在人们环保意识提升下&#xff0c;旧衣回收行业受到了大众的关注&#xff0c;同时旧衣回收具有门槛低、利润大的优势。在我国&#xff0c;回收行业不仅帮助普通人就业获利&#xff0c;还对环保做出了较大贡献。因此&#xff0c;旧衣回收行业成为了当下的热门商业模式&#xff0…

C#,入门教程(19)——循环语句(for,while,foreach)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(18)——分支语句&#xff08;switch-case&#xff09;的基础知识https://blog.csdn.net/beijinghorn/article/details/124039953 一、for循环 当老师进入教室&#xff0c;从门口开始分别按行、列点名&#xff0c;看看哪位翘课&…

详细介绍如何使用T5实现文本摘要:微调和构建 Gradio 应用程序-含完整源码

对高效文本摘要的需求从未如此迫切。无论您是正在处理冗长研究论文的学生还是浏览新闻文章的专业人士,快速提取关键见解的能力都是非常宝贵的。T5 是一种因多项 NLP 任务而闻名的预训练语言模型,擅长文本摘要。使用 T5 的文本摘要与 Hugging Face API 是无缝的。然而,对 T5 …

二、基础篇 vue计算属性和侦听器

计算属性 模板内的表达式非常便利&#xff0c;但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如&#xff1a; <div id"example">{{ message.split().reverse().join() }} </div> 在这个地方&#xff0c;模板不…

【松叶漫话】来聊聊ChatGPT 和文心一言吧

两大AI助手的较量 在当今信息技术飞速发展的时代&#xff0c;人工智能助手成为我们生活中不可或缺的一部分。ChatGPT和文心一言作为两大代表性的AI助手&#xff0c;在智能回复、语言准确性、知识库丰富度等方面各有千秋。本文将就这两位AI助手的特点进行深入比较&#xff0c;为…

深入解析多目标优化技术:理论、实践与优化

本文深入探讨了多目标优化技术及其在机器学习和深度学习中的应用&#xff0c;特别聚焦于遗传算法的原理和实践应用。我们从多目标优化的基础概念、常见算法、以及面临的挑战入手&#xff0c;进而详细介绍遗传算法的工作原理、Python代码实现&#xff0c;以及如何应用于实际的机…

Java中常用的加密算法及其实现原理详解

目录 1、前言 2、对称加密算法 2.1 对称加密算法的工作原理 2.2 DES、AES、RC4算法的原理及其在Java中的实现 2.3 对称加密算法的优缺点 3、非对称加密算法 3.1 非对称加密算法的工作原理 3.2 RSA、DSA算法的原理及其在Java中的实现 3.3 非对称加密算法的优缺点 4、散…

AI工具推荐:开源TTS(文本生成语音)模型集合

XTTS TTS是一个语音生成模型&#xff0c;可以通过一个简短的6秒音频片段将声音克隆到不同的语言。它不需要大量的训练数据&#xff0c;也不需要耗费大量时间。TTS支持17种语言&#xff0c;可以进行声音克隆、情感和风格转移、跨语言声音克隆以及多语言语音生成等功能。XTTS-v2…

chatgpt实用技巧之二反问式提示

大家好&#xff0c;今天跟大家讲实用gpt的小技巧二、反问式提示 有时候不知道怎么给 GPT 提示词&#xff0c;这时候&#xff0c;就可以反问 GPT 如何更好地给提示词。如图片所示 更详细内容可以看下这篇&#xff1a; 按照 GPT 给出的&#xff1a;故事设定角色故事发展主题结局…

SSM框架学习笔记04 | SpringMVC

文章目录 一、SpringMVC简介二、 请求与响应1. 请求映射路径2. get请求与post请求3. 响应 二、REST风格1.简介 三、 SSM整合四、拦截器1. 定义拦截器2.配置拦截器3.拦截器执行顺序4.拦截器参数5.多个连接器工作流程分析6.拦截器链的运行顺序 一、SpringMVC简介 SpringMVC技术与…

锐意进取,蓬勃发展|爱基百客2023全景图

岁序更迭&#xff0c;2023年已悄然离去。对我们来说&#xff0c;这是充满挑战与机遇的一年。爱基百客作为一家专注于测序服务的公司&#xff0c;我们在这一年里经历了许多挑战&#xff0c;也取得了令人鼓舞的成绩。前面我们盘点了表观产品和单细胞产品&#xff0c;今天再邀您回…

判断交叉编译工具是否支持C++20的标准

写个任意的测试程序hello_world 执行 arm-linux-gnueabihf-g -stdc14 main.cpp arm-linux-gnueabihf-g -stdc17 main.cpp arm-linux-gnueabihf-g -stdc20 main.cpp没报错则代表支持&#xff0c;报错则不支持.

ChatGPT写论文最强指令

一、我正在寻找与&#xff08;XX主题&#xff09;相关的高质量学术资源&#xff0c;包括期刊文章、会议论文和研究报告。希望能获取这些文献的摘要和关键词&#xff0c;以便快速评估其相关性。同时&#xff0c;请根据文献的相关度或发布日期进行排序&#xff0c;并提供完整的引…

Unity 编辑器篇|(六)编辑器拓展EditorGUI类 (全面总结 | 建议收藏)

目录 1. 前言2. 参数3. 功能3.1 折叠菜单&#xff1a; Foldout3.2 检查 GUI 更改&#xff1a; BeginChangeCheck 、EndChangeCheck 监听值改变3.3 可禁用控件&#xff1a;BeginDisabledGroup 、EndDisabledGroup 是否禁用组中的控件3.4 下拉菜单&#xff1a;DropdownButton3.5 …

MySQL 查询数据

今天介绍一下 MySQL 数据库使用 SELECT 语句来查询数据。 语法 首先&#xff0c;介绍一下语法。以下为在 MySQL 数据库中查询数据通用的 SELECT 语法&#xff1a; SELECT column1, column2, ... FROM table_name [WHERE condition] [ORDER BY column_name [ASC | DESC]] [LI…