springboot项目外卖管理 day07-功能补充

news2024/11/27 14:48:39

文章目录

  • 前端补充功能
    • 1、历史订单功能
      • 1.1、梳理过程
      • 1.2历史订单展示
      • 1.3、效果展示
    • 2、修改/删除地址
      • 2.1、回显数据
          • 梳理过程
        • 代码展示
      • 2.2、修改地址
        • 梳理过程
        • 代码
      • 2.3、删除地址
        • 梳理过程
        • 代码展示
    • 3、再来一单功能
      • 3.1、梳理过程
      • 3.2、具体实现思路(参考一下当初我们怎么添加购物车的)
    • 4、购物车菜品减少按钮
  • 后端补充功能
    • 1、菜品启售/停售
    • 2、菜品批量启售/停售
    • 3、菜品批量删除
    • 4、套餐修改
      • 4.1、数据回显
      • 4.2、套餐修改


前端补充功能

1、历史订单功能

1.1、梳理过程

当我们访问个人中心/历史订单的时候,都会发送请求

请求网址: http://localhost/order/userPage?page=1&pageSize=1
请求方法: GET

看样子是个分页的请求,我们之前把订单数据存进了order表中,那么该功能,大概率就是从表中查出数据然后返回给前端

那么具体要那些数据呢根据平时点外卖经验肯定是有具体的菜品、数量、价格,那么光靠一个order表是无法满足要求的,于是引入orderDao

特别注意
为什么要加入sumNum 因为该项目前端展示金额前端帮我们算好,但是我们不能相信前端数据,我们需要再后台计算一遍才好

@Data
public class OrdersDto extends Orders {

    private int sumNum;
   

    private List<OrderDetail> orderDetails;
    
}

1.2历史订单展示

大概流程就是先根据当前登录的用户id查询订单数据,再循环订单数据来查询每一单中具体的详细信息,然后计算金额,
然后将循环的order数据复制到ordersDto中,然后设置orderDto中的OrderDetails属性便可

 //查询历史订单
    @GetMapping("/userPage")
    public R<Page> page(int page, int pageSize) {
        //获取当前id
        Long userId = BaseContext.getCurrentId();
        Page<Orders> pageInfo = new Page<>(page, pageSize);
        Page<OrdersDto> ordersDtoPage = new Page<>(page, pageSize);
        //条件构造器
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        //查询当前用户id订单数据
        queryWrapper.eq(userId != null, Orders::getUserId, userId);
        //按时间降序排序
        queryWrapper.orderByDesc(Orders::getOrderTime);
        orderService.page(pageInfo, queryWrapper);

        List<OrdersDto> list = pageInfo.getRecords().stream().map((item) -> {
            OrdersDto ordersDto = new OrdersDto();
            //获取orderId,然后根据这个id,去orderDetail表中查数据
            Long orderId = item.getId();
            LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OrderDetail::getOrderId, orderId);
            List<OrderDetail> details = orderDetailService.list(wrapper);
            //后端需要自己进行计算金额
//            int j=0;
//            for(int i=0;i<details.size();i++)
//            {
//                int a=details.get(i).getAmount().intValue();
//                j=j+details.get(i).getAmount().intValue()*details.get(i).getNumber();
//            }
//            ordersDto.setSumNum(j);

            BeanUtils.copyProperties(item, ordersDto);
            //之后set一下属性
            ordersDto.setOrderDetails(details);
            return ordersDto;
        }).collect(Collectors.toList());
        BeanUtils.copyProperties(pageInfo, ordersDtoPage, "records");
        ordersDtoPage.setRecords(list);
        //日志输出看一下
        log.info("list:{}", list.get(0));
        return R.success(ordersDtoPage);
    }

1.3、效果展示

在这里插入图片描述

2、修改/删除地址

2.1、回显数据

梳理过程

点击地址选项卡的铅笔图案,跳转到修改地址页面,发送请求
在这里插入图片描述
观察前端传的参数
请求网址: http://localhost/addressBook/1579828298672885762
请求方法: GET
这是一个restful风格传的参数,大概可以判断是传给后端一个id,然后结合前端判断是需要返回该id对应的地址

