news 2026/8/5 8:05:12

苍穹外卖【day7| 对购物车进行操作】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
苍穹外卖【day7| 对购物车进行操作】

🌈个人主页:一条泥憨鱼(欢迎各位大佬莅临)

🎬精选专栏传送门:

❄️《数据结构》 ❄️《AI与Agent那些事》

❄️《从0开始学计算机网络》 ❄️《后端开发》

添加购物车

需求分析和设计

数据库设计

代码开发

1️⃣ 数据传输层 (DTO)

ShoppingCartDTO.java

@Data public class ShoppingCartDTO implements Serializable { private Long dishId; // 菜品ID private Long setmealId; // 套餐ID private String dishFlavor; // 菜品口味 }

作用:接收前端传来的添加购物车请求数据,只包含必要的前端参数。

2️⃣ 实体类 (Entity)

ShoppingCart.java

@Data @Builder public class ShoppingCart implements Serializable { private Long id; private String name; // 商品名称 private Long userId; // 用户ID private Long dishId; // 菜品ID private Long setmealId; // 套餐ID private String dishFlavor; // 口味 private Integer number; // 数量 private BigDecimal amount; // 金额 private String image; // 图片 private LocalDateTime createTime; // 创建时间 }

作用:购物车的完整数据模型,对应数据库表结构。

3️⃣ 控制层 (Controller)

ShoppingCartController.java

@RestController @RequestMapping("/user/shoppingCart") @Api(tags = "C端购物车相关接口") public class ShoppingCartController { @Autowired private ShoppingCartService shoppingCartService; @PostMapping("/add") @ApiOperation("添加购物车") public Result add(@RequestBody ShoppingCartDTO shoppingCartDTO){ log.info("添加购物车,商品信息为:{}", shoppingCartDTO); shoppingCartService.addShoppingCart(shoppingCartDTO); return Result.success(); } }
  • 路由POST /user/shoppingCart/add
  • 功能:接收JSON请求,调用service层处理,返回成功结果
  • 使用@Slf4j:启用Lombok日志

4️⃣ 服务接口层 (Service Interface)

ShoppingCartService.java

public interface ShoppingCartService { void addShoppingCart(ShoppingCartDTO shoppingCartDTO); }

5️⃣ 服务实现层 (Service Implementation)

ShoppingCartServiceImpl.java

@Service @Slf4j public class ShoppingCartServiceImpl implements ShoppingCartService { @Autowired private ShoppingCartMapper shoppingCartMapper; @Autowired private DishMapper dishMapper; @Autowired private SetmealMapper setmealMapper; public void addShoppingCart(ShoppingCartDTO shoppingCartDTO){ // 1. 构建查询条件 ShoppingCart shoppingCart = new ShoppingCart(); BeanUtils.copyProperties(shoppingCartDTO, shoppingCart); Long userId = BaseContext.getCurrentId(); // 获取当前登录用户ID shoppingCart.setUserId(userId); // 2. 查询当前用户的购物车中是否已有该商品 List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart); // 3. 如果存在该商品,数量+1 if(list != null && list.size() > 0){ ShoppingCart cart = list.get(0); cart.setNumber(cart.getNumber() + 1); shoppingCartMapper.updateNumberById(cart); } // 4. 如果不存在,需要新增一条记录 else { // 判断是菜品还是套餐 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 { // 添加的是套餐 Long setmealId = shoppingCartDTO.getSetmealId(); Setmeal setmeal = setmealMapper.getById(setmealId); shoppingCart.setName(setmeal.getName()); shoppingCart.setImage(setmeal.getImage()); shoppingCart.setAmount(setmeal.getPrice()); } shoppingCart.setNumber(1); shoppingCart.setCreateTime(LocalDateTime.now()); shoppingCartMapper.insert(shoppingCart); } } }

核心业务逻辑

