瑞吉外卖剩余功能实现(八)

简介: 1.菜品的停售合起售在dishController中编写该方法2.菜品的批量起售和停售在dishController中编写该方法

1.菜品的停售合起售

在dishController中编写该方法

   //对菜品进行停售或者起售
    @PostMapping("/status/{status}")
    public R<String> status(@PathVariable("status")Integer status,Long ids){
        log.info("status:{}",status);
        log.info("ids:{}",ids);
        Dish dish=dishService.getById(ids);
        if (dish!=null){
            dish.setStatus(status);
            dishService.updateById(dish);
            return R.success("开始起售");
        }
    return R.error("售卖状态设置异常");
    }

2.菜品的批量起售和停售

在dishController中编写该方法

    //对菜品批量进行停售或者起售
    @PostMapping("/status/{status}")
    public R<String> status(@PathVariable("status")Integer status,@RequestParam List<Long> ids) {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ids != null, Dish::getId, ids);
        //根据数据进行批量查询
        List<Dish> list = dishService.list(queryWrapper);
       for (Dish dish:list){
           if (dish!=null){
               dish.setStatus(status);
               dishService.updateById(dish);
           }
       }
return R.success("售卖状态修改成功");
    }

3.菜品的批量删除

在dishservice中声明方法

   //根据传过来的id批量或者单个的删除菜品
    void deleteByIds(List<Long> ids);

在dishserviceImpl中实现这个方法

 @Override
    @Transactional
    public void deleteByIds(List<Long> ids) {
//构造条件查询器
        LambdaQueryWrapper<Dish> queryWrapper=new LambdaQueryWrapper<>();
        //先查询该菜品是否在售卖,如果是则抛出异常
        queryWrapper.in(ids!=null,Dish::getId,ids);
        List<Dish> list=this.list(queryWrapper);
        for (Dish dish:list){
            Integer ststus=dish.getStatus();
            //如果不是在售卖,则可以删除
            if (ststus==0){
                this.removeById(dish.getId());
            }else {
                //此时应该回滚,因为前面的已经删除了,但后面的继续在售卖
                throw new CustomException("删除菜品中有正在售卖菜品,无法全部删除");
            }
        }
    }

在dishcontroller调用该方法

@DeleteMapping
    public R<String> delete(@RequestParam("ids")List<Long> ids){
        //根据菜品id在setmeal——dish表中查询那些套餐包含该菜品
    LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper=new LambdaQueryWrapper<>();
    setmealDishLambdaQueryWrapper.in(SetmealDish::getDishId,ids);
    List<SetmealDish> setmealDishList = setmealDishService.list(setmealDishLambdaQueryWrapper);
    //如果菜品没有关联套餐,直接删除
    if (setmealDishList.size()==0){
        //这个deleteByids已经做了菜品起售不能删除的判断
        dishService.deleteByIds(ids);
        LambdaQueryWrapper<DishFlavor> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.in(DishFlavor::getDishId,ids);
        dishFlavorService.remove(queryWrapper);
        return R.success("菜品删除成功");
    }
    //如果菜品有关联套餐,并且套餐正在售卖不能删除
   //得到与删除菜品关联的套餐id
    ArrayList<Long> Setmeal_idList=new ArrayList<>();
    for (SetmealDish setmealDish:setmealDishList){
        Long setmealId=setmealDish.getSetmealId();
       Setmeal_idList.add(setmealId);
    }
    //查询出与删除菜品相关的套餐
    LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper=new LambdaQueryWrapper<>();
    setmealLambdaQueryWrapper.in(Setmeal::getId,Setmeal_idList);
    List<Setmeal> setmealList=setmealService.list(setmealLambdaQueryWrapper);
    //对拿到的所有套餐进行遍历,然后拿到售卖状态
    for (Setmeal setmeal:setmealList){
        Integer status=setmeal.getStatus();
        if (status==1){
            return R.error("删除的菜品中有关联在售套餐,删除失败");
        }
    }
//要删除的菜品关联的套餐没有在售,可以删除
    //这下面的代码并不一定会执行,因为如果前面的for循环出现status==1,那么下面代码被执行
    dishService.deleteByIds(ids);
    LambdaQueryWrapper<DishFlavor> queryWrapper=new LambdaQueryWrapper<>();
    queryWrapper.in(DishFlavor::getDishId,ids);
    dishFlavorService.remove(queryWrapper);
    return R.success("菜品删除成功");
    }