代码展示

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

2.2、修改地址

梳理过程

点击上图中的保存地址按钮,查看发送的请求

请求网址: http://localhost/addressBook
请求方法: PUT

根据功能需求需要修改地址,可知后端需要用一个实体类接收数据

代码

 @PutMapping
    public R<String> updateaddress(@RequestBody AddressBook addressBook)
    {
        if (addressBook == null) {
        throw new CustomException("地址信息不存在,请刷新重试");
    }
        addressBookService.updateById(addressBook);
        return R.success("修改成功");
    }

2.3、删除地址

梳理过程

点击上图中的删除地址按钮,查看发送的请求

请求网址: http://localhost/addressBook?ids=1579828298672885762
请求方法: DELETE

根据请求地址可知是根据id删除地址并且这不是restful风格,所以直接用一个Long类型参数接受便可

代码展示

@DeleteMapping()
    public R<String> deleteAdd(@RequestParam("ids") Long id) {
        if (id == null) {
            throw new CustomException("地址信息不存在,请刷新重试");
        }
        AddressBook addressBook = addressBookService.getById(id);
        if (addressBook == null) {
            throw new CustomException("地址信息不存在,请刷新重试");
        }
        addressBookService.removeById(id);
        return R.success("地址删除成功");
    }

3、再来一单功能

3.1、梳理过程

这个功能其实比较隐晦,因为当订单状态为已完成时才会出现这个按钮(修改orders表中的status字段为4)。

查看请求的地址
请求网址: http://localhost/order/again
请求方法: POST

请求路径为/order/again,请求方式为POST,数据只携带了一个json格式的id数据,根据常识,这个id只能是orders表中的订单id,即order_id

{id: "1580121916188971009"}

这里其实有很多种想法,我想的是和平时外卖一样点击再来一单会跳转至购物车页面,然后之前选择的菜品会再次显示

3.2、具体实现思路(参考一下当初我们怎么添加购物车的)

之前是我们手动选择数据(菜品/套餐)添加到购物车,现在相当于我们手里有个发票,想办法看看上一单都买了啥,然后复刻一遍
分析完毕之后,我们来OrderController编写对应的方法

@PostMapping("/again")
public Result<String> again(@RequestBody Map<String,String> map){
    //获取order_id
    Long orderId = Long.valueOf(map.get("id"));
    //条件构造器
    LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
    //查询订单的口味细节数据
    queryWrapper.eq(OrderDetail::getOrderId,orderId);
    List<OrderDetail> details = orderDetailService.list(queryWrapper);
    //获取用户id,待会需要set操作
    Long userId = BaseContext.getCurrentId();
    List<ShoppingCart> shoppingCarts = details.stream().map((item) ->{
        ShoppingCart shoppingCart = new ShoppingCart();
        //Copy对应属性值
        BeanUtils.copyProperties(item,shoppingCart);
        //设置一下userId
        shoppingCart.setUserId(userId);
        //设置一下创建时间为当前时间
        shoppingCart.setCreateTime(LocalDateTime.now());
        return shoppingCart;
    }).collect(Collectors.toList());
    //加入购物车
    shoppingCartService.saveBatch(shoppingCarts);
    return Result.success("喜欢吃就再来一单吖~");
}

这里我就直接用了BeanUtils.copyProperties直接复制了,然后在set两个属性,好像就可以了,不过我看数据库的时候,备注没有copy过来,地址是选择当前默认地址(如果你改了默认地址,那么不是之前的地址,好像也挺合理的)

4、购物车菜品减少按钮

