瑞吉外卖第五天(套餐的增删改和手机端登录功能的实现)

1.新增套餐的功能

分析点击新增套餐时,就已经发送了这几个请求(分别查询了分类名,菜品,套餐分类)

根据分类Id查询菜品

@GetMapping("/list")
    public R<List<DishDto>> getByCategoryId(Dish dish){

        //创建条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish.getCategoryId()!= null,Dish::getCategoryId,dish.getCategoryId());
        //只显示起售状态下的菜品 和未删除的
        queryWrapper.eq(Dish::getStatus,1);
        queryWrapper.eq(Dish::getIsDeleted,0);

        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> dishList = dishService.list(queryWrapper);

        List<DishDto> dishDtoList = dishList.stream().map((item) ->{
            DishDto dishDto = new DishDto();
            //获取分类id
            Long categoryId = item.getCategoryId();
            //根据id查询分类信息
            Category category = categoryService.getById(categoryId);
            if(category != null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }

            BeanUtils.copyProperties(item,dishDto);
            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 R.success(dishDtoList);
    }

根据分类进行查询套餐fenlei以及分类名

 @GetMapping("/list")
    public R<List<Category>> list(Category category){
       //条件构造器
       LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
       queryWrapper.eq(category.getType() != null,Category::getType,category.getType());
       queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
       List<Category> list = categoryService.list(queryWrapper);
       return R.success(list);
   }

分析前端传来的参数

我们需要用SetmealDto来接收JSON数据,而且需要操作两张表即我们需要自定义一个新增套餐的方法

 实现类

/**
     * 自定义新增菜品实现
     * @param setmealDto
     */
    @Transactional
    public void saveSetmealWithSetmealDish(SetmealDto setmealDto) {

        //添加套餐到数据库
        this.save(setmealDto);
        //获取套餐包含的菜品表
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        Long setmealDtoId = setmealDto.getId();
        setmealDishes = setmealDishes.stream().map((item) ->{
            item.setSetmealId(setmealDtoId);
            return item;
        }).collect(Collectors.toList());

        setmealDishService.saveBatch(setmealDishes);

    }

使用Controller进行调用

/**
     *
     * 新增套餐
     * @param setmealDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody SetmealDto setmealDto){
        setmealService.saveSetmealWithSetmealDish(setmealDto);
        return R.success("新增套餐成功!");
    }

2.分页查询进行页面展示

分析前端传来的参数

 Controller实现

 /**
     * 分页查询套餐信息
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page,int pageSize,String name){

        //创建分页对象
        Page<Setmeal> pageInfo = new Page<>(page,pageSize);

        //创建条件构造器
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        //条件构造器
        queryWrapper.like(StringUtils.isNotEmpty(name),Setmeal::getName,name);
        //排序构造器
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);

        setmealService.page(pageInfo,queryWrapper);

        Page<SetmealDto> pageDto = new Page<>(page,pageSize);

        //对象拷贝
        BeanUtils.copyProperties(pageInfo,pageDto,"records");

        List<Setmeal> records = pageInfo.getRecords();
        List<SetmealDto> list = records.stream().map((item) ->{
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            SetmealDto setmealDto = new SetmealDto();
            setmealDto.setCategoryName(categoryName);
            BeanUtils.copyProperties(item,setmealDto);
            return setmealDto;
        }).collect(Collectors.toList());

        pageDto.setRecords(list);

        return R.success(pageDto);
    }

3修改套餐功能实现

首先我们需要进行数据的回显

实现类

    /**
     * 查询套餐和菜品用于页面的回显
     * @param id
     * @return
     */
    public SetmealDto getByIdWithSetMealDish(Long id) {

        //根据id查询套餐表
        Setmeal setmeal = this.getById(id);

        //根据套餐id查询所对应的菜品
        //构造条件封装
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,id);
        queryWrapper.eq(SetmealDish::getIsDeleted,0);
        List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper);

        //获取分类id,根据分类id查询分类名称
        Long categoryId = setmeal.getCategoryId();
        Category category = categoryService.getById(categoryId);
        String categoryName = category.getName();

        SetmealDto setmealDto = new SetmealDto();
        //对象拷贝
        BeanUtils.copyProperties(setmeal,setmealDto);
        setmealDto.setSetmealDishes(setmealDishes);
        setmealDto.setCategoryName(categoryName);

        return setmealDto;
    }

