当前位置:网站首页>5. dish management business development

5. dish management business development

2022-06-24 10:16:00 xjhqre

Dish management business development

1、 File upload function

1.1、 Import page

Import from data upload.html file

image-20220618161726114

1.2、 Write the file upload method

1、 Save address configuration , stay application.yml Add the following configuration

reggie:
  path: D:\reggieImg\

2、 Implementation method

package com.itheima.reggie.controller;

import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/** * @Author: xjhqre * @DateTime: 2022/6/18 16:18 */
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {
    

    @Value("${reggie.path}")
    private String basePath;

    @PostMapping("/upload")
    public R<String> upload(MultipartFile file) {
    
        // file It's a temporary document , It needs to be transferred to the specified location , Otherwise, the temporary file will be deleted after this request is completed 
        log.info(file.toString());

        //  Original filename 
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        //  Use UUID Regenerate file name , Prevent file names from being overwritten repeatedly 
        String fileName = UUID.randomUUID() + suffix;

        //  Create a directory object 
        File dir = new File(basePath);
        //  Determine whether the current directory exists 
        if (!dir.exists()) {
    
            dir.mkdirs();
        }

        try {
    
            //  Transfer the temporary file to the specified location 
            file.transferTo(new File(basePath + fileName));
        } catch (IOException e) {
    
            e.printStackTrace();
        }

        return R.success(fileName);
    }
}

1.3、 Open upload picture request address

modify LoginCheckFilter Filter configuration for

image-20220618163434986

1.4、 Test image upload function

Access address http://localhost:8080/backend/page/demo/upload.html

Test upload function

1.5、 Use alicloud OSS Storage ( Optional )

1.5.1、 establish bucket

image-20220618155455656

1.5.2、 establish AccessKey

1、 Use child users AccessKey, Remember to save after creation accessKeySecret, Unable to query in the future

image-20220618161448659

2、 Add user rights

image-20220423150723733

1.5.3、 Introduce dependencies

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

1.5.4、 Create upload method

/** *  Upload files OSS * @param file * @return */
@PostMapping("/upload")
public R<String> upload(MultipartFile file) {
    
    // file It's a temporary document , It needs to be transferred to the specified location , Otherwise, the temporary file will be deleted after this request is completed 
    log.info(file.toString());

    //  Original filename 
    String originalFilename = file.getOriginalFilename();
    String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

    // Endpoint East China 1( Hangzhou ) For example , Other Region Please fill in according to the actual situation .
    String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    //  Alicloud account AccessKey Have all the API Access rights of , The risk is high . It is highly recommended that you create and use it RAM The user carries out API Visit or daily operations , Please log in RAM Console creation RAM user .
    String accessKeyId = " Yours accessKeyId";
    String accessKeySecret = " Yours accessKeySecret";
    //  Fill in Bucket name , for example examplebucket.
    String bucketName = " Yours bucketName";
    //  Fill in Object The full path , The full path cannot contain Bucket name , for example exampledir/exampleobject.txt.
    String objectName = UUID.randomUUID() + suffix;
    //  establish OSSClient example .
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

    // getInputStream() Return to one InputStream To read the contents of the file . Through this method, you can get the stream 
    InputStream multipartFileInputStream = null;
    try {
    
        multipartFileInputStream = file.getInputStream();
    } catch (IOException e) {
    
        e.printStackTrace();
    }
    
    try {
    
        //  establish PutObject request .
        ossClient.putObject(bucketName, objectName, multipartFileInputStream);
    } catch (OSSException oe) {
    
        System.out.println("Caught an OSSException, which means your request made it to OSS, "
                + "but was rejected with an error response for some reason.");
        System.out.println("Error Message:" + oe.getErrorMessage());
        System.out.println("Error Code:" + oe.getErrorCode());
        System.out.println("Request ID:" + oe.getRequestId());
        System.out.println("Host ID:" + oe.getHostId());
    } catch (ClientException ce) {
    
        System.out.println("Caught an ClientException, which means the client encountered "
                + "a serious internal problem while trying to communicate with OSS, "
                + "such as not being able to access the network.");
        System.out.println("Error Message:" + ce.getMessage());
    } finally {
    
        if (ossClient != null) {
    
            ossClient.shutdown();
        }
    }

    return R.success(objectName);
}

2、 File download function

demand : When we upload an image, we need to echo it in the browser

2.1 Write the download method

stay CommonController Write below download Method

/** *  File download  * @param name * @param response */
@GetMapping("/download")
public void download(String name, HttpServletResponse response) {
    

    try {
    
        //  Input stream , Read picture information from local disk 
        FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));

        //  Output stream , Output picture information to browser 
        ServletOutputStream outputStream = response.getOutputStream();

        response.setContentType("image/jpeg");

        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fileInputStream.read(bytes)) != -1) {
    
            outputStream.write(bytes, 0, len);
            outputStream.flush();
        }
        //  close resource 
        outputStream.close();
        fileInputStream.close();
        
    } catch (Exception e) {
    
        e.printStackTrace();
    }
}