思路分析
根据这前端传过来的id,来对不同的菜品/套餐的number属性修改(对应的数量-1),如果number等于0,则删除

  @PostMapping("/sub")
    public R<String> sub(@RequestBody ShoppingCart shoppingCart)
    {
        if(shoppingCart.getDishId()!=null)
        {
            LambdaQueryWrapper<ShoppingCart> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ShoppingCart::getDishId,shoppingCart.getDishId());
            ShoppingCart shoppingCart1=shoppingCartService.getOne(lambdaQueryWrapper);
            if(shoppingCart1.getNumber()>1)
            {
                shoppingCart1.setNumber(shoppingCart1.getNumber()-1);
                shoppingCartService.updateById(shoppingCart1);
            }
            else
            {
                shoppingCartService.remove(lambdaQueryWrapper);
            }


        }
        else
        {
            LambdaQueryWrapper<ShoppingCart> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ShoppingCart::getSetmealId,shoppingCart.getSetmealId());
            ShoppingCart shoppingCart1=shoppingCartService.getOne(lambdaQueryWrapper);
            if(shoppingCart1.getNumber()>1)
            {
                shoppingCart1.setNumber(shoppingCart1.getNumber()-1);
                shoppingCartService.updateById(shoppingCart1);
            }
            else
            {
                shoppingCartService.remove(lambdaQueryWrapper);
            }

        }
        return R.success("成功");
    }

后端补充功能

1、菜品启售/停售

@PostMapping("/status/{status}")
public R<String> status(@PathVariable Integer status, Long ids) {
    log.info("status:{},ids:{}", status, ids);
    Dish dish = dishService.getById(ids);
    if (dish != null) {
        //直接用它传进来的这个status改就行
        dish.setStatus(status);
        dishService.updateById(dish);
        return R.success("售卖状态修改成功");
    }
    return Result.error("系统繁忙,请稍后再试");
}

2、菜品批量启售/停售

@PostMapping("/status/{status}")
public R<String> status(@PathVariable Integer status, @RequestParam List<Long> ids) {
    log.info("status:{},ids:{}", status, ids);
    LambdaUpdateWrapper<Dish> updateWrapper = new LambdaUpdateWrapper<>();
    updateWrapper.in(ids != null, Dish::getId, ids);
    updateWrapper.set(Dish::getStatus, status);
    dishService.update(updateWrapper);
    return R.success("批量操作成功");
}

3、菜品批量删除

  @DeleteMapping()
    public R<String> delete(@RequestParam List<Long> ids)
    {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.in(Dish::getId,ids);
        queryWrapper.eq(Dish::getStatus,1);

        Integer count=dishService.count(queryWrapper);
        System.out.println(count);
        if(count > 0){
            //如果不能删除,抛出一个业务异常
            throw new CustomException("套餐正在售卖中,不能删除");
        }
        for(int i=0;i<ids.size();i++)
        {
            dishService.removeById(ids.get(i));
        }

        return R.success("删除成功");
    }

4、套餐修改

4.1、数据回显

点击修改按钮,查看发送的请求
请求网址: http://localhost/setmeal/1580361496716759041
请求方法: GET

这个请求大概率是用于处理数据回显的,请求路径/setmeal/{setmealId},请求方式GET
普通的Setmeal实体类肯定是不够用的,还是要用到SetmealDto
那么我们直接来SetmealController中编写对应的方法

@GetMapping("/{id}")
public R<SetmealDto> getById(@PathVariable Long id) {
    Setmeal setmeal = setmealService.getById(id);
    SetmealDto setmealDto = new SetmealDto();
    //拷贝数据
    BeanUtils.copyProperties(setmeal, setmealDto);
    //条件构造器
    LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
    //根据setmealId查询具体的setmealDish
    queryWrapper.eq(SetmealDish::getSetmealId, id);
    List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper);
    //然后再设置属性
    setmealDto.setSetmealDishes(setmealDishes);
    //作为结果返回
    return R.success(setmealDto);
}

4.2、套餐修改

点击保存按钮,查看发送的请求
请求网址: http://localhost/setmeal
请求方法: PUT

@PutMapping
    public R<Setmeal> updateWithDish(@RequestBody SetmealDto setmealDto) {
    List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
    Long setmealId = setmealDto.getId();
    //先根据id把setmealDish表中对应套餐的数据删了
    LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SetmealDish::getSetmealId,setmealId);
    setmealDishService.remove(queryWrapper);
    //然后在重新添加
    setmealDishes = setmealDishes.stream().map((item) ->{
        //这属性没有,需要我们手动设置一下
        item.setSetmealId(setmealId);
        return item;
    }).collect(Collectors.toList());
    //更新套餐数据
    setmealService.updateById(setmealDto);
    //更新套餐对应菜品数据
    setmealDishService.saveBatch(setmealDishes);
    return R.success(setmealDto);
}