4.套餐的批量启售和停售

在setmealservice中声明updateSetmealStatusById方法

//根据套餐id修改售卖状态
    void updateSetmealStatusById(Integer status,List<Long> ids);

在setmealserviceImpl中实现updateSetmealStatusById方法

//根据套餐id修改售卖状态
    @Override
    public void updateSetmealStatusById(Integer status, List<Long> ids) {
        LambdaQueryWrapper<Setmeal> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.in(ids!=null,Setmeal::getId,ids);
        List<Setmeal> list=this.list(queryWrapper);
        for (Setmeal setmeal:list){
            if (setmeal!=null){
                setmeal.setStatus(status);
                this.updateById(setmeal);
            }
        }
    }

在setmealcontroller中调用updateSetmealStatusById方法

//对菜品批量或者单个 进行停售和起售
    @PostMapping("/status/{status}")
    public R<String> status(@PathVariable("status")Integer status,@RequestParam List<Long> ids){
        setmealService.updateSetmealStatusById(status,ids);
        return R.success("售卖状态修改成功");

5.套餐管理的修改

在setmealService中编写getDate回显数据的方法

   //回显套餐数据,根据套餐id查询套餐
    SetmealDto getDate(Long id);

在setmealServiceImpl中实现getdate方法

  //回显套餐数据,根据套餐id查询套餐
    @Override
    public SetmealDto getDate(Long id) {
     Setmeal setmeal=this.getById(id);
     SetmealDto setmealDto=new SetmealDto();
     LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
     //在关联表中查询,setmealdish
        queryWrapper.eq(id!=null,SetmealDish::getSetmealId,id);
        if (setmeal!=null){
            BeanUtils.copyProperties(setmeal,setmealDto);
            List<SetmealDish> list=setmealDishService.list(queryWrapper);
            setmealDto.setSetmealDishes(list);
            return setmealDto;
        }
        return null;
    }

在setmealcontroller中调用该方法

@GetMapping("/{id}")
    public R<SetmealDto> getDate(@PathVariable long id){
        SetmealDto setmealDto=setmealService.getDate(id);
        return R.success(setmealDto);
}
@PutMapping
    public R<String> edit(@RequestBody SetmealDto setmealDto){
        if (setmealDto==null) {
            return R.error("请求异常");
        }
        if (setmealDto.getSetmealDishes()==null){
            return R.error("套餐没有菜品,请添加套餐");
        }
List<SetmealDish> setmealDishes=setmealDto.getSetmealDishes();
        Long setmealId= setmealDto.getId();
        LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,setmealId);
        setmealDishService.remove(queryWrapper);
        //为setmealdish表填充相关属性
    for (SetmealDish setmealDish:setmealDishes){
        setmealDish.setSetmealId(setmealId);
    }
    //批量把setmealdish保存到setmealdish表
    setmealDishService.saveBatch(setmealDishes);
    setmealService.updateById(setmealDto);
    return R.success("套餐修改成功");
}

6.订单明细

在ordercontroller中编写

@GetMapping("/page")
    public R<Page> page(int page,int pageSize,String number,String beginTime,String endTime){
      //分页构造器对象
    Page<Orders> pageInfo=new Page<>(page,pageSize);
    //构造条件查询对象
    LambdaQueryWrapper<Orders> queryWrapper=new LambdaQueryWrapper<>();
    //添加查询条件  动态sql  字符串使用StringUtils.isNotEmpty这个方法来判断
    //这里使用了范围查询的动态SQL,这里是重点!!!
    queryWrapper.like(number!=null,Orders::getNumber,number)
            .gt(StringUtils.isNotEmpty(beginTime),Orders::getOrderTime,beginTime)
            .lt(StringUtils.isNotEmpty(endTime),Orders::getOrderTime,endTime);
    orderService.page(pageInfo,queryWrapper);
    return R.success(pageInfo);
}