2.2、 Test the picture echo function

2.3、 request OSS picture ( Optional )

If used OSS Upload picture service , Want to get OSS picture , Just modify the request path of the picture , As shown in the figure below :

modify upload.html In the file handleAvatarSuccess Method request path

image-20220618171611566

3、 New dishes

Execute the process :

  1. page (backend/page/food/add.html) send out ajax request , Request the server to obtain the dish classification data and display it in the drop-down box
  2. The page sends a request for image upload , Request the server to save the picture to the server
  3. The page sends a request for image download , Echo the uploaded picture
  4. Click the save button , send out ajax request , Take the relevant data of dishes as json Submit to the server in the form of

3.1、 preparation

First, prepare the required classes and interfaces :

  1. Entity class DishFlavor( Import from data )
  2. Mapper Interface DishFlavorMapper
  3. Business layer interface DishFlavorService
  4. Business layer implementation classes DishFlavorServiceImpl
  5. Control layer DishController

Dish and DishFlavor Our business is conducted by DishController Handle

3.2、 Query the menu classification list

stay CategoryController Written in list Method

/** *  Query classified data according to conditions  * @param category * @return */
@GetMapping("/list")
public R<List<Category>> list(Category category) {
    
    //  Conditional constructor 
    LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
    //  Adding conditions 
    queryWrapper.eq(category.getType() != null, Category::getType, category.getType());
    //  Add sorting criteria 
    queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);

    List<Category> list = categoryService.list(queryWrapper);
    return R.success(list);
}

3.3、 Import DTO

Because of the data from the front end , On the back end, you can't directly use Dish and DishFlavor receive , You need an entity class that also has Dish and DishFlavor Properties of .

package com.itheima.reggie.dto;

import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;

@Data
public class DishDto extends Dish {
    

    private List<DishFlavor> flavors = new ArrayList<>();

    private String categoryName;

    private Integer copies;
}

It can be seen that a subclass can inherit everything from the parent class . You just can't get permission directly private or default Properties and methods of

3.4、 establish controller Method

stay DishController Class save Method

package com.itheima.reggie.controller;

import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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

    @Autowired
    DishService dishService;

    @Autowired
    DishFlavorService dishFlavorService;

    /** *  New dishes  * @param dishDto * @return */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto) {
    
        log.info(dishDto.toString());
        dishService.saveWithFlavor(dishDto);
        return R.success(" Added dishes successfully ");
    }
}

3.5、 stay service Method defined in

stay DishService In the definition of saveWithFalvor Method

package com.itheima.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;

public interface DishService extends IService<Dish> {
    

    //  New dishes , At the same time, insert the taste data corresponding to the dish , You need to operate two tables :dish and dish_falvor
    void saveWithFalvor(DishDto dishDto);
}

3.6、 stay ServiceImpl Middle implementation method

package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    

    @Autowired
    private DishFlavorService dishFlavorService;

    /** *  New dishes , At the same time, save the corresponding taste data  * @param dishDto */
    @Override
    @Transactional
    public void saveWithFlavor(DishDto dishDto) {
    
        //  Save the basic information of the dishes to dish surface 
        this.save(dishDto);

        Long dishId = dishDto.getId();

        //  Dish taste 
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().peek(item -> item.setDishId(dishId)).collect(Collectors.toList());

        //  Save the dish taste data to dish_flavor surface 
        dishFlavorService.saveBatch(flavors);
    }
}

3.7、 Start the transaction in the main startup class

add to @EnableTransactionManagement annotation

@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableTransactionManagement
public class ReggieApplication {
    
    public static void main(String[] args) {
    
        SpringApplication.run(ReggieApplication.class, args);
        log.info(" The project started successfully ...");
    }
}

3.8、 Test new dishes

After adding dishes, check whether the database is added correctly

2

4、 Pagination query of dish information

4.1、 Create a paging query method

4.1.1、 Method 1 : The teacher's method