Controller调用

 /**
     *获取套餐以及所包含的菜品信息用于页面回显
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<SetmealDto> getByid(@PathVariable Long id){
        SetmealDto setmealDto = setmealService.getByIdWithSetMealDish(id);
        return R.success(setmealDto);
    }

进行修改

分析前端传来的参数

自定义一个修改套餐的方法

 实现类

 /**
     * 修改套餐信息
     * @param setmealDto
     */
    @Override
    public void updateSetmealWithDish(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();
        setmealDishes = setmealDishes.stream().map((item) ->{
            item.setSetmealId(setmealId);
            return item;
        }).collect(Collectors.toList());

        setmealDishService.saveBatch(setmealDishes);

    }

使用Controller进行调用

/**
     * 修改套餐
     * @param setmealDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody SetmealDto setmealDto){
        setmealService.updateSetmealWithDish(setmealDto);
        return R.success("修改套餐成功");
    }

4.(批量)停售启售 套餐

/**
     * 停售套餐
     * @param ids
     * @return
     */
    @PostMapping("/status/0")
    public R<String> updateStatusIsStop(@RequestParam List<Long> ids){

        for (Long id : ids) {
            Setmeal setmeal = new Setmeal();
            setmeal.setId(id);
            setmeal.setStatus(0);
            setmealService.updateById(setmeal);
        }
        return R.success("停售套餐成功");
    }
    /**
     * 启售套餐
     * @param ids
     * @return
     */
    @PostMapping("/status/1")
    public R<String> updateStatusIsStart(@RequestParam List<Long> ids){

        for (Long id : ids) {
            Setmeal setmeal = new Setmeal();
            setmeal.setId(id);
            setmeal.setStatus(1);
            setmealService.updateById(setmeal);
        }
        return R.success("启售套餐品成功");
    }

5.(批量)删除套餐(删除套餐以及套餐包含的菜品表)并且只有停售的套餐才可以删除,自定义一个删除的方法

 /**
     * 删除套餐以及关联的菜品
     * @param ids
     */
    public void deleteWithDish(List<Long> ids) {

        //根据id查询套餐是否是在售状态,select count(*) from setmeal where id in (ids) and status =1;
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId,ids);
        queryWrapper.eq(Setmeal::getStatus,1);

        int count = this.count(queryWrapper);
        //如果在售状态,则不能删除,抛一个业务异常
        if(count>0){
            throw new CustomExepction("套餐正在售卖中,不能删除");
        }
        //否则删除
        this.removeByIds(ids);
        //构造条件构造器
        LambdaQueryWrapper<SetmealDish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(SetmealDish::getSetmealId,ids);
        //删除套餐关联的菜品
        setmealDishService.remove(lambdaQueryWrapper);

    }

 Controller的调用

/**
     * 删除与批量删除套餐及菜品
     * @param ids
     * @return
     */

    @DeleteMapping
    public R<String> deleteAll(@RequestParam List<Long> ids){

        setmealService.deleteWithDish(ids);
        return R.success("删除套餐成功");
    }

6.用户登录功能实现(使用阿里云发送验证码)

首先先对手机端的路径放行

在拦截器上判断用户是否登录

 //3-2.判断用户是否登录
        if(request.getSession().getAttribute("user") != null){

            Long userId = (Long) request.getSession().getAttribute("user");
            BaseContext.setCurrentId(userId);

            //log.info("用户已登录,用户的id为:{}",request.getSession().getAttribute("employee"));
            filterChain.doFilter(request,response);
            return;
        }
        //4.如果未登录则返回未登录的结果,通过输出流的方式向客户端响应数据
        //log.info("用户未登录");
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        return;
    }