  1. 用户隔离:通过BaseContext.getCurrentId()获取当前用户ID,确保每个用户只能操作自己的购物车
  2. 存在性检查:先查询购物车是否已存在相同商品(判断条件:userId + dishId/setmealId + dishFlavor)
  3. 数量累加:如果已存在,只需将数量number + 1
  4. 新增记录:如果不存在,根据 dishId 或 setmealId 查询商品信息,插入新记录

6️⃣ 数据访问层 (Mapper)

ShoppingCartMapper.java

@Mapper public interface ShoppingCartMapper { // 动态条件查询 List<ShoppingCart> list(ShoppingCart shoppingCart); // 根据id修改商品数量 @Update("update shopping_cart set number = #{number} where id = #{id}") void updateNumberById(ShoppingCart 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); }

7️⃣ 用户上下文工具类

BaseContext.java

public class BaseContext { public static ThreadLocal<Long> threadLocal = new ThreadLocal<>(); public static Long getCurrentId() { return threadLocal.get(); } public static void setCurrentId(Long id) { threadLocal.set(id); } }

查看购物车

需求分析和设计

代码开发

1️⃣ 控制层 (Controller)

ShoppingCartController.java

@GetMapping("/list") @ApiOperation("查看购物车") public Result<List<ShoppingCart>> list (){ List<ShoppingCart> list = shoppingCartService.showShoppingCart(); return Result.success(list); }
  • 路由GET /user/shoppingCart/list
  • 返回类型Result<List<ShoppingCart>>- 包装了购物车列表
  • 功能:查询当前用户的购物车列表并返回

2️⃣ 服务实现层 (Service Implementation)

ShoppingCartServiceImpl.java

//查看购物车 public List<ShoppingCart> showShoppingCart(){ //获取到当前微信用户的id Long userId = BaseContext.getCurrentId(); ShoppingCart shoppingCart = ShoppingCart.builder() .userId(userId) .build(); List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart); return list; }
  1. 用户隔离:通过BaseContext.getCurrentId()获取当前登录用户ID
  2. 构建查询条件:只按userId查询,确保用户只能看到自己的购物车
  3. 调用Mapper:执行数据库查询并返回结果

3️⃣ Mapper 接口层

ShoppingCartMapper.java

@Mapper public interface ShoppingCartMapper { //动态条件查询 List<ShoppingCart> list(ShoppingCart shoppingCart); //根据id修改商品数量 @Update("update shopping_cart set number = #{number} where id = #{id}") void updateNumberById(ShoppingCart shoppingCart); //插入购物车数据 @Insert("insert into shopping_cart...") void insert(ShoppingCart shoppingCart); }

4️⃣ MyBatis XML 映射文件核心SQL

ShoppingCartMapper.xml

<select id="list" resultType="com.sky.entity.ShoppingCart"> select * from shopping_cart <where> <if test="userId != null"> and user_id = #{userId} </if> <if test="setmealId != null"> and setmeal_id = #{setmealId} </if> <if test="dishId != null"> and dish_id = #{dishId} </if> <if test="dishFlavor != null"> and dish_flavor = #{dishFlavor} </if> </where> </select>

🔄 完整请求流程

前端 GET /user/shoppingCart/list ↓ ShoppingCartController.list() ↓ ShoppingCartServiceImpl.showShoppingCart() ├── 1. 获取当前用户ID (BaseContext.getCurrentId()) ├── 2. 构建查询条件: ShoppingCart(userId=当前用户) └── 3. 调用 shoppingCartMapper.list() ↓ ShoppingCartMapper.xml.list() ↓ 执行动态SQL: SELECT * FROM shopping_cart WHERE user_id = ? ↓ 返回 List<ShoppingCart> ↓ Result.success(list) 包装结果 ↓ 前端收到购物车列表

清空购物车

需求分析和设计

代码开发

1️⃣ 控制层 (Controller)

ShoppingCartController.java

//清空购物车 @DeleteMapping("/clean") @ApiOperation("清空购物车") public Result clean(){ shoppingCartService.cleanShoppingCart(); return Result.success(); }

2️⃣ 服务接口层 (Service Interface)

ShoppingCartService.java

//清空购物车 void cleanShoppingCart();

3️⃣ 服务实现层 (Service Implementation)核心逻辑

ShoppingCartServiceImpl.java

//清空购物车 public void cleanShoppingCart(){ //获取到当前微信用户的id Long userId = BaseContext.getCurrentId(); shoppingCartMapper.deleteByUserId(userId); }
  1. 用户隔离:通过BaseContext.getCurrentId()获取当前登录用户ID
  2. 只做一件事:调用shoppingCartMapper.deleteByUserId(userId)删除该用户的所有购物车数据
  3. 简洁至上:清空购物车不需要复杂的业务逻辑,只需按用户ID删除

4️⃣ 数据访问层 (Mapper) ⭐核心SQL

ShoppingCartMapper.java

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

🔄 完整请求流程

前端 DELETE /user/shoppingCart/clean ↓ ShoppingCartController.clean() ↓ ShoppingCartServiceImpl.cleanShoppingCart() ├── 1. 获取当前用户ID (BaseContext.getCurrentId()) └── 2. 调用 shoppingCartMapper.deleteByUserId(userId) ↓ 执行SQL: DELETE FROM shopping_cart WHERE user_id = ? ↓ 数据库中该用户的所有购物车记录被删除 ↓ Result.success() // 返回成功 ↓ 前端收到成功响应,购物车已清空

至此,操作购物车的代码开发已经全部结束

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/5 8:04:20

STM32+DHT11+OLED温湿度检测系统:从时序调试到工程实践

为什么很多嵌入式初学者做的第一个项目都是“温湿度检测系统”&#xff1f;因为它看起来简单——传感器、单片机、显示屏&#xff0c;连上线就能跑。但真正动手后&#xff0c;你会发现&#xff0c;从DHT11的时序调试到OLED的I2C驱动&#xff0c;从Proteus的仿真到STM32的HAL库配…

作者头像 李华
网站建设 2026/8/5 8:00:50

大型医药集团数字化转型攻略:打造未来医药行业的领航者(PPT)

很多医药集团做信息化规划&#xff0c;最后都栽在同一个问题上&#xff1a;系统买了不少&#xff0c;钱花了不少&#xff0c;但集团总部还是看不清下面各个厂子和公司的真实经营情况&#xff0c;报表合并要等半个月&#xff0c;费用报销卡在中间表跑一天&#xff0c;WMS 管不到…

作者头像 李华
网站建设 2026/8/5 7:57:33

从零构建AI智能体:基于ReAct模式与LangChain的工程实践指南

如果你是一名开发者&#xff0c;最近可能被各种“AI Agent”和“超级智能体”的概念刷屏了。从OpenAI的o1到DeepSeek的DeepSeek-R1&#xff0c;再到各路创业公司&#xff0c;似乎不搞个“智能体”就落伍了。但热闹背后&#xff0c;一个核心问题却越来越模糊&#xff1a; 我们到…

作者头像 李华
网站建设 2026/8/5 7:57:31

机器人导航系统实战:从定位、路径规划到多传感器融合的工程实现

1. 项目概述&#xff1a;从“能走”到“会走”的跨越聊到机器人导航&#xff0c;很多人的第一反应可能是科幻电影里那些在复杂环境中穿梭自如的机器人。但在现实中&#xff0c;让一个机器人从A点移动到B点&#xff0c;并且不撞墙、不迷路、不走冤枉路&#xff0c;这背后是一整套…

作者头像 李华
网站建设 2026/8/5 7:55:11

ZooKeeper 3.7.1三节点集群部署:myid、选举与同步测试

前言 在本地学习ZooKeeper时&#xff0c;通常只需要启动一个服务端&#xff0c;再连接localhost:2181完成节点的创建和查询。这种方式适合熟悉命令&#xff0c;但单个进程停止后&#xff0c;整个协调服务就无法继续提供访问。 ZooKeeper集群通常由奇数个节点组成。三节点集群…

作者头像 李华