首页 > 其他分享 >SpringBoot 项目实战 | 瑞吉外卖 Day06

SpringBoot 项目实战 | 瑞吉外卖 Day06

时间:2023-02-10 19:55:31浏览次数:58  
标签:SpringBoot addressBook Day06 qiuluo Result 外卖 reggie import com

该系列将记录一份完整的实战项目的完成过程,该篇属于第六天

案例来自B站黑马程序员Java项目实战《瑞吉外卖》,请结合课程资料阅读以下内容

该篇我们将完成以下内容:

  • 用户地址簿相关功能
  • 菜品展示
  • 购物车
  • 下单

用户地址簿相关功能

视频中将这部分代码直接给出,我们下面简单进行解释并给出代码

准备工作

首先我们需要知道用户地址簿的基本规则:

  • 地址簿用于记录用户的地址信息
  • 用户登录之后才可以操作自己的地址簿信息
  • 同一个用户可以拥有多个地址簿,但只能拥有一个默认地址

然后我们查看所使用的数据表:

img

最后我们需要创建一些简单的Java代码:

实体类AddressBook
数据层AddressBookMapper
业务层接口AddressBookService
业务层AddressBookServiceImpl
服务层AddressBookController

功能实现

下面我们会进行简单说明并给出代码展示,包含有地址簿的所有方法

查询指定用户的全部地址

功能用途:

查看该用户的所有地址

图片展示:

img

代码展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.AddressBook;
import com.qiuluo.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址簿管理
 */
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 查询指定用户的全部地址
     */
    @GetMapping("/list")
    public Result<List<AddressBook>> list(AddressBook addressBook) {
        addressBook.setUserId(BaseContext.getCurrentId());
        log.info("addressBook:{}", addressBook);

        //条件构造器
        LambdaQueryWrapper<AddressBook> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(null != addressBook.getUserId(), AddressBook::getUserId, addressBook.getUserId());
        queryWrapper.orderByDesc(AddressBook::getUpdateTime);

        //SQL:select * from address_book where user_id = ? order by update_time desc
        return Result.success(addressBookService.list(queryWrapper));
    }
}

新增用户地址

功能用途:

增加该用户的地址设置

图片展示:

img

代码展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.AddressBook;
import com.qiuluo.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址簿管理
 */
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 设置默认地址
     */
    @PutMapping("default")
    public Result<AddressBook> setDefault(@RequestBody AddressBook addressBook) {
        log.info("addressBook:{}", addressBook);
        LambdaUpdateWrapper<AddressBook> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId());
        wrapper.set(AddressBook::getIsDefault, 0);
        //SQL:update address_book set is_default = 0 where user_id = ?
        addressBookService.update(wrapper);

        addressBook.setIsDefault(1);
        //SQL:update address_book set is_default = 1 where id = ?
        addressBookService.updateById(addressBook);
        return Result.success(addressBook);
    }
}

设置默认地址

功能用途:

设置用户的默认地址簿

图片展示:

img

代码展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.AddressBook;
import com.qiuluo.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址簿管理
 */
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 设置默认地址
     */
    @PutMapping("default")
    public Result<AddressBook> setDefault(@RequestBody AddressBook addressBook) {
        log.info("addressBook:{}", addressBook);
        LambdaUpdateWrapper<AddressBook> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId());
        wrapper.set(AddressBook::getIsDefault, 0);
        //SQL:update address_book set is_default = 0 where user_id = ?
        addressBookService.update(wrapper);

        addressBook.setIsDefault(1);
        //SQL:update address_book set is_default = 1 where id = ?
        addressBookService.updateById(addressBook);
        return Result.success(addressBook);
    }
}

查看默认地址

功能用途:

购物车进行订单提交时直接展示默认地址并提交

图片展示:

img

代码展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.AddressBook;
import com.qiuluo.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址簿管理
 */
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 查询默认地址
     */
    @GetMapping("default")
    public Result<AddressBook> getDefault() {
        LambdaQueryWrapper<AddressBook> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId());
        queryWrapper.eq(AddressBook::getIsDefault, 1);

        //SQL:select * from address_book where user_id = ? and is_default = 1
        AddressBook addressBook = addressBookService.getOne(queryWrapper);

        if (null == addressBook) {
            return Result.error("没有找到该对象");
        } else {
            return Result.success(addressBook);
        }
    }
}

