添加购物车-02.代码开发

news2025/5/13 13:33:19

一.代码开发

购物车属于用户端功能,因此要在user下创建controller代码。

Controller层

package com.sky.controller.user;

import com.sky.dto.ShoppingCartDTO;
import com.sky.entity.ShoppingCart;
import com.sky.result.Result;
import com.sky.service.ShoppingCartService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user/shoppingCart")
@Slf4j
@Api(tags = "购物车相关接口")
public class ShoppingCartController {
    @Autowired
    private ShoppingCartService shoppingCartService;


    /**
     * 添加购物车
     * @param shoppingCartDTO
     * @return
     */
    @ApiOperation("添加购物车")
    @PostMapping("/add")
    public Result add(@RequestBody ShoppingCartDTO shoppingCartDTO) {
        log.info("向购物车中添加菜品或套餐:{}",shoppingCartDTO);
        shoppingCartService.add(shoppingCartDTO);
        return Result.success();
    }
}

前端传递过来的参数是JSON类型的,要使用注解@RequestBody。 ShoppingCartDTO中包含3个属性:setmealId,dishId,dishFlavor。

Service层

接口

package com.sky.service;

import com.sky.dto.ShoppingCartDTO;
import org.springframework.stereotype.Service;

@Service
public interface ShoppingCartService {

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

实现类

package com.sky.service.impl;

import com.sky.context.BaseContext;
import com.sky.dto.ShoppingCartDTO;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.ShoppingCart;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.service.ShoppingCartService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 添加购物车
     * @param shoppingCartDTO
     */
    @Override
    public void add(ShoppingCartDTO shoppingCartDTO) {
        // 首先判断这次添加购物车的操作加入的菜品或套餐是否已经存在,如果存在就把份数+1,如果不存在就新增
        ShoppingCart shoppingCart = new ShoppingCart();
        BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);
        Long userId = BaseContext.getCurrentId();
        shoppingCart.setUserId(userId);

        // 1.首先查询该菜品或套餐在数据库中是否存在
        List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);    // 每次添加的要么是菜品,要么是套餐。且如果重复添加只会增加份数而不会新增一条数据,因此每次查询要么为空,要么查询出1条数据

        if (list != null && list.size() > 0) {      // 已存在,数量+1
            ShoppingCart cart = list.get(0);    // 将已存在的购物车对象取出
            cart.setNumber(cart.getNumber() + 1);   // 并将其菜品/套餐数量+1
            shoppingCartMapper.updateNumberById(cart);      // 通过id更新
        } else {
            // 2.不存在,先判断是套餐还是菜品,因为套餐和菜品在购物车中所需要的属性是不一样的
            Long dishId = shoppingCartDTO.getDishId();
            if (dishId != null) {
                // 3.如果是菜品,那么从菜品数据库中查找并将对应属性赋值给购物车对象
                Dish dish = dishMapper.getById(dishId);
                shoppingCart.setName(dish.getName());
                shoppingCart.setImage(dish.getImage());
                shoppingCart.setAmount(dish.getPrice());
            } else {
                // 4.如果是套餐,那么从套餐数据库中查找并将对应属性赋值给购物车对象
                Long setmealId = shoppingCartDTO.getSetmealId();
                Setmeal setmeal = setmealMapper.getById(setmealId);
                shoppingCart.setName(setmeal.getName());
                shoppingCart.setImage(setmeal.getImage());
                shoppingCart.setAmount(setmeal.getPrice());
            }
            // 5.将新增的菜品/套餐加入数据库中
            shoppingCart.setNumber(1);
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCartMapper.insert(shoppingCart);
        }
    }
}

 首先判断这次添加购物车的操作加入的菜品或套餐是否已经存在,如果存在就把份数+1,如果不存在就新增。首先我们创建一个购物车对象shoppingCart,然后将shoppingCartDTO的属性赋值给shoppingCart。接着我们通过前端请求的JWT令牌来获得登录用户的用户id作为shoppingCart对象的userId字段。接着我们进行以下操作:

1.首先查询该菜品或套餐在数据库中是否存在。请注意:每次添加的要么是菜品,要么是套餐。且如果重复添加只会增加份数而不会新增一条数据,因此每次查询要么为空,要么查询出1条数据

如果存在,那么将其数量+1即可,即进行数据库的查询和修改操作。

2.如果不存在,先判断是套餐还是菜品,因为套餐和菜品在购物车中所需要的属性是不一样的。如何判断?通过shoppingCartDTO中的dishId和setmealId判断,哪个不为空就是哪个。

