I New package
(1). Perfect page
The new package is divided into two parts: the first is the basic information of the package, and the second is the information of the inspection group associated with the package
Among them, the new package is different from that of the previous inspection item inspection group, and the function of uploading pictures is added
-
Improve the handleCreate method, send ajax request to query all inspection group data, and assign the results to tableData model data for page table display
// The add window pops up handleCreate() { this.dialogFormVisible = true; this.resetForm(); axios.get("/checkgroup/findAll.do").then((res)=> { if(res.data.flag){ this.tableData = res.data.data; }else{ this.$message.error(res.data.message); } }); }
2. In CheckGroupController, CheckGroupService, CheckGroupServiceImpl, CheckGroupDao and CheckGroupDao respectively Query all inspection group data by extension method in XML
(1)CheckGroupController
//Query all @RequestMapping("/findAll") public Result findAll(){ List<CheckGroup> checkGroupList = checkGroupService.findAll(); if(checkGroupList != null && checkGroupList.size() > 0){ Result result = new Result(true, MessageConstant.QUERY_CHECKGROUP_SUCCESS); result.setData(checkGroupList); return result; } return new Result(false,MessageConstant.QUERY_CHECKGROUP_FAIL); }
(2) CheckGroupService
List<CheckGroup> findAll();
(3)CheckGroupServiceImpl,
public List<CheckGroup> findAll() { return checkGroupDao.findAll(); }
(4)CheckGroupDao
List<CheckGroup> findAll();
(5)CheckGroupDao.xml
<select id="findAll" resultType="com.itheima.pojo.CheckGroup"> select * from t_checkgroup </select>
(2) Picture upload function
1. The upload component El upload provided by ElementUI is used here, which provides a variety of different upload effects. After successful upload, you can preview it.
(1) Define the model data for the picture preview of the uploaded file later:
imageUrl:null,//Model data, which is used for picture preview after uploading pictures
(2) Define upload components:
<!-- el-upload: Upload component action: Upload submission address auto-upload: Whether to automatically upload the selected file name: The name of the uploaded file. The server can obtain the uploaded file object according to the name show-file-list: Whether to display the list of uploaded files on-success: Hook when the file is uploaded successfully before-upload: Hook before uploading file --> <el-upload class="avatar-uploader" action="/setmeal/upload.do" :auto-upload="autoUpload" name="imgFile" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <!--Preview for uploading pictures--> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <!--Used to display the upload icon--> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload>
(3) Define the corresponding hook function
//The hook after the file is uploaded successfully. The response is the value returned by the server, and the file is the js object encapsulated by the currently uploaded file handleAvatarSuccess(response, file) { this.imageUrl = "http://pqjroc654.bkt.clouddn.com/"+response.data; this.$message({ message: response.message, type: response.flag ? 'success' : 'error' }); //Set the model data (picture name), which will be submitted to the background and finally saved to the database when submitting ajax requests later this.formData.img = response.data; } //Hook before uploading file beforeAvatarUpload(file) { const isJPG = file.type === 'image/jpeg'; const isLt2M = file.size / 1024 / 1024 < 2; if (!isJPG) { this.$message.error('Upload package pictures can only be JPG format!'); } if (!isLt2M) { this.$message.error('Upload package picture size cannot exceed 2 MB!'); } return isJPG && isLt2M; }
(4) Create a SetmealController to receive uploaded files
/** * Package management */ @RestController @RequestMapping("/setmeal") public class SetmealController { @Reference private SetmealService setmealService; //Picture upload @RequestMapping("/upload") public Result upload(@RequestParam("imgFile")MultipartFile imgFile){ try{ //Get original file name String originalFilename = imgFile.getOriginalFilename(); int lastIndexOf = originalFilename.lastIndexOf("."); //Get file suffix String suffix = originalFilename.substring(lastIndexOf - 1); //Use UUID to randomly generate file names to prevent files with the same name from being overwritten String fileName = UUID.randomUUID().toString() + suffix; QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName); //Picture uploaded successfully Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS); result.setData(fileName); return result; }catch (Exception e){ e.printStackTrace(); //Picture upload failed return new Result(false,MessageConstant.PIC_UPLOAD_FAIL); } } }
(5) Note: don't forget to upload the component in the spring configuration file
<!--File upload component--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="104857600" /> <property name="maxInMemorySize" value="4096" /> <property name="defaultEncoding" value="UTF-8"/> </bean>
(3) Submit request
(1) Perfect page:
When the user clicks the submit button, he / she calls the handAdd() method to send an ajax request to submit the form data
//add to handleAdd () { axios.post("/setmeal/add.do?checkgroupIds=" + this.checkgroupIds,this.formData). then((response)=> { this.dialogFormVisible = false; if(response.data.flag){ this.$message({ message: response.data.message, type: 'success' }); }else{ this.$message.error(response.data.message); } }).finally(()=> { this.findPage(); }); }
(2) Background code
(1) Layer Controller
//newly added @RequestMapping("/add") public Result add(@RequestBody Setmeal setmeal, Integer[] checkgroupIds){ try { setmealService.add(setmeal,checkgroupIds); }catch (Exception e){ //Failed to add package return new Result(false,MessageConstant.ADD_SETMEAL_FAIL); } //Successfully added package return new Result(true,MessageConstant.ADD_SETMEAL_SUCCESS); }
(2) Service layer
/** * Physical examination package service interface */ public interface SetmealService { public void add(Setmeal setmeal, Integer[] checkgroupIds); }
(3) Service implementation class
/** * Physical examination package service implementation class */ @Service(interfaceClass = SetmealService.class) @Transactional public class SetmealServiceImpl implements SetmealService { @Autowired private SetmealDao setmealDao; //New package public void add(Setmeal setmeal, Integer[] checkgroupIds) { setmealDao.add(setmeal); if(checkgroupIds != null && checkgroupIds.length > 0){ //Many to many relationship between binding package and inspection group setSetmealAndCheckGroup(setmeal.getId(),checkgroupIds); } } //Many to many relationship between binding package and inspection group private void setSetmealAndCheckGroup(Integer id, Integer[] checkgroupIds) { for (Integer checkgroupId : checkgroupIds) { Map<String,Integer> map = new HashMap<>(); map.put("setmeal_id",id); map.put("checkgroup_id",checkgroupId); setmealDao.setSetmealAndCheckGroup(map); } } }
(4) Dao interface:
public interface SetmealDao { public void add(Setmeal setmeal); public void setSetmealAndCheckGroup(Map<String, Integer> map); }
(5) Mapper mapping 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.dao.SetmealDao" > <!--newly added--> <insert id="add" parameterType="com.itheima.pojo.Setmeal"> <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> SELECT LAST_INSERT_ID() </selectKey> insert into t_setmeal (code,name,sex,age,helpCode,price,remark,attention,img) values (#{code},#{name},#{sex},#{age},#{helpCode},#{price},#{remark},# {attention},#{img}) </insert> <!--Bind packages and check group many to many relationships--> <insert id="setSetmealAndCheckGroup" parameterType="hashmap"> insert into t_setmeal_checkgroup (setmeal_id,checkgroup_id) values (#{setmeal_id},#{checkgroup_id}) </insert> </mapper>
II Improve the function of file upload:
Previously, we have completed the file upload and stored the pictures in qiniu cloud server. However, there is a problem in this process, that is, if the user only uploads the picture without finally saving the package information to our database, then the picture we upload will become a garbage picture. For these junk images, we need to clean them regularly to free up disk space. This requires us to be able to distinguish which are spam images and which are not. How to achieve it? The scheme is to use redis to save the picture name. The specific methods are as follows:
1. When the user uploads a picture, the picture name is saved to a Set set of redis, for example, the Set name is setmealPicResources
2. After the user adds a package, save the picture name to another Set of redis, for example, the Set name is setmealPicDbResources
3. Calculate the difference between the setmealPicResources set and the setmealPicDbResources set. The result is the name set of garbage pictures. Clean up these pictures.
Implementation steps:
1. (1) in health_ The Spring configuration file Spring redis.com is provided in the backend project xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/springbeans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/springmvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/springcontext.xsd"> <!--Jedis Related configuration of connection pool--> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal"> <value>200</value> </property> <property name="maxIdle"> <value>50</value> </property> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="true"/> </bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool"> <constructor-arg name="poolConfig" ref="jedisPoolConfig" /> <constructor-arg name="host" value="127.0.0.1" /> <constructor-arg name="port" value="6379" type="int" /> <constructor-arg name="timeout" value="30000" type="int" /> </bean> </beans>
2. (2) in health_ Redis constant class is provided in common project
package com.itheima.constant; public class RedisConstant { //Package picture all picture names public static final String SETMEAL_PIC_RESOURCES = "setmealPicResources"; //Picture name of package picture saved in database public static final String SETMEAL_PIC_DB_RESOURCES = "setmealPicDbResources"; }
3. (3) improve the SetmealController and save the picture name to the redis collection after the file is uploaded successfully
@Autowired private JedisPool jedisPool; //Picture upload @RequestMapping("/upload") public Result upload(@RequestParam("imgFile")MultipartFile imgFile){ try{ //Get original file name String originalFilename = imgFile.getOriginalFilename(); int lastIndexOf = originalFilename.lastIndexOf("."); //Get file suffix String suffix = originalFilename.substring(lastIndexOf - 1); //Use UUID to randomly generate file names to prevent files with the same name from being overwritten String fileName = UUID.randomUUID().toString() + suffix; QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName); //Picture uploaded successfully Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS); result.setData(fileName); //Save the uploaded picture name in Redis and store it in Redis based Set collection jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_RESOURCES,fileName); return result; }catch (Exception e){ e.printStackTrace(); //Picture upload failed return new Result(false,MessageConstant.PIC_UPLOAD_FAIL); } }
4. (4) in health_ service_ The provider project provides the Spring configuration file ApplicationContext redis xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/springbeans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/springmvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/springcontext.xsd"> <!--Jedis Related configuration of connection pool--> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal"> <value>200</value> </property> <property name="maxIdle"> <value>50</value> </property> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="true"/> </bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool"> <constructor-arg name="poolConfig" ref="jedisPoolConfig" /> <constructor-arg name="host" value="127.0.0.1" /> <constructor-arg name="port" value="6379" type="int" /> <constructor-arg name="timeout" value="30000" type="int" /> </bean> </beans>
5. (5) improve the SetmealServiceImpl service class and store the picture name in the redis collection after saving the package information\
@Autowired private JedisPool jedisPool; //New package public void add(Setmeal setmeal, Integer[] checkgroupIds) { setmealDao.add(setmeal); if(checkgroupIds != null && checkgroupIds.length > 0){ setSetmealAndCheckGroup(setmeal.getId(),checkgroupIds); } //Save the picture name to Redis savePic2Redis(setmeal.getImg()); } //Save the picture name to Redis private void savePic2Redis(String pic){ jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,pic); }
Three. Delete the check package information , delete the check package information according to the id , and delete the check group id associated with the package according to the package id ,;
(1) Page:
deleteById(row){ this.$confirm( "Are you sure you want to delete the current data" ,"Tips" , {//Confirmation box type: 'warning' }).then(()=>{ //The user clicks the OK button and sends an ajax request to submit the inspection item id to the Controller for processing axios.delete("/setmeal/delete.do?id="+row.id).then((res)=>{ if(res.data.flag){ //Successful execution //Pop up prompt success message this.$message({ type:'success', message:res.data.message }); //Re query this.findPage(); }else{ //Execution failed this.$message.error(res.data.message); } }).catch((res)=>{ this.showMessage(res); }); }).catch(()=>{ this.$message({ type:'info', message:'Operation cancelled' }); }) }
(2) Background code:
1.Controller layer:
//Delete the package according to the package id and delete the many to many relationship table of the inspection group of the package; @DeleteMapping("/delete") public Result delete(Integer id){ try { setmealService.delete(id); return new Result(true,MessageConstant.DELETE_SETMEAL_SUCCESS); } catch (Exception e) { e.printStackTrace(); return new Result(true,MessageConstant.DELETE_SETMEAL_FAIL); } }
2.Service layer:
void delete(Integer id);
3. Service realization:
@Override //Delete the package and clear the many to many correspondence table between the package and the inspection group according to the package id public void delete(Integer id) { setmealDao.deleteAssocication(id); setmealDao.delete(id); }
4.Dao interface:
void delete(Integer id);
5.Mapper.xml:
<!-- According to the package id Delete the relationship between package and inspection group--> <delete id="deleteAssocication"> delete from t_setmeal_checkgroup where setmeal_id = #{id} </delete> <!-- According to the package id Delete package --> <delete id="delete"> delete from t_setmeal where id = #{id} </delete>