瑞吉外賣實戰項目全攻略——功能補充篇

瑞吉外賣實戰項目全攻略——功能補充篇

該系列將記錄一份完整的實戰項目的完成過程,該篇屬於功能補充篇

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

該篇我們將完成課程中未完成的所有功能,包括以下功能:

  • 菜品單獨啟售停售和批量啟售停售(管理端)
  • 菜品批量刪除(管理端)
  • 套餐管理啟售停售(管理端)
  • 套餐管理修改(管理端)
  • 訂單明細展示(管理端)
  • 後台訂單狀態修改(管理端)
  • 套餐詳細展示(用戶端)
  • 購物車數量減少(用戶端)
  • 查看訂單(用戶端)
  • 再來一單(用戶端)
  • 地址功能補充(用戶端)
  • 退出賬戶(用戶端)

菜品單獨啟售停售和批量啟售停售(管理端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

修改菜品的售賣狀況

請求展示:

# 單個啟售
url://localhost:8080/dish/status/1?ids=1413384757047271425,1413385247889891330
Method:POST

# 單個停售
url://localhost:8080/dish/status/0?ids=1413384757047271425,1413385247889891330
Method:POST

# 批量啟售
url://localhost:8080/dish/status/1?ids=1413384757047271425,1413385247889891330
Method:POST

# 批量停售
url://localhost:8080/dish/status/0?ids=1413384757047271425,1413385247889891330
Method:POST

程式碼實現

程式碼展示:

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.dto.DishDto;
import com.qiuluo.reggie.service.impl.CategoryServiceImpl;
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.List;
import java.util.stream.Collectors;

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

    @Autowired
    private DishServiceImpl dishService;

     /**
     * 啟售,批量啟售
     * @param ids
     * @return
     */

    @PostMapping("/status/1")
    public Result<String> openStatus(Long[] ids) {

        for (Long id : ids
        ) {
            Dish dish = dishService.getById(id);
            dish.setStatus(1);
            dishService.updateById(dish);
        }

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

    
     /**
     * 停售,批量停售
     * @param ids
     * @return
     */
    @PostMapping("/status/0")
    public Result<String> closeStatus(Long[] ids) {

        for (Long id : ids
        ) {
            Dish dish = dishService.getById(id);
            dish.setStatus(0);
            dishService.updateById(dish);
        }

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

實際測試

返回菜品頁面,點擊若干菜品,進行三個方法的測試,實現即可

菜品批量刪除(管理端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

刪除菜品本身

請求展示:

# 批量刪除
url://localhost:8080/dish?ids=1583025958761824258
Method:DELETE

程式碼實現

程式碼展示:

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.dto.DishDto;
import com.qiuluo.reggie.service.impl.CategoryServiceImpl;
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.List;
import java.util.stream.Collectors;

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

    @Autowired
    private DishServiceImpl dishService;

    /**
     * 批量刪除
     * @param ids
     * @return
     */
    @DeleteMapping
    public Result<String> deleteByIds(Long[] ids){

        for (Long id:ids
             ) {
            dishService.removeById(id);
        }

        return Result.success("刪除成功");
    }
}

實際測試

回到菜品管理頁面,進行批量刪除,刪除成功即為功能開發成功

套餐管理啟售停售(管理端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

修改套餐的售賣狀況

請求展示:

// 單個停售
請求 URL: //localhost:8080/setmeal/status/0?ids=1415580119015145474
請求方法: POST

// 多個停售
請求 URL: //localhost:8080/setmeal/status/0?ids=1415580119015145474,1583260610277715970
請求方法: POST

// 單個啟售
請求 URL: //localhost:8080/setmeal/status/1?ids=1415580119015145474
請求方法: POST

// 多個啟售
請求 URL: //localhost:8080/setmeal/status/1?ids=1415580119015145474,1583260610277715970
請求方法: POST

程式碼實現

程式碼展示:

package com.qiuluo.reggie.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Category;
import com.qiuluo.reggie.domain.Setmeal;
import com.qiuluo.reggie.dto.DishDto;
import com.qiuluo.reggie.dto.SetmealDto;
import com.qiuluo.reggie.service.impl.CategoryServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealDishServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealServiceImpl;
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.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Autowired
    private SetmealServiceImpl setmealService;

    @Autowired
    private SetmealDishServiceImpl setmealDishService;

    @Autowired
    private CategoryServiceImpl categoryService;

    // 其實還可以整合成一個方法,url寫為/status,讀取後面的值設置為status,根據status對ids進行操作即可
    
    @PostMapping("/status/0")
    public Result<String> closeStatus(@RequestParam List<Long> ids){

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.in(Setmeal::getId,ids);

        List<Setmeal> setmeals = setmealService.list(queryWrapper);

        for (Setmeal setmeal:setmeals
        ) {
            setmeal.setStatus(0);
            setmealService.updateById(setmeal);
        }

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

    @PostMapping("/status/1")
    public Result<String> openStatus(@RequestParam List<Long> ids){

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.in(Setmeal::getId,ids);

        List<Setmeal> setmeals = setmealService.list(queryWrapper);

        for (Setmeal setmeal:setmeals
        ) {
            setmeal.setStatus(1);
            setmealService.updateById(setmeal);
        }

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

}

實際測試

回到套餐管理頁面,點擊啟售停售,操作成功即為功能開發成功

套餐管理修改(管理端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

該功能由兩部分組成,一方面需要根據id將該套餐的資訊回顯在頁面,一方面需要將修改後的套餐資訊保存起來

請求展示:

# 回顯操作
請求 URL: //localhost:8080/setmeal/1415580119015145474
請求方法: GET

# 修改操作
請求 URL: //localhost:8080/setmeal
請求方法: PUT

程式碼實現

回顯操作程式碼展示:

// 回顯操作

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Category;
import com.qiuluo.reggie.domain.Setmeal;
import com.qiuluo.reggie.domain.SetmealDish;
import com.qiuluo.reggie.dto.DishDto;
import com.qiuluo.reggie.dto.SetmealDto;
import com.qiuluo.reggie.service.impl.CategoryServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealDishServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealServiceImpl;
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.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Autowired
    private SetmealServiceImpl setmealService;

    @Autowired
    private SetmealDishServiceImpl setmealDishService;

    @Autowired
    private CategoryServiceImpl categoryService;

    /**
    * 回顯操作
    */
    @GetMapping("/{id}")
    public Result<SetmealDto> getById(@PathVariable Long id){

        // 我們需要把setmealDto返回回去,定義一個新的setmealDto用於保存數據
        SetmealDto setmealDto = new SetmealDto();

        // 將普通數據傳入

        Setmeal setmeal = setmealService.getById(id);

        BeanUtils.copyProperties(setmeal,setmealDto);

        // 將菜品資訊傳遞進去

        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,id);

        List<SetmealDish> list = setmealDishService.list(queryWrapper);

        setmealDto.setSetmealDishes(list);

        // 返回setmealDto即可
        return Result.success(setmealDto);
    }
}

修改操作程式碼展示:

// 1.修改操作——業務層介面定義

package com.qiuluo.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.qiuluo.reggie.domain.Setmeal;
import com.qiuluo.reggie.dto.SetmealDto;

import java.util.List;

public interface SetmealService extends IService<Setmeal> {

    /**
     * 修改操作
     * @param setmealDto
     */
    public void updateWithDish(SetmealDto setmealDto);

}
// 2.修改操作——業務層功能實現

package com.qiuluo.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiuluo.reggie.common.CustomException;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Setmeal;
import com.qiuluo.reggie.domain.SetmealDish;
import com.qiuluo.reggie.dto.SetmealDto;
import com.qiuluo.reggie.mapper.SetmealMapper;
import com.qiuluo.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

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

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper,Setmeal> implements SetmealService {

    @Autowired
    private SetmealDishServiceImpl setmealDishService;

    /**
     * 修改操作
     * @param setmealDto
     */
    public void updateWithDish(SetmealDto setmealDto){

        // 首先修改套餐上的資訊
        this.updateById(setmealDto);

        // 修改內部菜品操作(同樣先刪除再添加)

        // 刪除操作
        Long setmealId = setmealDto.getId();

        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,setmealId);

        setmealDishService.remove(queryWrapper);

        // 新填操作

        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();

        setmealDishService.saveBatch(setmealDishes);

    }

}
// 3.服務層程式碼實現

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Category;
import com.qiuluo.reggie.domain.Setmeal;
import com.qiuluo.reggie.domain.SetmealDish;
import com.qiuluo.reggie.dto.DishDto;
import com.qiuluo.reggie.dto.SetmealDto;
import com.qiuluo.reggie.service.impl.CategoryServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealDishServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealServiceImpl;
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.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Autowired
    private SetmealServiceImpl setmealService;

    @PutMapping
    public Result<String> update(@RequestBody SetmealDto setmealDto){

        setmealService.updateById(setmealDto);

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

    }
}

實際測試

我們需要注意兩處測試內容:

  • 點擊修改功能後,打開修改頁面,頁面出現相關資訊
  • 點擊修改完成功能後,頁面資訊內容成功修改即可

訂單明細展示(管理端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

返回類型大部分都是Orders的屬性,但含有特殊屬性UserName需要採用DTO實現

請求展示:

# 訂單展示
請求 URL: //localhost:8080/order/page?page=1&pageSize=10
請求方法: GET

程式碼實現

程式碼展示:

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;

    @Autowired
    private OrderDetailServiceImpl orderDetailService;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private ShoppingCartServiceImpl shoppingCartService;

    /**
     * 後台回顯
     * @param page
     * @param pageSize
     * @param number
     * @param beginTime
     * @param endTime
     * @return
     */
    @GetMapping("/page")
    public Result<Page> pagePC(int page, int pageSize, Long number, Date beginTime,Date endTime){

        // 訂製基本Page
        Page<Orders> pageInfo = new Page<>(page,pageSize);

        // 訂製帶有名字的特殊Orders
        Page<OrdersDto> ordersDtoPage = new Page<>();

        // 書寫限制條件
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(number != null,Orders::getId,number);
        if (beginTime != null && endTime != null){
            queryWrapper.between(Orders::getOrderTime,beginTime,endTime);
        }

        orderService.page(pageInfo, queryWrapper);

        // 普通賦值
        BeanUtils.copyProperties(pageInfo,ordersDtoPage,"records");

        // 訂單賦值
        List<Orders> records = pageInfo.getRecords();

        List<OrdersDto> ordersDtoList = records.stream().map((item) -> {

            // 新創內部元素
            OrdersDto ordersDto = new OrdersDto();

            // 普通值賦值
            BeanUtils.copyProperties(item,ordersDto);

            // 特殊值賦值
            Long userId = item.getUserId();

            User user = userService.getById(userId);

            ordersDto.setUserName(user.getName());

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

        // 完成dishDtoPage的results的內容封裝
        ordersDtoPage.setRecords(ordersDtoList);

        return Result.success(ordersDtoPage);
    }
}

實際測試

打開訂單介面,訂單數據全部展示即為功能開發成功

後台訂單狀態修改(管理端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

將訂單的狀態進行修改,訂單狀態分為未支付,未派送,已派送,已完成

請求展示:

# 訂單status狀態修改
請求 URL: //localhost:8080/order
請求方法: PUT

程式碼實現

程式碼展示:

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;

    @Autowired
    private OrderDetailServiceImpl orderDetailService;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private ShoppingCartServiceImpl shoppingCartService;

    /**
     * 狀態修改
     * @param orders
     * @return
     */
    @PutMapping
    public Result<String> beginSend(@RequestBody Orders orders){

        orderService.updateById(orders);

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

實際測試

點擊狀態修改對應的相關按鈕,訂單狀態發生改變即可

套餐詳細展示(用戶端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

點擊菜品圖片,展示菜品的詳細介紹

請求展示:

# 套餐詳細展示
請求 URL: //localhost:8080/setmeal/dish/1415580119015145474
請求方法: GET

程式碼實現

程式碼展示:

package com.qiuluo.reggie.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Category;
import com.qiuluo.reggie.domain.Dish;
import com.qiuluo.reggie.domain.Setmeal;
import com.qiuluo.reggie.domain.SetmealDish;
import com.qiuluo.reggie.dto.DishDto;
import com.qiuluo.reggie.dto.SetmealDto;
import com.qiuluo.reggie.service.impl.CategoryServiceImpl;
import com.qiuluo.reggie.service.impl.DishServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealDishServiceImpl;
import com.qiuluo.reggie.service.impl.SetmealServiceImpl;
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.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Autowired
    private DishServiceImpl dishService;

    @Autowired
    private SetmealServiceImpl setmealService;

    @Autowired
    private SetmealDishServiceImpl setmealDishService;

    @Autowired
    private CategoryServiceImpl categoryService;

    /**
     * 點擊套餐圖片查看套餐具體內容
     * 前端主要要展示的資訊是:套餐中菜品的基本資訊,圖片,菜品描述,以及菜品的份數
     * @param SetmealId
     * @return
     */
    @GetMapping("/dish/{id}")
    public Result<List<DishDto>> dish(@PathVariable("id") Long SetmealId) {
        
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, SetmealId);
        
        // 獲得數據
        List<SetmealDish> list = setmealDishService.list(queryWrapper);

        List<DishDto> dishDtos = list.stream().map((setmealDish) -> {
            DishDto dishDto = new DishDto();

            // 基本資訊拷貝
            BeanUtils.copyProperties(setmealDish, dishDto);
            
            // 設置其他資訊
            Long dishId = setmealDish.getDishId();
            Dish dish = dishService.getById(dishId);
            BeanUtils.copyProperties(dish, dishDto);

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

        return Result.success(dishDtos);
    }
}

實際測試

點擊移動端頁面中的套餐圖片,彈出套餐詳情彈框即可

購物車數量減少(用戶端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

點擊購物車的減號,購物車中菜品數量減少

請求展示:

# 減少數量
請求 URL: //localhost:8080/shoppingCart/sub
請求方法: POST

程式碼實現

程式碼展示:

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("/sub")
    public Result<ShoppingCart> sub(@RequestBody ShoppingCart shoppingCart){
        // 設置用戶
        Long currentId = BaseContext.getCurrentId();
        shoppingCart.setUserId(currentId);

        // 基本查找條件
        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());
        }

        // 判斷個數,如果為正數,減一;如果為0,拋出異常
        ShoppingCart shoppingCartServiceOne = shoppingCartService.getOne(queryWrapper);
        Integer number = shoppingCartServiceOne.getNumber();

        if (number != 0){
            shoppingCartServiceOne.setNumber(number - 1);
            shoppingCartService.updateById(shoppingCartServiceOne);
        }else {
            shoppingCartService.removeById(shoppingCartServiceOne);
        }

        return Result.success(shoppingCartServiceOne);
    }
}

實際測試

點擊購物車的減號,菜品數量減少即為功能開發成功

查看訂單(用戶端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

點開歷史訂單,可以查看到自己之前的訂單資訊

請求展示:

# 查看訂單(菜品)
請求 URL: //localhost:8080/order/userPage?page=1&pageSize=5
請求方法: GET

# 查看訂單(套餐)
請求 URL: //localhost:8080/order/userPage?page=2&pageSize=5
請求方法: GET

程式碼實現

程式碼展示:

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;

    @Autowired
    private OrderDetailServiceImpl orderDetailService;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private ShoppingCartServiceImpl shoppingCartService;

    /**
     * 查看手機版歷史紀錄
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping("/userPage")
    public Result<Page> pagePhone(int page,int pageSize){

        // 新創返回類型Page
        Page<Orders> pageInfo = new Page<>(page,pageSize);
        Page<OrdersDto> ordersDtoPage = new Page<>();

        // 用戶ID
        Long currentId = BaseContext.getCurrentId();

        // 原條件寫入
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getUserId,currentId);
        queryWrapper.orderByDesc(Orders::getOrderTime);

        orderService.page(pageInfo,queryWrapper);

        // 普通賦值
        BeanUtils.copyProperties(pageInfo,ordersDtoPage,"records");

        // 訂單賦值
        List<Orders> records = pageInfo.getRecords();

        List<OrdersDto> ordersDtoList = records.stream().map((item) -> {

            // 新創內部元素
            OrdersDto ordersDto = new OrdersDto();

            // 普通值賦值
            BeanUtils.copyProperties(item,ordersDto);

            // 菜單詳情賦值
            Long itemId = item.getId();

            LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId,itemId);

            int count = orderDetailService.count(orderDetailLambdaQueryWrapper);

            List<OrderDetail> orderDetailList = orderDetailService.list(orderDetailLambdaQueryWrapper);

            ordersDto.setSumNum(count);

            ordersDto.setOrderDetails(orderDetailList);

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

        // 完成dishDtoPage的results的內容封裝
        ordersDtoPage.setRecords(ordersDtoList);

        return Result.success(ordersDtoPage);
    }
}

實際測試

點開歷史訂單,關於自己的歷史訂單展現即可

再來一單(用戶端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

當訂單處於已完成的階段,手機端出現再來一單的按鈕,點擊後跳轉購物車並將該訂單的菜品加入購物車

請求展示:

# 再來一單
請求 URL: //localhost:8080/order/again
請求方法: POST

程式碼實現

我們需要對購物車進行一些簡單的操作,因而我們需要先構造一個簡單方法:

// 業務層實現(業務層介面這裡不再展示)

package com.qiuluo.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiuluo.reggie.common.BaseContext;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.ShoppingCart;
import com.qiuluo.reggie.mapper.ShoppingCartMapper;
import com.qiuluo.reggie.service.ShoppingCartService;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.DeleteMapping;

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

    public Result<String> clean(){

        // 進行用戶比對
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId, BaseContext.getCurrentId());

        // 刪除即可
        this.remove(queryWrapper);

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

    }
}

然後我們正式進入程式碼實現環節:

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;

    @Autowired
    private OrderDetailServiceImpl orderDetailService;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private ShoppingCartServiceImpl shoppingCartService;

    //客戶端點擊再來一單
    /**
     * 我們需要將訂單內的菜品重新加入購物車,所以在此之前我們需要將購物車清空(業務層實現方法)
     * 
     * 
     */
    @PostMapping("/again")
    public Result<String> againSubmit(@RequestBody Map<String,String> map){
        // 獲得ID
        String ids = map.get("id");

        long id = Long.parseLong(ids);

        // 製作判斷條件
        LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderDetail::getOrderId,id);
        
        //獲取該訂單對應的所有的訂單明細表
        List<OrderDetail> orderDetailList = orderDetailService.list(queryWrapper);

        //通過用戶id把原來的購物車給清空
        shoppingCartService.clean();

        //獲取用戶id
        Long userId = BaseContext.getCurrentId();
        
        // 整體賦值
        List<ShoppingCart> shoppingCartList = orderDetailList.stream().map((item) -> {
       		
            // 以下均為賦值操作
            
            ShoppingCart shoppingCart = new ShoppingCart();
            shoppingCart.setUserId(userId);
            shoppingCart.setImage(item.getImage());
            
            Long dishId = item.getDishId();
            Long setmealId = item.getSetmealId();
            
            if (dishId != null) {
                // 如果是菜品那就添加菜品的查詢條件
                shoppingCart.setDishId(dishId);
            } else {
                // 添加到購物車的是套餐
                shoppingCart.setSetmealId(setmealId);
            }
            shoppingCart.setName(item.getName());
            shoppingCart.setDishFlavor(item.getDishFlavor());
            shoppingCart.setNumber(item.getNumber());
            shoppingCart.setAmount(item.getAmount());
            shoppingCart.setCreateTime(LocalDateTime.now());
            return shoppingCart;
        }).collect(Collectors.toList());

        // 將攜帶數據的購物車批量插入購物車表
        shoppingCartService.saveBatch(shoppingCartList);

        return Result.success("操作成功");
    }
}

實際測試

點擊再來一單後,跳轉購物車頁面並且已經添加好相關菜品

地址功能補充(用戶端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

我們的地址功能還缺少修改和刪除操作

請求展示:

# 修改操作
請求 URL: //localhost:8080/addressBook
請求方法: PUT

# 刪除操作
請求 URL: //localhost:8080/addressBook?ids=1583794867236589570
請求方法: DELETE

程式碼實現

程式碼展示:

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

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

        addressBookService.removeById(ids);

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

    }
}

實際測試

分別進行修改和刪除操作,操作成功即為功能開發成功

退出賬戶(用戶端)

我們將程式碼開發分為三部分

需求分析

功能解釋:

點擊退出登錄,退出賬戶回到登陸頁面

請求展示:

# 退出賬戶
請求 URL: //localhost:8080/user/loginout
請求方法: POST

程式碼實現

程式碼展示:

package com.qiuluo.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.User;
import com.qiuluo.reggie.service.UserService;
import com.qiuluo.reggie.utils.SMSUtils;
import com.qiuluo.reggie.utils.ValidateCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.jws.soap.SOAPBinding;
import javax.servlet.http.HttpSession;
import java.util.Map;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/loginout")
    public Result<String> loginOut(HttpSession session){

        // 去除Session即可
        session.removeAttribute("user");

        return Result.success("退出成功");
    }
}

實際測試

在用戶頁面退出後,回到登陸頁面,查看Session資訊為空即為功能開發成功

結束語

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

附錄

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

這裡附上影片鏈接:業務開發Day1-01-本章內容介紹_嗶哩嗶哩_bilibili