为了在订单明细界面能够显示用户名,所有要修改前端代码,把72行的userName改成consignee就行。

4c48f1857d2648adb0cecc86bb4fd7b9.png

7.手机端减少菜品或者套餐数量

在Shoppingcarcontroller中编写

//购物车减少
    @PostMapping("/sub")
    @Transactional
    public R<ShoppingCart> sub(@RequestBody ShoppingCart shoppingCart){
        Long dishId = shoppingCart.getDishId();
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        //代表数量减少的是菜品数量
        if (dishId != null){
            //通过dishId查出购物车对象
            queryWrapper.eq(ShoppingCart::getDishId,dishId);
            //这里必须要加两个条件,否则会出现用户互相修改对方与自己购物车中相同套餐或者是菜品的数量
            queryWrapper.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());
            ShoppingCart cart1 = shoppingCartService.getOne(queryWrapper);
            cart1.setNumber(cart1.getNumber()-1);
            Integer LatestNumber = cart1.getNumber();
            if (LatestNumber > 0){
                //对数据进行更新操作
                shoppingCartService.updateById(cart1);
            }else if(LatestNumber == 0){
                //如果购物车的菜品数量减为0,那么就把菜品从购物车删除
                shoppingCartService.removeById(cart1.getId());
            }else if (LatestNumber < 0){
                return R.error("操作异常");
            }
            return R.success(cart1);
        }
        Long setmealId = shoppingCart.getSetmealId();
        if (setmealId != null){
            //代表是套餐数量减少
            queryWrapper.eq(ShoppingCart::getSetmealId,setmealId).eq(ShoppingCart::getUserId,BaseContext.getCurrentId());
            ShoppingCart cart2 = shoppingCartService.getOne(queryWrapper);
            cart2.setNumber(cart2.getNumber()-1);
            Integer LatestNumber = cart2.getNumber();
            if (LatestNumber > 0){
                //对数据进行更新操作
                shoppingCartService.updateById(cart2);
            }else if(LatestNumber == 0){
                //如果购物车的套餐数量减为0,那么就把套餐从购物车删除
                shoppingCartService.removeById(cart2.getId());
            }else if (LatestNumber < 0){
                return R.error("操作异常");
            }
            return R.success(cart2);
        }
        //如果两个大if判断都进不去
        return R.error("操作异常");
    }

8.用户查看自己的订单

Dto下新建一个orderDto

import com.itheima.reggie.entity.OrderDetail;
import com.itheima.reggie.entity.Orders;
import lombok.Data;
import java.util.List;
@Data
public class OrderDto extends Orders {
private List<OrderDetail> orderDetails;
}

在ordercontroller编写

    //抽离的一个方法,通过订单id查询订单明细,得到一个订单明细的集合
    //这里抽离出来是为了避免在stream中遍历的时候直接使用构造条件来查询导致eq叠加,从而导致后面查询的数据都是null