查询特定地址

功能用途:

修改地址内容时将该地址回显

图片展示:

img

代码展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.AddressBook;
import com.qiuluo.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址簿管理
 */
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 根据id查询地址
     */
    @GetMapping("/{id}")
    public Result get(@PathVariable Long id) {
        AddressBook addressBook = addressBookService.getById(id);
        if (addressBook != null) {
            return Result.success(addressBook);
        } else {
            return Result.error("没有找到该对象");
        }
    }
}

修改地址内容

功能用途:

修改特定地址的内容

图片展示:

img

代码展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.AddressBook;
import com.qiuluo.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址簿管理
 */
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 额外添加功能:修改地址内容
     */
    @PutMapping
    public Result<String> update(@RequestBody AddressBook addressBook) {

        LambdaQueryWrapper<AddressBook> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(AddressBook::getId,addressBook.getId());
        addressBookService.update(addressBook,queryWrapper);

        return Result.success("修改成功");
    }
}

删除地址内容

功能用途:

删除特定地址的内容

图片展示:

img

代码展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.AddressBook;
import com.qiuluo.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址簿管理
 */
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 额外添加功能:删除地址内容
     * @param ids
     * @return
     */
    @DeleteMapping
    public Result<String> remove(Long ids){

        addressBookService.removeById(ids);

        return Result.success("修改成功");

    }
}

补充内容

上述我们讲解了资料给出的用户簿全部功能并且补充了两个用户簿未实现的方法,想练手的小朋友可以动手尝试一下~

菜品展示

我们的功能开发通常分为三部分

需求分析

我们打开菜品展示页面会发现主页发送了两个请求

第一个请求是关于分类的请求:

img

第二个请求是关于购物车的请求:

img

我们的前端设置只有当两个均可实现时,页面才会展示,所以我们暂时将购物车请求更换一下:

// 该文件处于front/api/main.js下

//获取购物车内商品的集合
function cartListApi(data) {
    return $axios({
       	// 原有代码:'url': '/shoppingCart/list',我们修改为下述代码,该代码指向一个默认购物车,注意需要在资料中导入该文件
        'url': '/front/cartData.json',
        'method': 'get',
        params:{...data}
    })
}

那么我们的界面只需要处理第一个关于分类的请求即可,我们注意请求路径就可以发现这个请求我们之前已经完成了

我们第一个处理点就已经完成了

我们查看第三个请求:

img

然后我们需要注意在菜品的选择中,如果菜品有口味,就要显示选择规格,如果没有口味,就直接是一个加号

所以我们在查看该分类的菜品的代码中需要将该菜品携带的口味也返回回来,我们这里就需要使用DTO实体类来完成

代码实现

我们将对原本的代码进行修改,利用DTO实体类来增加返回值:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Category;
import com.qiuluo.reggie.domain.Dish;
import com.qiuluo.reggie.domain.DishFlavor;
import com.qiuluo.reggie.dto.DishDto;
import com.qiuluo.reggie.service.impl.CategoryServiceImpl;
import com.qiuluo.reggie.service.impl.DishFlavorServiceImpl;
import com.qiuluo.reggie.service.impl.DishServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishServiceImpl dishService;

    @Autowired
    private DishFlavorServiceImpl dishFlavorService;

    @Autowired
    private CategoryServiceImpl categoryService;

    /**
     * 根据id查询菜品
     * @param dish
     * @return
     */
    @GetMapping("/list")
    public Result<List<DishDto>> list(Dish dish){

        // 提取CategoryID
        Long id = dish.getCategoryId();

        // 判断条件
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(id != null,Dish::getCategoryId,id);
        queryWrapper.eq(Dish::getStatus,1);
        queryWrapper.orderByAsc(Dish::getSort);

        List<Dish> list = dishService.list(queryWrapper);

        // 创建返回类型
        List<DishDto> dishDtoList = list.stream().map((item) -> {

            // 创建新的返回类型内部
            DishDto dishDto = new DishDto();

            // 将元素复制过去
            BeanUtils.copyProperties(item,dishDto);

            // 设置CategoryName
            Long categoryId = item.getCategoryId();

            LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
            categoryLambdaQueryWrapper.eq(Category::getId,categoryId);

            Category category = categoryService.getOne(categoryLambdaQueryWrapper);

            String categoryName = category.getName();

            dishDto.setCategoryName(categoryName);

            // 设置flavor
            Long dishId = item.getId();

            LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper();
            lambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);

            List<DishFlavor> dishFlavors = dishFlavorService.list(lambdaQueryWrapper);

            dishDto.setFlavors(dishFlavors);

            return dishDto;
        }).collect(Collectors.toList());

        return Result.success(dishDtoList);

    }
}