/** *  Pagination query of dish information  * @param page * @param pageSize * @param name * @return */
@GetMapping("/page")
public R<Page<DishDto>> page(int page, int pageSize, String name) {
    
    //  Constructing a page builder object 
    Page<Dish> pageInfo = new Page<>(page, pageSize);
    Page<DishDto> dishDtoPage = new Page<>();

    //  Conditional constructor 
    LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
    //  Add filter conditions 
    queryWrapper.like(name != null, Dish::getName, name);
    //  Add sorting criteria 
    queryWrapper.orderByDesc(Dish::getUpdateTime);

    //  Perform paging queries 
    dishService.page(pageInfo, queryWrapper);

    //  Object Copy 
    BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");

    List<Dish> records = pageInfo.getRecords();
    List<DishDto> list = records.stream().map(item -> {
    
        DishDto dishDto = new DishDto();

        BeanUtils.copyProperties(item, dishDto);

        Long categoryId = item.getCategoryId();
        //  According to the classification id Query classification objects 
        Category category = categoryService.getById(categoryId);

        if (category != null) {
    
            String categoryName = category.getName();
            dishDto.setCategoryName(categoryName);
        }

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

    dishDtoPage.setRecords(list);

    return R.success(dishDtoPage);
}

4.1.2、 Method 2 : Join table query method ( Optional )

1、DishController layer

/** *  Pagination query of dish information  * @param page * @param pageSize * @param name * @return */
@GetMapping("/page")
public R<Page<DishDto>> page(int page, int pageSize, String name) {
    
    //  Constructing a page builder object 
    Page<DishDto> pageInfo = new Page<>(page, pageSize);

    dishService.selectDishWithCategoryNameList(pageInfo, name);

    return R.success(pageInfo);
}

2、DishService layer , Add the following method declaration

//  Query the information of all dishes with category names 
void selectDishWithCategoryNameList(Page<DishDto> page, String name);

3、DishServiceImpl layer , Realization selectDishWithCategoryNameList Method

/** *  Query all Dish With the category name of the dishes  * @param page */
@Override
public void selectDishWithCategoryNameList(Page<DishDto> page, String name) {
    
    List<DishDto> records = baseMapper.selectDishWithCategoryNameList(page, name == null ? "" : name);
    page.setRecords(records);
}

4、DishMapper layer , Add the following method declaration

@Select("SELECT a.*, b.`name` AS category_name FROM dish a JOIN category b ON a.`category_id` = b.`id` WHERE a.`name` LIKE CONCAT('%',#{name},'%') ORDER BY sort")
List<DishDto> selectDishWithCategoryNameList(Page<DishDto> page, @Param("name") String name);

4.2、 The menu shows Alibaba cloud OSS picture ( Optional )

If you use images stored by Alibaba cloud , Need modification backend/page/food/list.html There are two places in the document

modify :preview-src-list Value

image-20220618205112471

modify return Value

image-20220618205154527

4.3、 Test the effect of dish query

image-20220618211641139

5、 Modify the menu page data echo

Execute the process :

  1. Page sending ajax request , Request the server to obtain classification data , It is used to display the data in the drop-down box of dish classification
  2. Page sending ajax request , Request server , according to id Query the current dish information , Used for echo of dish information
  3. Page send request , Request the server to download pictures , Used for page picture echo
  4. Click the save button , Page sending ajax request , Use the modified dish related data as json Submit to the server in the form of

5.1、DishController

establish get Method

/** *  according to id Query the dish information and the corresponding taste information  * @param id * @return */
@GetMapping("/{id}")
public R<DishDto> get(@PathVariable Long id) {
    
    DishDto dishDto = dishService.getByIdWithFlavor(id);
    return R.success(dishDto);
}

5.2、DishService

Statement getByIdWithFlavor Method

//  according to id Query the dish information and the corresponding taste information 
DishDto getByIdWithFlavor(Long id);

5.3、DishServiceImpl

Realization getByIdWithFlavor Method

/** *  according to id Query the dish information and the corresponding taste information  * @param id * @return */
@Override
public DishDto getByIdWithFlavor(Long id) {
    
    //  Query the basic information of dishes , from dish Table query 
    Dish dish = this.getById(id);

    DishDto dishDto = new DishDto();
    BeanUtils.copyProperties(dish, dishDto);

    //  Query the taste information corresponding to the current dish , from dish_flavor Table query 
    LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(DishFlavor::getDishId, dish.getId());
    List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
    dishDto.setFlavors(flavors);

    return dishDto;
}

5.4、 Alibaba cloud OSS Picture echo ( Optional )

modify backend/page/food/add.html file

image-20220618215903004

5.5、 Test modification echo

image-20220618220024367

6、 Modify the dishes

Delete first dish All corresponding dish_flavor, Adding

6.1、DishController

/** *  Modify the dishes  * @param dishDto * @return */
@PutMapping
public R<String> update(@RequestBody DishDto dishDto) {
    
    log.info(dishDto.toString());

    dishService.updateWithFlavor(dishDto);

    return R.success(" Dishes modified successfully ");
}

6.2、DishService

//  Update dish information , At the same time, update the corresponding taste information 
void updateWithFlavor(DishDto dishDto);

6.3、DishServiceImpl

@Override
@Transactional
public void updateWithFlavor(DishDto dishDto) {
    
    //  to update dish Table basic information 
    this.updateById(dishDto);

    //  Clear the taste data corresponding to the current dish 
    LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());

    dishFlavorService.remove(queryWrapper);

    //  Add the currently submitted taste data 
    List<DishFlavor> flavors = dishDto.getFlavors();
    flavors = flavors.stream().peek(item -> item.setDishId(dishDto.getId())).collect(Collectors.toList());

    dishFlavorService.saveBatch(flavors);
}

6.4、 Test and modify dishes

7、 Delete and batch delete dishes ( Optional )

Use logical deletion

First delete the taste corresponding to the dish , Deleting dishes ,is_delete by 1 Said to delete ,0 Indicates not deleted

7.1、 modify Dish and DishFlavor Entity class

to isDeleted Property to add comments @TableLogic(value = "0", delval = "1"). After adding this comment , call mybatis-plus The deletion method of is actually update Method

image-20220619131554336

7.2、DishController

/** *  Logical deletion  * @param ids * @return */
@DeleteMapping
@Transactional
public R<String> delete(Long[] ids) {
    
    log.info(" Batch deleted id:{}", Arrays.toString(ids));
    //  First, delete the taste information corresponding to the dishes 
    dishFlavorService.removeByDishIds(Arrays.asList(ids));
    //  Delete the dishes logically 
    dishService.removeByIds(Arrays.asList(ids));

    return R.success(" Delete dishes successfully ");
}

7.3、DishFlavorService

/** *  Delete the taste record of the corresponding dish logically  * @param dishIds */
void removeByDishIds(List<Long> dishIds);

7.4、DishFlavorServiceImpl

@Service
public class DishFlavorServiceImpl extends ServiceImpl<DishFlavorMapper, DishFlavor> implements DishFlavorService {
    

    @Autowired
    DishFlavorMapper dishFlavorMapper;

    /** *  Delete the taste record of the corresponding dish logically  * @param dishIds */
    @Override
    public void removeByDishIds(List<Long> dishIds) {
    
        dishFlavorMapper.removeByDishIds(dishIds);
    }
}

7.5、DishFlavorMapper

@Mapper
public interface DishFlavorMapper extends BaseMapper<DishFlavor> {
    
    void removeByDishIds(@Param("dishIds") List<Long> dishIds);
}

7.6、DishFlavorDao.xml

stay resources Create under directory mapper Catalog , stay mapper Create under directory DishFlavorDao.xml.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itheima.reggie.mapper.DishFlavorMapper">


    <update id="removeByDishIds">
        UPDATE dish_flavor SET is_deleted=1 WHERE dish_id IN
        <foreach collection="dishIds" item="id" index="index" open="(" close=")" separator=",">
            #{id}
        </foreach>
        AND is_deleted=0
    </update> <!--  modify  -->


</mapper>

7.7、 Modify the menu paging query function

Because we use logical deletion , Deleted dishes can still be seen on the menu , We need to modify the paging query function

The following is to modify the paging query method I wrote , If you use the teacher's paging query method, please modify it by yourself

modify DishMapper Inside selectDishWithCategoryNameList Method , Add... To the notes is_deleted The field can be judged

@Select("SELECT a.*, b.`name` AS category_name FROM dish a JOIN category b ON a.`category_id` = b.`id` WHERE a.`name` LIKE CONCAT('%',#{name},'%') AND a.`is_deleted` = 0 ORDER BY sort")
List<DishDto> selectDishWithCategoryNameList(Page<DishDto> page, @Param("name") String name);

7.8、 Test batch delete

8、 Start and stop selling in batches ( Optional )

8.1、DishController

/** *  Stop selling and start selling in batches  * @param status * @param ids * @return */
@PostMapping("status/{status}")
@Transactional
public R<String> status(@PathVariable("status") int status, @RequestParam Long[] ids) {
    
    log.info(" Start and stop selling in batches :{},{}", status, Arrays.toString(ids));
    dishService.updateStatusByIds(status, ids);
    return R.success(" Successful start and stop of batch sales ");
}

8.2、DishService

//  Start and stop selling in batches 
void updateStatusByIds(int status, Long[] ids);

8.3、DishServiceImpl

/** *  Start and stop selling in batches  * @param status * @param ids */
@Override
public void updateStatusByIds(int status, Long[] ids) {
    
    dishMapper.updateStatusByIds(status, ids);
}

8.4、DishMapper

void updateStatusByIds(@Param("status") int status, @Param("ids") Long[] ids);

8.5、DishDao.xml

stay resources In the catalog mapper Create under directory DishDao.xml file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itheima.reggie.mapper.DishMapper">

    <update id="updateStatusByIds">
        UPDATE dish
        SET status = #{status}
        WHERE id IN
        <foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
            #{id}
        </foreach>
        AND status != #{status}
    </update> <!--  modify  -->
</mapper>

8.6、 Test the start and stop of batch sales

原网站

版权声明
本文为[xjhqre]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/175/202206240916021068.html