目录

添加查询删除购物车逻辑及其代码

难点-代码复杂下单功能


项目基于spring boot,同样都是需要mvc三层架构+实体bean类。

在这先抛出几个问题。如何添加购物车,如何查询购物车,如何删除购物车。

  1. 在数据库这块,先分析前段保存的数据,与数据库对应的关系
  2. F12查看前端传输的数据,可以查看到传输的路径和相对应的信息

———————————————————————————————————————————

在理清逻辑之后,开始bean类的构建,继承Serializable接口,Long类型需要序列化的注解格式为:@JsonSerialize(using = ToStringSerializer.class)

*然后是mapper接口。

@Mapper
public interface ShoppingCartMapper extends BaseMapper<ShoppingCart> {     }

*业务层接口 ShoppingCartService

public interface ShoppingCartService extends IService<ShoppingCart> {     }

*业务层实现类 ShoppingCartServiceImpl

@Service
public class ShoppingCartServiceImpl extends ServiceImpl<ShoppingCartMapper, ShoppingCart> implements ShoppingCartService {     }

控制层 ShoppingCartController

@Slf4j
@RestController
@RequestMapping("/shoppingCart")
public class ShoppingCartController {
    @Autowired
    private ShoppingCartService shoppingCartService;
 }

———————————————————————————————————————————

添加查询删除购物车逻辑及其代码

在ShoppingCartController中创建add方法,

由于表的特殊性,来完成添加购物车的逻辑实现。

添加购物车。