实际测试

我们点开主界面,可以查看到菜品分类界面以及相关菜品,部分菜品上使用选择规格即可

购物车

我们的功能开发通常分为三部分

需求分析

移动端用户将菜品或套餐添加到购物车中,菜品的不同口味也被判定为不同的购物车个体

如果是未加入购物车的菜品我们添加到购物车,如果是已添加购物车的菜品我们将数量叠加即可

首先我们需要将JavaScript代码修改过来:

// 该文件处于front/api/main.js下

//获取购物车内商品的集合
function cartListApi(data) {
    return $axios({
       	'url': '/shoppingCart/list',
        'method': 'get',
        params:{...data}
    })
}

这次我们要完成购物车的三种基本功能

第一次请求添加购物车:

img

第二次请求查看购物车信息:

img

第三次清除购物车:

img

然后我们查看相关数据表:

img

最后我们进行一些准备工作:

实体类ShoppingCart
数据层ShoppingCartMapper
业务层接口ShoppingCartService
业务层ShoppingCartServiceImpl
服务层ShoppingCartController

代码实现

首先实现添加购物车:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.CustomException;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.ShoppingCart;
import com.qiuluo.reggie.service.impl.ShoppingCartServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/shoppingCart")
public class ShoppingCartController {

    @Autowired
    private ShoppingCartServiceImpl shoppingCartService;


    /**
     * 添加菜品进购物车
     * @param shoppingCart
     * @return
     */
    @PostMapping("/add")
    public Result<ShoppingCart> add(@RequestBody ShoppingCart shoppingCart){
        // 1.设置用户
        Long currentId = BaseContext.getCurrentId();
        shoppingCart.setUserId(currentId);

        // 2. 判断是否是第一次加入,若第一次直接添加,若不是第一次number++

        // 2.2 给部分判断条件
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(ShoppingCart::getUserId,currentId);

        Long dishId = shoppingCart.getDishId();

        if(dishId != null){
            // 购物车为菜品
            queryWrapper.eq(ShoppingCart::getDishId,shoppingCart.getDishId());
        }else {
            // 购物车为套餐
            queryWrapper.eq(ShoppingCart::getSetmealId,shoppingCart.getSetmealId());
        }

        ShoppingCart cartServiceOne = shoppingCartService.getOne(queryWrapper);

        // 2.3判断是否是第一次加入
        if (cartServiceOne != null){
            // 不是第一次加入,直接number++
            Integer number = cartServiceOne.getNumber();
            cartServiceOne.setNumber(number + 1);
            shoppingCartService.updateById(cartServiceOne);
        } else {
            // 是第一次加入
            shoppingCartService.save(shoppingCart);
            cartServiceOne = shoppingCart;
        }

        return Result.success(cartServiceOne);
    }
}

然后是购物车回显:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.CustomException;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.ShoppingCart;
import com.qiuluo.reggie.service.impl.ShoppingCartServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/shoppingCart")
public class ShoppingCartController {

    @Autowired
    private ShoppingCartServiceImpl shoppingCartService;


    /**
     * 购物车回显
     * @return
     */
    @GetMapping("list")
    public Result<List<ShoppingCart>> list(){

        // 进行用户比对
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());

