Dark Horse Programmer Java Project Actual Combat "Regi Takeaway" Notes Day5: Video P69-P88

Dark Horse Programmer Java Project Actual Combat "Regis Takeaway" Notes

This course is based on the current popular takeaway food ordering business, and the business is real, practical and extensive.
Developed based on popular technical frameworks such as Spring Boot and mybatis plus, leading students to experience the real project development process, requirements analysis process and code implementation process. After completing this course, you can gain: exercise demand analysis ability, coding ability, bug debugging ability, and increase development experience.

  • Link: https://www.bilibili.com/video/BV13a411q753

20230322 Day5: Video P69-P88

  • Package system management
  • New package
  • Package page query
  • Package delete
  • send a text message

Package system management:

demand analysis:

A set meal is a collection of dishes.
You can manage the set meal information in the background system, and add a new set meal through the new set meal function. When adding a set meal, you need to select the set meal category
and the included dishes of the current set meal! And you need to upload the picture corresponding to the package, and the corresponding package will be displayed on the mobile terminal according to the category of the package.

Data model:

Adding a new set meal is actually inserting the set meal information entered on the new page into the setmeal table, and also inserting the setmeal_dish table with related data about the set meal and dishes.
So when adding a package, two tables are involved:

  • setmeal set menu
  • setmeal_dish set meal dish relationship table

Before developing business functions, first create the basic structure of the classes and interfaces that need to be used:
the entity class SetmealDish

DTO SetmealDto

package com.reggie.DTO;

import com.reggie.entity.Setmeal;
import com.reggie.entity.SetmealDish;
im坎普iopt 吃点饭认得日日日f't'ge'w's'xport lombok.Data;
import java.util.List;

@Data
public class SetmealDto extends Setmeal {
    
    

    private List<SetmealDish> setmealDishes;

    private String categoryName;
}

Mapper interface SetmealDishMapper

package com.reggie.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.reggie.entity.SetmealDish;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface SetmealDishMapper extends BaseMapper<SetmealDish> {
    
    
    
}

Business layer connection ▣SetmealDishService

package com.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.reggie.entity.SetmealDish;

public interface SetmealDishService extends IService<SetmealDish> {
    
    

}

Business layer implementation class SetmealDishServicelmpl

package com.reggie.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reggie.entity.SetmealDish;
import com.reggie.mapper.SetmealDishMapper;
import com.reggie.mapper.SetmealMapper;
import com.reggie.service.SetmealDishService;
import org.springframework.stereotype.Service;

@Service
public class SetmealDishServicelmpl extends ServiceImpl<SetmealDishMapper, SetmealDish> implements SetmealDishService {
    
    
    
}

Control layer SetmealController

package com.reggie.controller;

import com.reggie.service.SetmealDishService;
import com.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {
    
    
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private SetmealService setmealService;
    
}

New package:

Before developing the code, you need to sort out the interaction process between the front-end page and the server when adding a package:

1. The page (backend/page/combo/add.html) sends an ajax request, requesting the server to obtain the package classification data and display it in the drop-down box 2. The page
sends an ajx request, requesting the server to obtain the dish classification data and display it to add dishes In the window
3. The page sends an ajx request, requests the server to query the corresponding dish data according to the dish classification and displays it in the add dish window 4. The page
sends a request to upload the picture, and requests the server to save the picture to the server
5. The page sends the request Download pictures and echo the uploaded pictures
6. Click the save button, send an ajax request, and submit package-related data to the server in the form of )json
to develop new package functions. In fact, it is to write code on the server to process the front-end page The 6 requests sent are enough.

Create a List method in DishController to query dishes

@GetMapping("/list")
public R<List<Dish>> List(Dish dish){
    
    
    LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
    queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
    
    List<Dish> list = dishService.list(queryWrapper);
    return R.success(list);
}

Create the method saveWithDish in SetmealService, and implement it in SetmealServiceImpl, follow the previous code, use the stream flow, read the ID from setmealDto, and finally call the method in SetmealController to complete the save

@Transactional
@Override
public void saveWithDish(SetmealDto setmealDto) {
    
    
    this.save(setmealDto);

    List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
    setmealDishes.stream().map((item)->{
    
    
       item.setDishId(setmealDto.getId());
       return item;
    }).collect(Collectors.toList());

    setmealDishService.saveBatch(setmealDishes);
}
@PostMapping
public R<String> save(@RequestBody SetmealDto setmealDto){
    
    
    setmealService.saveWithDish(setmealDto);
    return R.success("套餐保存成功!") ;
}