用户输入手机号点击发送验证码发送请求

 在Controller完成此功能

@PostMapping("/sendMsg")
    public R<String> sendMsg(@RequestBody User user, HttpSession session){

        //获取手机号
        String phone = user.getPhone();
        //判断手机号是否存在
        if(StringUtils.isNotEmpty(phone)){

            //若存在,生成一个随机4位验证码
            String code = ValidateCodeUtils.generateValidateCode(4).toString();
            log.info("code= {}",code);
            //发送验证码
            SMSUtils.sendMessage("签名名称","模板Code",phone,code);

            //将验证码存入到session中
            session.setAttribute(phone,code);
            return R.success("验证码发送成功");
        }

        return R.error("验证码发送失败");
    }

使用ValidateCodeUtils工具类生成一个指定长度的验证码

/**
 * 随机生成验证码工具类
 */
public class ValidateCodeUtils {
    /**
     * 随机生成验证码
     * @param length 长度为4位或者6位
     * @return
     */
    public static Integer generateValidateCode(int length){
        Integer code =null;
        if(length == 4){
            code = new Random().nextInt(9999);//生成随机数,最大为9999
            if(code < 1000){
                code = code + 1000;//保证随机数为4位数字
            }
        }else if(length == 6){
            code = new Random().nextInt(999999);//生成随机数,最大为999999
            if(code < 100000){
                code = code + 100000;//保证随机数为6位数字
            }
        }else{
            throw new RuntimeException("只能生成4位或6位数字验证码");
        }
        return code;
    }

    /**
     * 随机生成指定长度字符串验证码
     * @param length 长度
     * @return
     */
    public static String generateValidateCode4String(int length){
        Random rdm = new Random();
        String hash1 = Integer.toHexString(rdm.nextInt());
        String capstr = hash1.substring(0, length);
        return capstr;
    }
}

使用SMSUtils工具类进行短信的发送

/**
 * 短信发送工具类
 */
public class SMSUtils {

	/**
	 * 发送短信
	 * @param signName 签名
	 * @param templateCode 模板
	 * @param phoneNumbers 手机号
	 * @param param 参数
	 */
	public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param){
		DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "", "");
		IAcsClient client = new DefaultAcsClient(profile);

		SendSmsRequest request = new SendSmsRequest();
		request.setSysRegionId("cn-hangzhou");
		request.setPhoneNumbers(phoneNumbers);
		request.setSignName(signName);
		request.setTemplateCode(templateCode);
		request.setTemplateParam("{\"code\":\""+param+"\"}");
		try {
			SendSmsResponse response = client.getAcsResponse(request);
			System.out.println("短信发送成功");
		}catch (ClientException e) {
			e.printStackTrace();
		}
	}

}

实现登录功能(校验验证码是否正确,先判断该用户是否存在,如果不存在直接注册)

 @PostMapping("/login")
    public R<User> login(@RequestBody Map map,HttpSession session){

        //获取手机号
        String phone = map.get("phone").toString();
        //获取验证码
        String code = map.get("code").toString();
        //从Session中获取验证码
        Object codeInSession = session.getAttribute(phone);
        //进行验证码校验
        if(codeInSession != null && code.equals(codeInSession)){
            //如果正确则登录成功,判断用户是否为新用户

            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getPhone,phone);
            User user = userService.getOne(queryWrapper);
            if(user == null){
                user = new User();
                user.setPhone(phone);
                userService.save(user);
            }
            session.setAttribute("user",user.getId());
            return R.success(user);
        }
        return R.error("登录失败");
    }

 退出登录功能的实现

/**
     * 退出登录
     * @return
     */
    @PostMapping("/loginout")
    public R<String> logout(HttpServletRequest request){
        //清理session中的指定数据
        request.getSession().removeAttribute("user");
        return R.success("退出成功");
    }

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值