        // 查询并返回即可

        List<ShoppingCart> list = shoppingCartService.list(queryWrapper);

        return Result.success(list);

    }
}

最后是购物车清除操作:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.CustomException;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.ShoppingCart;
import com.qiuluo.reggie.service.impl.ShoppingCartServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/shoppingCart")
public class ShoppingCartController {

    @Autowired
    private ShoppingCartServiceImpl shoppingCartService;


    /**
     * 购物车清除
     * @return
     */
    @DeleteMapping("/clean")
    public Result<String> clean(){

        // 进行用户比对
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());

        // 删除即可
        shoppingCartService.remove(queryWrapper);

        return Result.success("清空成功");

    }
}

实际测试

购物车添加测试:

当我们点击第一次加入购物车的菜品,菜品加入购物车

当我们点击已经加入购物车的菜品,购物车中的菜品数量增加

购物车回显测试:

点击提交后,相关菜品回显在页面中

购物车清除测试:

点击清除键后,购物车信息消失

用户下单

我们的功能开发通常分为三部分

需求分析

移动端用户点击购物车的去结算功能后进入结算界面,这时其实页面已经调用了两条回显请求,但我们前面已经完成,这里不再介绍

然后我们点击去支付,相当于用户下单操作,我们这一小节就是完成这个功能

首先给出页面展示:

img

我们这时需要注意我们的数据添加不仅仅是订单表的数据添加,订单表与菜品的关联表也需要添加数据

我们给出两张相关表的展示

订单表:

img

订单菜品关联表:

img

因为数据设计两张表,所以我们自定义方法来实现

代码实现

我们从头开始进行代码实现:

  1. 准备工作
实体类Orders,OrderDetail
数据层OrdersMapper,OrderDetailMapper
业务层接口OrdersService,OrderDetailService
业务层OrdersServiceImpl,OrderDetailServiceImpl
服务层OrdersController,OrderDetailController
  1. 业务层接口实现
package com.qiuluo.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.qiuluo.reggie.domain.Orders;

public interface OrderService extends IService<Orders> {

    /**
     * 提交订单
     * @param orders
     */
    public void submit(Orders orders);
}
  1. 业务层逻辑实现
package com.qiuluo.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.CustomException;
import com.qiuluo.reggie.domain.*;
import com.qiuluo.reggie.mapper.OrderMapper;
import com.qiuluo.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private UserService userService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private OrderDetailService orderDetailService;

    /**
     * 提交订单
     * @param orders
     */
    public void submit(Orders orders){
        //获得当前用户id
        Long userId = BaseContext.getCurrentId();

        //查询当前用户的购物车数据
        LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShoppingCart::getUserId,userId);
        List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper);

        if(shoppingCarts == null || shoppingCarts.size() == 0){
            // 购物车无数据
            throw new CustomException("购物车为空,不能下单");
        }

        //查询用户数据
        User user = userService.getById(userId);

        //查询地址数据
        Long addressBookId = orders.getAddressBookId();
        AddressBook addressBook = addressBookService.getById(addressBookId);
        if(addressBook == null){
            // 下单地址错误
            throw new CustomException("用户地址信息有误,不能下单");
        }

        //订单号
        long orderId = IdWorker.getId();

        // 计算总金额(AtomicInteger原子int型,确保多线程内计算成功)
        AtomicInteger amount = new AtomicInteger(0);

        // 补全订单详情其他内容
        List<OrderDetail> orderDetails = shoppingCarts.stream().map((item) -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            orderDetail.setNumber(item.getNumber());
            orderDetail.setDishFlavor(item.getDishFlavor());
            orderDetail.setDishId(item.getDishId());
            orderDetail.setSetmealId(item.getSetmealId());
            orderDetail.setName(item.getName());
            orderDetail.setImage(item.getImage());
            orderDetail.setAmount(item.getAmount());
            amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());
            return orderDetail;
        }).collect(Collectors.toList());

        // 补全订单其他内容
        orders.setId(orderId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setStatus(2);
        orders.setAmount(new BigDecimal(amount.get()));//总金额
        orders.setUserId(userId);
        orders.setNumber(String.valueOf(orderId));
        orders.setUserName(user.getName());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
                + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
                + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
                + (addressBook.getDetail() == null ? "" : addressBook.getDetail()));

        //向订单表插入数据,一条数据
        this.save(orders);

        //向订单明细表插入数据,多条数据
        orderDetailService.saveBatch(orderDetails);

        //清空购物车数据
        shoppingCartService.remove(wrapper);

    }
}
  1. 服务层实现