Package page query:

It is almost the same as the menu page query, skip here

    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name){
    
    
        log.info("接收到查询请求,page={},pageSize={},name={}",page,pageSize,name);
        //构造分页构造器
        Page<Setmeal> pageinfo=new Page<>(page,pageSize);
        Page<SetmealDto> setmealDtoPage = 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);
        BeanUtils.copyProperties(pageinfo,setmealDtoPage,"records");

        List<Setmeal> records = pageinfo.getRecords();
        List<SetmealDto> list = null;

        list = records.stream().map((item)->{
    
    
            SetmealDto setmealDto = new SetmealDto();

            BeanUtils.copyProperties(item,setmealDto);

            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if(category!=null){
    
    
                String categoryName = category.getName();
                setmealDto.setCategoryName(categoryName);
            }

            return setmealDto;

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

        setmealDtoPage.setRecords(list);

        return R.success(setmealDtoPage);
    }

Package deletion:

demand analysis

Click the delete button on the package management list page to delete the corresponding package information. You can also select multiple packages through the check boxes, and click the batch delete
button to delete multiple packages at one time. Note that packages whose status is on sale cannot be deleted, they need to be stopped before they can be deleted.

Create a method in SetmealController, and add @PostMapping annotation, the incoming parameter is @RequestBody SetmealDto setmealDto

@DeleteMapping
public R<String> delete(@RequestParam List<Long> ids){
    
    
    return null;
}

Create the removeWithDish method in SetmealService and implement the method in SetmealServiceImpl

@Override
    public void removeWithDish(List<Long> ids) {
    
    
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId,ids).eq(Setmeal::getStatus,1);
        int count = this.count(queryWrapper);
        if(count>0){
    
    
            throw new CustomException("套餐正在售卖中,无法删除!");
        }
        this.removeByIds(ids);
        LambdaQueryWrapper<SetmealDish> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(SetmealDish::getSetmealId,ids);
        setmealDishService.remove(queryWrapper1);

    }

send a text message:

Create a utils package and copy in two tool classes

package com.reggie.utils;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;

/**
 * 短信发送工具类
 */
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();
		}
	}

}

package com.reggie.utils;

import java.util.Random;

/**
 * 随机生成验证码工具类
 */
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;
    }
}

Create entity class User

package com.reggie.entity;

import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
/**
 * 用户信息
 */
@Data
public class User implements Serializable {
    
    

    private static final long serialVersionUID = 1L;

    private Long id;


    //姓名
    private String name;


    //手机号
    private String phone;


    //性别 0 女 1 男
    private String sex;


    //身份证号
    private String idNumber;


    //头像
    private String avatar;


    //状态 0:禁用,1:正常
    private Integer status;
}

Create Mapper/Service/ServiceImpl/Controller in turn

package com.reggie.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.reggie.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    
    

}

package com.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.reggie.entity.User;

public interface UserService extends IService<User> {
    
    
}

package com.reggie.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reggie.entity.User;
import com.reggie.mapper.UserMapper;
import com.reggie.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    

}

package com.reggie.controller;

import com.reggie.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    
    
    @Autowired
    private UserService userService;


}

Create a sendMsg method in UserController to send the verification code

@PostMapping("/sendMsg")
public R<String> sendMsg(@RequestBody User user, HttpSession session){
    
    
    String phone = user.getPhone();
    if(StringUtils.isNotEmpty(phone)){
    
    
        String  code = ValidateCodeUtils.generateValidateCode(4).toString();
        //调用api发送短信
        log.info("验证码为:{}",code);
        //需要申请签名,先跳过
        session.setAttribute(phone,code);
        return R.success("验证码发送成功!");

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

Create a login method in UserController to judge whether the verification code is correct, and query after the verification code is correct. If the user does not exist in the database, it will be created automatically

@PostMapping("/login")
public R<User> login(@RequestBody Map map, HttpSession session){
    
    
    String phone = map.get("phone").toString();
    String code = map.get("code").toString();

    Object codeInSession = session.getAttribute(phone);

    if(codeInSession!= null&&codeInSession.equals(code)){
    
    
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone,phone);
        User user = userService.getOne(queryWrapper);
        if(user==null){
    
    
            user = new User();
            user.setPhone(phone);
            user.setStatus(1);
            userService.save(user);
            log.info("用户{}注册成功!",user.toString());
        }
        session.setAttribute("user",phone);
        return R.success(user);
    }

    return R.error("");
}

Guess you like

Origin blog.csdn.net/m0_46504802/article/details/129722841