瑞吉外賣實戰專案全攻略——第六天

2022-10-24 09:00:16

瑞吉外賣實戰專案全攻略——第六天

該系列將記錄一份完整的實戰專案的完成過程,該篇屬於第六天

案例來自B站黑馬程式設計師Java專案實戰《瑞吉外賣》,請結合課程資料閱讀以下內容

該篇我們將完成以下內容:

  • 使用者地址簿相關功能
  • 菜品展示
  • 購物車
  • 下單

使用者地址簿相關功能

視訊中將這部分程式碼直接給出,我們下面簡單進行解釋並給出程式碼

準備工作

首先我們需要知道使用者地址簿的基本規則:

  • 地址簿用於記錄使用者的地址資訊
  • 使用者登入之後才可以操作自己的地址簿資訊
  • 同一個使用者可以擁有多個地址簿,但只能擁有一個預設地址

然後我們檢視所使用的資料表:

最後我們需要建立一些簡單的Java程式碼:

實體類AddressBook
資料層AddressBookMapper
業務層介面AddressBookService
業務層AddressBookServiceImpl
服務層AddressBookController

功能實現

下面我們會進行簡單說明並給出程式碼展示,包含有地址簿的所有方法

查詢指定使用者的全部地址

功能用途:

檢視該使用者的所有地址

圖片展示:

程式碼展示:

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));
    }
}

新增使用者地址

功能用途:

增加該使用者的地址設定

圖片展示:

程式碼展示:

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);
    }
}

設定預設地址

功能用途:

設定使用者的預設地址簿

圖片展示:

程式碼展示:

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);
    }
}

檢視預設地址

功能用途:

購物車進行訂單提交時直接展示預設地址並提交

圖片展示:

程式碼展示:

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);
        }
    }
}

查詢特定地址

功能用途:

修改地址內容時將該地址回顯

圖片展示:

程式碼展示:

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("沒有找到該物件");
        }
    }
}

修改地址內容

功能用途:

修改特定地址的內容

圖片展示:

程式碼展示:

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("修改成功");
    }
}

刪除地址內容

功能用途:

刪除特定地址的內容

圖片展示:

程式碼展示:

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("修改成功");

    }
}

補充內容

上述我們講解了資料給出的使用者簿全部功能並且補充了兩個使用者簿未實現的方法,想練手的小朋友可以動手嘗試一下~

菜品展示

我們的功能開發通常分為三部分

需求分析

我們開啟菜品展示頁面會發現主頁傳送了兩個請求

第一個請求是關於分類的請求:

第二個請求是關於購物車的請求:

我們的前端設定只有當兩個均可實現時,頁面才會展示,所以我們暫時將購物車請求更換一下:

// 該檔案處於front/api/main.js下

//獲取購物車內商品的集合
function cartListApi(data) {
    return $axios({
       	// 原有程式碼:'url': '/shoppingCart/list',我們修改為下述程式碼,該程式碼指向一個預設購物車,注意需要在資料中匯入該檔案
        'url': '/front/cartData.json',
        'method': 'get',
        params:{...data}
    })
}

那麼我們的介面只需要處理第一個關於分類的請求即可,我們注意請求路徑就可以發現這個請求我們之前已經完成了

我們第一個處理點就已經完成了

我們檢視第三個請求:

然後我們需要注意在菜品的選擇中,如果菜品有口味,就要顯示選擇規格,如果沒有口味,就直接是一個加號

所以我們在檢視該分類的菜品的程式碼中需要將該菜品攜帶的口味也返回回來,我們這裡就需要使用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}
    })
}

這次我們要完成購物車的三種基本功能

第一次請求新增購物車:

第二次請求檢視購物車資訊:

第三次清除購物車:

然後我們檢視相關資料表:

最後我們進行一些準備工作:

實體類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("清空成功");

    }
}

實際測試

購物車新增測試:

當我們點選第一次加入購物車的菜品,菜品加入購物車

當我們點選已經加入購物車的菜品,購物車中的菜品數量增加

購物車回顯測試:

點選提交後,相關菜品回顯在頁面中

購物車清除測試:

點選清除鍵後,購物車資訊消失

使用者下單

我們的功能開發通常分為三部分

需求分析

行動端使用者點選購物車的去結算功能後進入結算介面,這時其實頁面已經呼叫了兩條回顯請求,但我們前面已經完成,這裡不再介紹

然後我們點選去支付,相當於使用者下單操作,我們這一小節就是完成這個功能

首先給出頁面展示:

我們這時需要注意我們的資料新增不僅僅是訂單表的資料新增,訂單表與菜品的關聯表也需要新增資料

我們給出兩張相關表的展示

訂單表:

訂單菜品關聯表:

因為資料設計兩張表,所以我們自定義方法來實現

程式碼實現

我們從頭開始進行程式碼實現:

  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("下單成功");
    }
}

實際測試

在介面提交訂單後,在資料表可以看到相關資訊即為功能開發成功

結束語

該篇內容到這裡就結束了,希望能為你帶來幫助~

附錄

該文章屬於學習內容,具體參考B站黑馬程式設計師的Java專案實戰《瑞吉外賣》

這裡附上視訊連結:業務開發Day6-01-本章內容介紹_嗶哩嗶哩_bilibili