public List<OrderDetail> getOrderDetailListByOrderId(Long orderId){
        LambdaQueryWrapper<OrderDetail> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderDetail::getOrderId,orderId);
        List<OrderDetail> orderDetailList=orderDetailService.list(queryWrapper);
        return orderDetailList;
}
@GetMapping("/userPage")
    public R<Page> page(int page,int pageSize){
    //分页构造器对象
    Page<Orders> pageInfo=new Page<>(page,pageSize);
    Page<OrderDto> pageDto=new Page<>(page,pageSize);
    //构造条件查询对象
    LambdaQueryWrapper<Orders> queryWrapper=new LambdaQueryWrapper<>();
    queryWrapper.eq(Orders::getUserId, BaseContext.getCurrentId());
    //这里是直接把当前用户分页的全部结果查询出来,要添加用户id作为查询条件,否则会出现用户可以查询到其他用户的订单情况
    //添加排序条件,根据更新时间降序排列
    queryWrapper.orderByDesc(Orders::getOrderTime);
    orderService.page(pageInfo,queryWrapper);
    //通过OrderId查询对应的OrderDetail
    LambdaQueryWrapper<OrderDetail> queryWrapper2=new LambdaQueryWrapper<>();
    //对OrderDto进行需要的属性赋值
    List<Orders> records=pageInfo.getRecords();
    List<OrderDto> orderDtoList=records.stream().map((item)->{
        OrderDto orderDto=new OrderDto();
        //此时orderdto对象里面还是空,下面准备为他赋值
        Long orderId = item.getId();
        List<OrderDetail> orderDetailList=this.getOrderDetailListByOrderId(orderId);
        BeanUtils.copyProperties(item,orderDto);
        //对orderDto进行orderDetaillists属性赋值
        orderDto.setOrderDetails(orderDetailList);
        return orderDto;
    }).collect(Collectors.toList());
    BeanUtils.copyProperties(pageInfo,pageDto,"records");
    pageDto.setRecords(orderDtoList);
    return R.success(pageDto);
}

9.用户点击套餐图片查看套餐详情

在setmealcontroller中编写

@GetMapping("dish/{id}")
    public R<List<DishDto>> dish(@PathVariable("id") Long SetmealId){
 LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
 queryWrapper.eq(SetmealDish::getSetmealId,SetmealId);
 //获取套餐里面的所有菜品 这个就是SetmealDsih表里面的数据
    List<SetmealDish> list= setmealDishService.list(queryWrapper);
    List<DishDto> dishDtos=list.stream().map((setmealDish) -> {
        DishDto dishDto=new DishDto();
        //其实这个beanutils的拷贝是浅拷贝,这里要注意
        BeanUtils.copyProperties(setmealDish,dishDto);
        //这里是为了把套餐中菜品的基本信息填充到dto中
        Long dishId= setmealDish.getDishId();
        Dish dish=dishService.getById(dishId);
        BeanUtils.copyProperties(dish,dishDto);
        return dishDto;
    }).collect(Collectors.toList());
    return R.success(dishDtos);
}

10.退出登录

在usercontroller中编写

@PostMapping
    public R<String> logout(HttpServletRequest request){
    //清理seession中的id
    request.getSession().removeAttribute("user");
    return R.success("退出成功");
}

11.后台订单状态修改

在ordercontroller中编写

@PutMapping
    public R<String> orderStatusChange(@RequestBody Map<String,String> map){
        String id=map.get("id");
        Long orderId=Long.parseLong(id);
        Integer status=Integer.parseInt(map.get("status"));
        if (orderId==null || status==null){
            return R.error("传入的信息不合法");
        }
        Orders orders=orderService.getById(orderId);
        orders.setStatus(status);
        orderService.updateById(orders);
        return R.success("订单状态修改");
}

12.删除地址

在AddressBookController中编写代码

    @DeleteMapping
    public R<String> delete(@RequestParam("ids")Long id){
        if (id==null){
            return R.error("请求异常");
        }
        LambdaQueryWrapper<AddressBook> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(AddressBook::getId,id).eq(AddressBook::getUserId,BaseContext.getCurrentId());
        addressBookService.remove(queryWrapper);
        return R.success("删除地址成功");
    }

13.修改地址

在AddressBookController中编写代码

    //修改地址
    @PutMapping
    public R<String> update(@RequestBody AddressBook addressBook){
        if (addressBook==null){
            return R.error("请求异常");
        }
        addressBookService.updateById(addressBook);
        return R.success("修改成功");
    }


