购物车及下单的逻辑知识点

目录

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

难点-代码复杂下单功能


项目基于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){//说明没有 需要添加 份数是1
            shoppingCart.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);
        // 先做了更新 份数  份数-1
        one.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 {
    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Override
    @Transactional
    public void submit(Orders orders) {
        //1.1 查看 有什么数据
        // 地址簿id
        Long 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位uuid
        String 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语句拼总账单金额。定义累加的总金额数据  初始值是0
        BigDecimal 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=用户id
        shoppingCartService.remove(wrapper);

    }
}

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值