@PostMapping("/add")public R<ShoppingCart> add(@RequestBody ShoppingCart shoppingCart){log.info("添加到购物车中的购物项:"+shoppingCart);// 目标 shoppingCart 数据补全 存到数据库中// 1:购物项少 登录人id id在呢呢 session域中// 啥时候存的  登录时候存的  可以从session取 没毛病// 过滤器在做登录权限校验的时候,把用户id放到了线程中。// 还可以从当前线程中取出Long userId = BaseContext.getCurrentId();//存进去shoppingCart.setUserId(userId);//2: 这个购物项 用户点了几份?/*去数据库查,如果数据库没有,这是第一份。数据库添加数据如果数据库有,在原有的份数上+1。数据库进行更新份数*/// 怎么查询该用户有没有添加过 该套餐/菜品呢?
// select * from  shopping_cart where user_id=? and dish_id=?
// select * from  shopping_cart where user_id=? and setmeal_id=?LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ShoppingCart::getUserId,userId);// select * from  shopping_cart where user_id=?//shoppingCart 添加购物项数据if(shoppingCart.getDishId()!=null){ //添加的菜品wrapper.eq(ShoppingCart::getDishId,shoppingCart.getDishId());}else{//添加的套餐wrapper.eq(ShoppingCart::getSetmealId,shoppingCart.getSetmealId());}// select * from  shopping_cart where user_id=? and dish_id=?// select * from  shopping_cart where user_id=? and setmeal_id=?// 查询  上面两个sql其中一个ShoppingCart one = shoppingCartService.getOne(wrapper);// one 就是 从数据库查出来 购物项(菜品or套餐)数据if(one==null){//说明没有 需要添加 份数是1shoppingCart.setNumber(1);shoppingCart.setCreateTime(LocalDateTime.now());//完成添加shoppingCartService.save(shoppingCart);//  return R.success(shoppingCart);//返回添加到数据库的数据}else{// one 查出来的 购物项 原来的信息// 需要更新数量one.setNumber(one.getNumber()+1);// 更新shoppingCartService.updateById(one);// return R.success(one);//返回 更新到数据库的数据shoppingCart=one;}return R.success(shoppingCart);}

删除购物车:

 /***  清空指定用户的购物项*/@DeleteMapping("/clean")public R<String> clean(){log.info("清空用户的所有购物项");// 当前用户指的是 谁登录是谁Long userId = BaseContext.getCurrentId();// delete from shoppingCart where user_id=?LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ShoppingCart::getUserId,userId);shoppingCartService.remove(wrapper);return R.success("清空成功");}

查询购物车:

/*** 查询 某个用户所有的购物项信息 在页面进行展示*/@GetMapping("/list")public R<List> list(){log.info("查询当前用户的 购物项信息!!");// 当前用户指的是 谁登录是谁Long userId = BaseContext.getCurrentId();// 怎么查询该用户的购物项// select * from shopping_cart where user_id = ?LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ShoppingCart::getUserId,userId);List<ShoppingCart> list = shoppingCartService.list(wrapper);return R.success(list);}

购物车-1:

 @PostMapping("/sub")public R<ShoppingCart> sub(@RequestBody ShoppingCart shoppingCart){log.info("需要更新的购物项(可能是菜品可能是套餐):"+shoppingCart);/*去数据库 根据 菜品id/套餐id 查询指定用户 的购物项信息*/Long userId = BaseContext.getCurrentId();//2: 这个购物项 用户点了几份?/*去数据库查,查询当前购物项,更新份数  份数-1检查更新后的份数如果是 0  说明没了,数据库要进行删除。如果不是0, 把最新的购物项数据更新到数据库*/LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ShoppingCart::getUserId,userId);// select * from  shopping_cart where user_id=?//shoppingCart 添加购物项数据if(shoppingCart.getDishId()!=null){ //添加的菜品wrapper.eq(ShoppingCart::getDishId,shoppingCart.getDishId());}else{//添加的套餐wrapper.eq(ShoppingCart::getSetmealId,shoppingCart.getSetmealId());}// select * from  shopping_cart where user_id=? and dish_id=?// select * from  shopping_cart where user_id=? and setmeal_id=?// 查询  上面两个sql其中一个ShoppingCart one = shoppingCartService.getOne(wrapper);// 先做了更新 份数  份数-1one.setNumber(one.getNumber()-1);if(one.getNumber()==0){//没了 删除// 根据条件删 delete from  shopping_cart where user_id=? and dish_id=?//    delete  from  shopping_cart where user_id=? and setmeal_id=?shoppingCartService.remove(wrapper);}else{ // 还有 更新shoppingCartService.updateById(one);}return R.success(one);}

下单功能:

同样的,新建或者导入bean类还有三层结构。

bean 数据库表 mapper接口 service接口 cerviceImpl实现类 还有controller类

需求分析:

移动端用户将菜品或者套餐加入购物车后,可以点击购物车中的 "去结算" 按钮,页面跳转到订单确认页面,点击 "去支付" 按钮则完成下单操作。

个人的话由于没有企业资质,支付的接口先不做开发。

在开发代码之前,需要梳理一下用户下单操作时前端页面和服务端的交互过程:

基本逻辑:

A. 获得当前用户id, 查询当前用户的购物车数据

B. 根据地址ID, 查询地址数据

C. 组装订单明细数据, 计算订单总价值,批量保存订单明细

D. 组装订单数据(订单Id ,日期、状态、价值、订单编号等), 保存订单数据

E. 删除当前用户的购物车列表数据

由于下单的逻辑相对复杂,我们可以在OrderService中定义submit方法,来处理下单的具体逻辑

@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {@Autowiredprivate ShoppingCartService shoppingCartService;@Autowiredprivate AddressBookService addressBookService;@Autowiredprivate UserService userService;@Autowiredprivate OrderDetailService orderDetailService;@Override@Transactionalpublic void submit(Orders orders) {//1.1 查看 有什么数据// 地址簿idLong addressBookId = orders.getAddressBookId();// 备注String remark = orders.getRemark();// 支付方式Integer payMethod = orders.getPayMethod();// 1.2 缺什么  根据已知条件能不能找到缺失内容// 解决跟地址相关的数据 因为知道地址簿 就可找到地址相关数据AddressBook addressBook = addressBookService.getById(addressBookId);//  谁登录 就根据谁查询//先获取用户id 登录的用户Long userId = BaseContext.getCurrentId();User user = userService.getById(userId);//用uuid完成//String number = UUID.randomUUID().toString().replace("-", "");//String number = IdWorker.get32UUID(); 32位uuidString number = IdWorker.getId()+"";// 雪花算法19位LocalDateTime now = LocalDateTime.now();// 1.3 把缺的补上// 订单号orders.setNumber(number);// 用户id  用户名字orders.setUserId(userId);orders.setUserName(user.getName());// 没有名字不用做这一步...// 地址簿相关信息orders.setConsignee(addressBook.getConsignee());orders.setPhone(addressBook.getPhone());orders.setAddress(addressBook.getDetail());// 下单和 结算时间orders.setOrderTime(now);orders.setCheckoutTime(now);log.info("开始计算总金额");//开始sql语句拼总账单金额。定义累加的总金额数据  初始值是0BigDecimal amount = new BigDecimal(0);// 总金额的获取 就 结合 购物项和订单转换了....//2:把购物项信息转换成 订单信息 存到数据库中// 2.1 查询 当前用户的 指定的所有的购物项信息LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ShoppingCart::getUserId,userId);List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper);log.info("同时开始进行购物项和订单明细转换");// shoppingCarts 是该用户的所有购物项信息// 把所有的购物项 全部变成 所有的订单(明细)项集合List<OrderDetail> orderDetails = new ArrayList<>();//开始遍历了。for (ShoppingCart shoppingCart : shoppingCarts) {OrderDetail orderDetail = new OrderDetail();BeanUtils.copyProperties(shoppingCart,orderDetail,"id");// orderDetail   除了订单id        shoppingCart里面都有orderDetail.setOrderId(Long.parseLong(number));orderDetails.add(orderDetail);// 计算总金额// 单价 和 份数BigDecimal danjia = shoppingCart.getAmount();BigDecimal fenshu = new BigDecimal(shoppingCart.getNumber());BigDecimal xiaoji = danjia.multiply(fenshu);//已经算出小计的价钱amount = amount.add(xiaoji);}orders.setAmount(amount);//得到了有数据的  orderDetails集合 保存// 保存两个数据//orders数据this.save(orders);orderDetailService.saveBatch(orderDetails);// 3:清空购物车 写过这个功能log.info("3:清空该用户的所有购物项");// delete  from shopping_cart where user_id=用户idshoppingCartService.remove(wrapper);}
}

需要仔细看看其中的逻辑信息。

购物车及下单的逻辑知识点相关推荐

  1. vue2 + vuex 高度还原 饿了么 App,用真实数据登陆官网,并实现购物车、下单功能

    前言 vue2的发布后自己也研究了一段时间,奈何公司的技术栈是以react为主,没有机会好好利用vue2去做一个完整的项目.虽然写了几个demo,但和写一个完整的项目还是有很大差别的.于是自己想着用空 ...

  2. 【SpringBoot项目实战+思维导图】瑞吉外卖⑥(用户地址簿功能、菜品展示、购物车、下单)

    文章目录 用户地址簿功能 需求分析 数据模型 导入功能代码 功能测试 思维导图总结 菜品展示 需求分析 前端页面分析 代码开发 查询菜品方法修改 根据分类ID查询套餐 功能测试 思维导图总结 购物车 ...

  3. vue2 + vuex 高度还原 饿了么 App,与官方后台真实数据交互,实现登陆、购物车、下单等功能...

    [b]前言[/b] vue2的发布后自己也研究了一段时间,奈何公司的技术栈是以react为主,没有机会好好利用vue2去做一个完整的项目.虽然写了几个demo,但和写一个完整的项目还是有很大差别的.于 ...

  4. vue2 + vuex 高度还原 饿了么 App,与官方后台真实数据交互,获取商品信息,实现登陆、购物车、下单等功能...

    前言 vue2的发布后自己也研究了一段时间,奈何公司的技术栈是以react为主,没有机会好好利用vue2去做一个完整的项目.虽然写了几个demo,但和写一个完整的项目还是有很大差别的.于是自己想着用空 ...

  5. SSM实战-外卖项目-06-用户地址簿功能、菜品展示、购物车、下单(一个业务涉及5张表)

    文章目录 外卖项目-第六天 课程内容 1. 用户地址簿功能 1.1 需求分析 1.2 数据模型 1.3 导入功能代码 1.4 功能测试 (其实需求分析里我就自己写了一份代码,而且测试过了,下面再测试了 ...

  6. python flask实战订餐系统微信小程序-54删除购物车以及下单页面跳转功能实现

    B站配套视频教程观看 动态计算价格 index.js ,totalPrice: function () {var list = this.data.list;var totalPrice = 0.00 ...

  7. mysql中的逻辑类型如何定义_MYSQL存储过程即常用逻辑知识点总结

    Mysql存储过程 1.创建存储过程语法(格式) DELIMITER $ CREATE PROCEDURE 存储过程名A(IN 传入参数名a INT,IN 传入参数名b VARCHAR(20),OUT ...

  8. 商品服务(SKU、下单流程、购物车、优惠券设计)

    一.两个概念SKU.SPU SKU:最小库存单位(裤子-蓝色-XS大小---->对应一个库存) SPU:商品具有的属性,不涉及到库存 (一)SKU相关表的设计: (1) pms_product_ ...

  9. Java架构师,大数据架构师,高并发设计模式,机器学习知识点分享

    第一章:java精品课程目录大全 1.亿级流量电商详情页系统的大型高并发与高可用缓存架构实战 1课程介绍以及高并发高可用复杂系统中的缓存架构有哪些东西?32分钟 2基于大型电商网站中的商品详情页系统贯 ...

最新文章

  1. 小学五年级计算机教学论文,小学五年级数学教学论文 如何激发学生学习数学的兴趣...
  2. Postgres 9.5的特性及未来发展方向
  3. 【转】JPG打包压缩后比原来尺寸还大
  4. PHP常用工具函数之手机号相关
  5. [坑] IDEA Unable to import maven project 解决办法
  6. SAP UI5 binding syntax - model name + + attribute name
  7. 最强NLP模型BERT可视化学习
  8. python numpy安装失败_解决python3.x安装numpy成功但import出错的问题
  9. 宝可梦推出「电子鸡」新游戏 训练师赶紧将可爱伊布带回家!
  10. python在线编辑器手机-QPython,一个在手机上运行Python的神器
  11. Docker使用小结(一)Docker镜像以及Docker容器
  12. Action类为何要继承ActionSupport
  13. c 语言随机生成迷宫,[原创]递归随机迷宫生成算法详解
  14. 通过线程八锁问题融会贯通synchronized关键字的使用
  15. Spring切入点表达式
  16. matlab画一个放大图中图
  17. 余弦cos计算相似度
  18. linux管理光标显示与否
  19. Apollo无人驾驶课程笔记 第四课-感知
  20. 海康监控主机无法登录后台解决办法

热门文章

  1. html年龄怎么设置,js+html实现周岁年龄计算器
  2. java runnable接口_java实现Runnable接口适合资源的共享
  3. 2020天猫“双11”全球狂欢季成交额达4982亿元!再次刷新纪录!
  4. 软件平台新思维:iPhone思维影响中国软件商
  5. 本地jar包推送到maven私有仓库常用的3种方式
  6. Vue中Html2canvas生成网页局部截图
  7. ES6之 函数(五)
  8. Android - 最基础的控件TextView
  9. [ZT]理光R1V夜景拍摄技巧
  10. sql语句之CONCAT 函数