3.如果是菜品,那么从菜品数据库中查找并将对应属性赋值给购物车对象。

4.如果是套餐,那么从套餐数据库中查找并将对应属性赋值给购物车对象。

5.将新增的菜品/套餐加入数据库中。

Mapper层

package com.sky.mapper;

import com.sky.entity.ShoppingCart;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;

import java.util.List;

@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, image, user_id, dish_id, setmeal_id, dish_flavor, number, amount, create_time) " +
            "VALUES (#{name}, #{image}, #{userId}, #{dishId}, #{setmealId}, #{dishFlavor}, #{number}, #{amount},#{createTime})")
    void insert(ShoppingCart shoppingCart);
}

首先查询是否存在,不存在就执行insert操作,存在就执行update操作。 

 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" resultType="com.sky.entity.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>
    </select>
</mapper>

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

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

相关文章

Unity动画系统使用整理 --- Playable

​​Playable API​​ 是一个强大的工具&#xff0c;用于更灵活地控制动画、音频、脚本等时间轴内容的播放和混合。它提供了比传统 Animator 更底层、更可控的方式管理时间轴行为&#xff0c;尤其适合复杂动画逻辑或动态内容组合的场景。 优点&#xff1a; 1.Playables API 支…

Xilinx FPGA PCIe | XDMA IP 核 / 应用 / 测试 / 实践

注&#xff1a;本文为 “Xilinx FPGA 中 PCIe 技术与 XDMA IP 核的应用” 相关文章合辑。 图片清晰度受引文原图所限。 略作重排&#xff0c;未整理去重。 如有内容异常&#xff0c;请看原文。 FPGA&#xff08;基于 Xilinx&#xff09;中 PCIe 介绍以及 IP 核 XDMA 的使用 N…

winreg查询Windows注册表的一些基本用法

注册表是Windows操作系统中用于存储配置信息的数据库。它包含了关于系统硬件、已安装的应用程序、用户账户设置以及系统设置的信息。 特别地&#xff0c;当我们需要某些软件的配置配息时&#xff0c;主要在HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE下的SoftWare内进行查询操作。 …

计算机网络|| 路由器和交换机的配置

一、实验目的 1. 了解路由器和交换机的工作模式和使用方法&#xff1b; 2. 熟悉 Cisco 网络设备的基本配置命令&#xff1b; 3. 掌握 Cisco 路由器的基本配置方式及配置命令&#xff1b; 4. 掌握路由器和交换机的基本配置与管理方法。 二、实验环境 1. 运行 Windows 操作…

推理加速新范式:火山引擎高性能分布式 KVCache (EIC)核心技术解读

资料来源&#xff1a;火山引擎-开发者社区 分布式 KVCache 的兴起 背景 在大模型领域&#xff0c;随着模型参数规模的扩大和上下文长度增加&#xff0c;算力消耗显著增长。在 LLM 推理过程中&#xff0c;如何减少算力消耗并提升推理吞吐已经成为关键性优化方向。以多轮对话场…

中央处理器(CPU)(概述、指令周期)

一、概述 主要功能&#xff1a;&#xff08;1&#xff09;程序控制&#xff08;2&#xff09;操作控制&#xff08;3&#xff09;时序控制&#xff08;4&#xff09;数据加工&#xff08;5&#xff09;中断处理 组成&#xff1a;早期冯诺依曼计算机的 CPU 主要由运算器和控制…

MiniCPM-V

一、引言 在多模态大语言模型(MLLMs)快速发展的背景下,现有模型因高参数量(如 72B、175B)和算力需求,仅能部署于云端,难以适配手机、车载终端等内存和算力受限的端侧设备。MiniCPM-V聚焦 “轻量高效” 与 “端侧落地”,通过架构创新、训练优化和部署适配,打造高知识密…

Screeps Arena基础入门

本文主要内容 JavaSsript语法使用VScode编译环境Screeps Arena游戏规则 JavaSsript语法使用 基本数据类型 // String, Numker,Boolean,null, undefined const username "John"; const age 30; const rate 4.5; const iscool true; const x null; #表示值为…

开疆智能Profinet转Canopen网关连接sick RFID读写器配置案例

打开CANopen总线配置软件设置CANopen参数&#xff1a; 1. 使用Profinet转CANopen网关的配置软件修改CANopen主站参数&#xff1a; 首先新建项目&#xff0c;选择对应网关模块 2. 设置波特率&#xff1a;250 kbps&#xff08;需与SICK RFID读写器一致&#xff09;。 设置同步…

17.three官方示例+编辑器+AI快速学习webgl_buffergeometry_lines