还有一些简单的功能就不赘述了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/646981.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux操作系统——第四章 进程间通信

目录 进程间通信介绍 进程间通信目的 进程间通信发展 进程间通信分类 管道 System V IPC POSIX IPC 管道 什么是管道 匿名管道 管道读写规则 管道特点 命名管道 创建一个命名管道 匿名管道与命名管道的区别 命名管道的打开规则 system V共享内存 共享内存示意…

【SpringBoot】解决依赖版本不一致报错问题

哈喽大家好&#xff0c;我是阿Q。今天在开发代码的过程中&#xff0c;由于手抖&#xff0c;不知道引入了什么包依赖&#xff0c;导致项目启动一直报错&#xff0c;特写本文来记录下解决问题的经过。 文章目录 问题描述报错信息如下报错描述 解决方法总结 问题描述 报错信息如下…

vite中使用 vite- aliases 插件报错

vite 中使用 vite-aliases 插件报错 vite-aliases 介绍报错内容解决方法 vite-aliases 介绍 vite-aliases 可以帮助我们自动生成别名: 检测你当前目录下包括 src 在内的所有文件夹, 并帮助我们去生成别名。 下载 npm i vite-aliases -D 使用 import { defineConfig } from vi…

VALSE 2023 无锡线下参会个人总结 6月11日-2

VALSE2023无锡线下参会个人总结 6月11日-2 6月11日会议日程安排Workshop&#xff1a;目标检测与分割程明明&#xff1a;粒度自适应的图像感知技术张兆翔&#xff1a;基于多传感器融合的视觉物体检测与分割 Workshop&#xff1a;ChatGPT与计算机视觉白翔&#xff1a;再谈ChatGPT…

290. 单词规律

290. 单词规律 C代码&#xff1a;别人手搓的 bool wordPattern(char * pattern, char * s){char arr[301][3001];char *p strtok(s, " ");int pos 0;while(p ! NULL) {sprintf(arr[pos], "%s", p);p strtok(NULL, " ");}int len strlen(pat…

Linux环境安装Jdk图文步骤

准备工作&#xff1a; a、jdk安装包&#xff1a;百度网盘 请输入提取码&#xff0c;提取码&#xff1a;jdk8 b、远程工具&#xff0c;xshell&#xff0c;&#xff0c;electerm&#xff0c;&#xff0c;MobaXterm&#xff0c;&#xff0c;fxp&#xff0c;docker&#xff0c;宝…

软件测试V、W和H模型的优缺点汇总,零基础必看哦

目录 V模型 W模型 H模型 总结&#xff1a; 软件测试有三种模型&#xff0c;分别是V模型&#xff0c;W模型和H模型。每种模型都有自己的优点和缺点。 V模型 V模型如下图所示&#xff1a; V模型的优点 V模型明确地标识出了在开发过程中一般应完成的测试级别&#xff0c;以及…

STM32-HAL库串口DMA空闲中断的正确使用方式+解析SBUS信号

STM32-HAL库串口DMA空闲中断的正确使用方式解析SBUS信号 一. 问题描述二. 方法一——使用HAL_UART_Receive_DMA三. 方法二——使用HAL_UARTEx_ReceiveToIdle_DMA四. 方法三——使用HAL_UARTEx_ReceiveToIdle_IT&#xff08;不使用DMA&#xff09;五. 总结 一. 问题描述 能够点…

java springboot整合MyBatis-Plus 多用点Plus支持一下国人开发的东西吧

文章java springboot整合MyBatis做数据库查询操作讲述了boot项目整合MyBatis的操作方法 但现在就还有一个 MyBatis-Plus Plus是国内整合的一个技术 国内的很多人会喜欢用 特别是一些中小型公司 他们用着会比较舒服 好 然后我们打开idea 创建一个项目 选择 Spring Initializr…

(九)CSharp-数组