相关文章
|
前端开发 Java 开发者
深入理解Spring Boot中的@Service注解
【4月更文挑战第22天】在 Spring Boot 应用开发中,@Service 注解扮演着特定的角色,主要用于标识服务层组件。本篇技术博客将全面探讨 @Service 注解的概念,并提供实际的应用示例,帮助开发者理解如何有效地使用这一注解来优化应用的服务层架构
3071 1
|
9月前
|
人工智能 搜索推荐 自然语言处理
大模型落地的关键:如何用 RAG 打造更智能的 AI 搜索——阿里云 AI 搜索开放平台
本文分享了大模型落地的关键:如何用阿里云 AI 搜索开放平台 打造更智能的 AI 搜索。
632 8
大模型落地的关键:如何用 RAG 打造更智能的 AI 搜索——阿里云 AI 搜索开放平台
|
机器学习/深度学习 人工智能 开发者
【AI系统】昇思 MindSpore 关键特性
本文介绍华为自研AI框架昇思MindSpore,一个面向全场景的AI计算框架,旨在提供统一、高效、安全的平台,支持AI算法研究与生产部署。文章详细阐述了MindSpore的定位、架构、特性及在端边云全场景下的应用优势,强调其动静态图统一、联邦学习支持及高性能优化等亮点。
482 7
【AI系统】昇思 MindSpore 关键特性
|
存储 Serverless API
通过图片视觉理解,结构化提取属性信息测评报告
本文详细评测了阿里云的图片信息提取解决方案,涵盖部署、功能测试、性能表现及安全性考量等方面。该方案结合函数计算、对象存储与百炼模型服务,提供高效、准确的图像处理能力,适合快速搭建图像处理应用。
509 12
|
存储 缓存 自然语言处理
es的java实战
【5月更文挑战第22天】Elasticsearch (ES) 是一个强大的分布式搜索和分析引擎,它可以处理大量的数据并支持复杂的搜索需求。
289 1
|
缓存 分布式计算 DataWorks
DataWorks操作报错合集之连接数据库时出现了通信链接失败的报错,该如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
数据采集 移动开发 搜索推荐
HTML基础-HTML5新增语义标签:解锁网页结构新维度
【6月更文挑战第5天】本文介绍了HTML5的语义标签,旨在提升网页结构化和可访问性。核心语义标签包括`&lt;header&gt;`、`&lt;nav&gt;`、`&lt;main&gt;`、`&lt;article&gt;`、`&lt;section&gt;`、`&lt;aside&gt;`、`&lt;footer&gt;`、`&lt;figure&gt;`和`&lt;figcaption&gt;`。常见问题包括滥用标签作布局工具、忽略`&lt;main&gt;`、不恰当嵌套和忽视辅助功能。
375 3
|
运维 监控 架构师
自动化运维的概念|学习笔记
快速学习自动化运维的概念
自动化运维的概念|学习笔记
|
关系型数据库 MySQL 大数据
MySQL分区与分表:优化性能与提升可扩展性
本文深入探讨了MySQL数据库中的分区与分表策略,通过详细的代码示例,解释了分区的概念与用途、不同的分区类型以及创建分区表的步骤。同时,文章还介绍了分表的概念、策略和实际操作方法,以代码演示展示了如何创建分表、插入数据以及查询数据。分区和分表作为优化数据库性能和提升可扩展性的关键手段,通过本文的阐述,读者将能够深入了解如何根据数据特点选择合适的分区方式,以及如何灵活地处理大量数据,提高查询和维护效率。这些技术将为数据库设计和优化提供有力支持,确保在大数据场景下能够高效地管理和查询数据。
2686 0
|
机器学习/深度学习 算法
【机器学习】梯度消失和梯度爆炸的原因分析、表现及解决方案
本文分析了深度神经网络中梯度消失和梯度爆炸的原因、表现形式及解决方案,包括梯度不稳定的根本原因以及如何通过网络结构设计、激活函数选择和权重初始化等方法来解决这些问题。
3020 0