本实例主要讲解内容 这个Three.js示例展示了如何使用BufferGeometry创建大量线段&#xff0c;并通过**变形目标(Morph Targets)**实现动态变形效果。通过随机生成的点云数据&#xff0c;结合顶点颜色和变形动画&#xff0c;创建出一个视觉效果丰富的3D线条场景。 核心技术包括…

深入掌握CSS定位:构建精密布局的核心技术

一、定位的定义 定位&#xff08;Positioning&#xff09;是CSS中用于控制元素在网页中的具体位置的一种机制。通过定位&#xff0c;可以将元素放置在页面的任意位置&#xff0c;并控制其与其他元素的层叠关系。 二、定位的特点与作用 自由摆放位置&#xff1a; 允许元素摆放…

Go语言多线程爬虫与代理IP反爬

有个朋友想用Go语言编写一个多线程爬虫&#xff0c;并且使用代理IP来应对反爬措施。多线程在Go中通常是通过goroutine实现的&#xff0c;所以应该使用goroutine来并发处理多个网页的抓取。然后&#xff0c;代理IP的话&#xff0c;可能需要一个代理池&#xff0c;从中随机选择代…

node.js 实战——express图片保存到本地或服务器(七牛云、腾讯云、阿里云)

本地 ✅ 使用formidable 读取表单内容 npm i formidable ✅ 使用mime-types 获取图片后缀 npm install mime-types✅ js 中提交form表单 document.getElementById(uploadForm).addEventListener(submit, function(e){e.preventDefault();const blob preview._blob;if(!blob)…

Shadertoy着色器移植到Three.js经验总结

Shadertoy是一个流行的在线平台&#xff0c;用于创建和分享WebGL片段着色器。里面有很多令人惊叹的画面&#xff0c;甚至3D场景。本人也移植了几个ShaderToy上的着色器。本文将详细介绍移植过程中需要注意的关键点。 1. 基本结构差异 想要移植ShaderToy的shader到three.js&am…

电脑端音乐播放器推荐:提升你的听歌体验!

在快节奏的职场环境中&#xff0c;许多上班族都喜欢用音乐为工作时光增添色彩。今天要分享的这款音乐工具&#xff0c;或许能为你的办公时光带来意想不到的惊喜。 一、软件介绍-澎湃 澎湃音乐看似是个普通的播放器&#xff0c;实则藏着强大的资源整合能力。左侧功能栏清晰陈列着…

VIC-2D 7.0 为平面样件机械试验提供全视野位移及应变数据软件

The VIC-2D系统是一个完全集成的解决方案&#xff0c;它基于优化的相关算法为平面试样的力学测试提供非接触、全场的二维位移和应变数据&#xff0c;可测量关注区域内的每个像素子集的面内位移&#xff0c;并通过多种张量选项计算全场应变。The VIC-2D 系统可测量超过 2000%变形…

一周学完计算机网络之三:1、数据链路层概述

简单的概述 数据链路层是计算机网络体系结构中的第二层&#xff0c;它在物理层提供的基本服务基础上&#xff0c;负责将数据从一个节点可靠地传输到相邻节点。可以将其想象成一个负责在两个相邻的网络设备之间进行数据 “搬运” 和 “整理” 的 “快递中转站”。 几个重要概念…

单片机-STM32部分:13-1、蜂鸣器

飞书文档https://x509p6c8to.feishu.cn/wiki/V8rpwIlYIiEuXLkUljTcXWiKnSc 一、应用场景 大部分的电子产品、家电&#xff08;风扇、空调、电水壶&#xff09;都会有蜂鸣器&#xff0c;用于提示设备的工作状态 二、原理 蜂鸣器是一种将电信号转换为声音信号的器件&#xff0…

动态IP技术赋能业务创新:解锁企业数字化转型新维度

在数字经济高速发展的今天&#xff0c;IP地址已不再是简单的网络标识符&#xff0c;而是演变为支撑企业数字化转型的核心基础设施之一。动态IP技术凭借其灵活、高效、安全的特性&#xff0c;正在重塑传统业务模式&#xff0c;催生出诸多创新应用场景。本文将深入剖析动态IP的技…

TDengine 在金融领域的应用

简介 金融行业正处于数据处理能力革新的关键时期。随着市场数据量的爆炸式增长和复杂性的日益加深&#xff0c;金融机构面临着寻找能够高效处理大规模、高频次以及多样化时序数据的大数据处理系统的迫切需求。这一选择将成为金融机构提高数据处理效率、优化交易响应时间、提高…