一、矩形数组 1、访问数组元素 class Program{static void Main(string[] args){int[] intArr1 new int[15];intArr1[2] 10;int var1 intArr1[2];int[,] intArr2 new int[5, 10];intArr2[2, 3] 7;int var2 intArr2[2, 3];int[] myIntArray new int[4];for (int i 0; i…

Git 报错 Updates were rejected because the remote contains work that you do

目录 Git 报错 Updates were rejected because the remote contains work that you do 1、命令行出现这种情况 2、idea出现同样的报错&#xff0c;解决方式同上 Git 报错 Updates were rejected because the remote contains work that you do 这个报错实在是让我受不了了&…

Kendo UI for jQuery---03.组件___网格---05.编辑---01.概述

编辑概述 编辑是剑道 UI 网格的一项基本功能&#xff0c;它允许您操作其数据的呈现方式。 网格提供以下编辑模式&#xff1a; 批量编辑 内联编辑 弹出窗口编辑 自定义编辑开始 要启用编辑&#xff1a; 熟悉剑道UI中的常见编辑概念 配置网格的数据源 通过配置定义字段schem…

PaddleOCR Windows下配置环境并测试

目录 1.PaddleOCR 介绍 1.2 PaddleOCR支持模型介绍 2.环境配置 3.PaddleOCR源码 1.PaddleOCR 介绍 PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库&#xff0c;助力开发者训练出更好的模型&#xff0c;并应用落地。 支持多种OCR相关前沿算法&#xff0c;在此基础上打…

简单的一批的DockerFile构建(内附超详细docker学习笔记)

目录 介绍 DockerFile常用保留字指令 演示自定义构建java8版本centos docker专用学习笔记 超全 介绍 总结: 从应用软件的角度来看&#xff0c;Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段&#xff0c; * Dockerfile是软件的原材料 * Docker镜像是软件…

SpringBoot参数校验入门

一、添加依赖 <!--参数校验--> <dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId> </dependency> <!--lombok--> <dependency><groupId>org.projectlombok&…

few-shot object counting论文汇总

文章目录 2021OBJECT COUNTING: YOU ONLY NEED TO LOOK AT ONE 2022CounTR: Transformer-based Generalised Visual CountingFew-shot Object Counting with Similarity-Aware Feature Enhancement 2023CAN SAM COUNT ANYTHING? AN EMPIRICAL STUDY ON SAM COUNTING 2021 OBJ…

【MSP432电机驱动学习】TB6612带稳压电机驱动模块、MG310电机、13线霍尔编码器

所用控制板型号&#xff1a;MSP432P401r 今日终于得以继续我的电赛小车速通之路&#xff1a; 苏轼云 “ 素面常嫌粉涴 &#xff0c; 洗妆不褪朱红。 ” 这告诫我们不能只注重在表面粉饰虚伪的自己&#xff0c;要像梅花一样&#xff0c;不断磨砺自己的内在~ 后半句是 “…

广告经济学与垄断竞争分析

产品与广告 产品的分类&#xff1a; 搜寻品&#xff1a;消费者在购买商品之前就可以知道其特征的产品经验品&#xff1a;只能够在使用后才能确认其特征的产品信任品&#xff1a;产品的质量即使在消费之后仍然不能确定&#xff0c;例如医学和法律服务 广告的分类&#xff1a;…

【C++】在线编译器推荐,让你随时随地编写代码

▒ 目录 ▒ &#x1f6eb; 问题描述环境 1️⃣ 支持调试网站Repl.itOnlineGDB 2️⃣ 不支持调试网站Wandboxjson.cnjdoodletutorialspointcppshellideonecoliruonline-ide 3️⃣ 性能分析网站Quick C BenchmarkCompare C Builds 4️⃣ 其它C Insights&#xff08;学习模板、C11…

Java阶段四Day04

Java阶段四Day04 文章目录 Java阶段四Day04关于SLF4j日志框架使用Sql注解关于DAO架构关于Service关于异常 关于SLF4j日志框架 在开发实践中&#xff0c;通常禁止使用System.out.println()这种语句输出信息&#xff0c;主要原因有&#xff1a; 输出效率低下&#xff0c;特别是字…