瑞吉外卖实战项目全攻略——第六天

2022-10-25 17:47:31 浏览数 (1)

瑞吉外卖实战项目全攻略——第六天

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

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

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

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

用户地址簿相关功能

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

准备工作

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

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

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

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

代码语言:javascript复制
实体类AddressBook
数据层AddressBookMapper
业务层接口AddressBookService
业务层AddressBookServiceImpl
服务层AddressBookController

功能实现

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

查询指定用户的全部地址

功能用途:

查看该用户的所有地址

图片展示:

代码展示:

代码语言:javascript复制
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));
    }
}
新增用户地址

功能用途:

增加该用户的地址设置

图片展示:

代码展示:

代码语言:javascript复制
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);
    }
}
设置默认地址

功能用途:

设置用户的默认地址簿

图片展示:

代码展示:

代码语言:javascript复制
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);
    }
}
查看默认地址

功能用途:

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

图片展示:

代码展示:

代码语言:javascript复制
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);
        }
    }
}
查询特定地址

功能用途:

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

图片展示:

代码展示:

代码语言:javascript复制
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("没有找到该对象");
        }
    }
}
修改地址内容

功能用途:

修改特定地址的内容

图片展示:

代码展示:

代码语言:javascript复制
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("修改成功");
    }
}
删除地址内容

功能用途:

删除特定地址的内容

图片展示:

代码展示:

代码语言:javascript复制
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("修改成功");

    }
}

补充内容

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

菜品展示

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

需求分析

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

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

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

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

代码语言:javascript复制
// 该文件处于front/api/main.js下

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

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

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

我们查看第三个请求:

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

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

代码实现

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

代码语言:javascript复制
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代码修改过来:

代码语言:javascript复制
// 该文件处于front/api/main.js下

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

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

第一次请求添加购物车:

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

第三次清除购物车:

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

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

代码语言:javascript复制
实体类ShoppingCart
数据层ShoppingCartMapper
业务层接口ShoppingCartService
业务层ShoppingCartServiceImpl
服务层ShoppingCartController

代码实现

首先实现添加购物车:

代码语言:javascript复制
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);
    }
}

然后是购物车回显:

代码语言:javascript复制
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);

    }
}

最后是购物车清除操作:

代码语言:javascript复制
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("清空成功");

    }
}

实际测试

购物车添加测试:

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

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

购物车回显测试:

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

购物车清除测试:

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

用户下单

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

需求分析

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

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

首先给出页面展示:

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

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

订单表:

订单菜品关联表:

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

代码实现

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

  1. 准备工作
代码语言:javascript复制
实体类Orders,OrderDetail
数据层OrdersMapper,OrderDetailMapper
业务层接口OrdersService,OrderDetailService
业务层OrdersServiceImpl,OrderDetailServiceImpl
服务层OrdersController,OrderDetailController
  1. 业务层接口实现
代码语言:javascript复制
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. 业务层逻辑实现
代码语言:javascript复制
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. 服务层实现
代码语言:javascript复制
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("下单成功");
    }
}

实际测试

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

结束语

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

附录

该文章属于学习内容,具体参考B站黑马程序员的Java项目实战《瑞吉外卖》

这里附上视频链接:业务开发Day6-01-本章内容介绍_哔哩哔哩_bilibili

0 人点赞