package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.OrderDetail;
import com.qiuluo.reggie.domain.Orders;
import com.qiuluo.reggie.domain.ShoppingCart;
import com.qiuluo.reggie.domain.User;
import com.qiuluo.reggie.dto.OrdersDto;
import com.qiuluo.reggie.service.OrderService;
import com.qiuluo.reggie.service.impl.OrderDetailServiceImpl;
import com.qiuluo.reggie.service.impl.ShoppingCartServiceImpl;
import com.qiuluo.reggie.service.impl.UserServiceImpl;
import com.sun.org.apache.xpath.internal.operations.Or;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单
 */
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * 用户下单
     * @param orders
     * @return
     */
    @PostMapping("/submit")
    public Result<String> submit(@RequestBody Orders orders){
        log.info("订单数据:{}",orders);
        orderService.submit(orders);
        return Result.success("下单成功");
    }
}

实际测试

在界面提交订单后,在数据表可以看到相关信息即为功能开发成功

结束语

该篇内容到这里就结束了,希望能为你带来帮助~

标签:SpringBoot,addressBook,Day06,qiuluo,Result,外卖,reggie,import,com
From: https://www.cnblogs.com/RioTian/p/17110166.html

相关文章

  • 015_SpringBoot整合Druid
    导入Druid对应的starter  变更Druid的配置方式  整合任意第三方技术:导入对应的starter,根据提供的配置格式,配置非默认值对应的配置项......
  • springboot自定义banner
    网址:关于灰太狼的ascii艺术字,SpringBoot灰太狼Banner-bootschool.net在resources目录下创建banner.txt文件当文件出现 ......
  • day06
    数据类型强语言类型要求变量的使用要严格符合规定,所有变量必须先定义后才能使用弱语言类型与强语言类型相反数据类型分为:基本类型数值类型整数类型(byte......
  • 《自定义工作流配置,springboot集成activiti,前端vue,完整版审批单据》
    前言activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,一套完整并且实际运用在多套项目中的案例,满足日常业务流程审批需求。一、项目形式springboot......
  • pageOffice插件 springboot实现服务器上Word文档在线打开编辑保存
    pageOffice插件springboot实现服务器上Word文档在线打开编辑保存需求:在oa系统上,想实现在线,服务器上doc,docx文档,在web打开,编辑。编辑后,可以再同步保存到服务器端。开发......
  • 014_SpringBoot整合MyBatisPlus
    MyBatis-Plus与MyBatis区别:导入坐标不同;数据层实现简化。①:在pom.xml手动添加SpringBoot整合MyBatis-Plus的坐标,可以通过mvnrepository获取  ②:在dao层里......
  • SpringBoot + Disruptor实现高并发内存消息队列
    1.简介  Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。基于Disruptor开......
  • springboot开发日记(10)——web开发
    通过SpringInitializer进行项目创建文件->新建项目->选中SpringInitializer->勾选所需的插件和项目类型(本次勾选插件为:lombok、dev-tools、SpringConfigurationProcessor,......
  • SpringBoot启动流程
    SpringBoot项目都需要一个启动类。在启动类上标注@SpringBootApplication,在main方法中调用SpringApplication.run()方法,就可以启动项目:@SpringBootApplicationpublic......
  • springboot SpEL关于@ConditionalOnExpression注解,在使用spel表达式引用配置属性bean
    springboot关于@ConditionalOnExpression注解,在使用spel表达式引用配置属性bean导致提前初始化,无绑定数据的问题及相应的解决方法。SpringBoot版本<parent>......