1. 图片存储方案
七牛云存储图片服务器使用:https://blog.csdn.net/ZGL_cyy/article/details/111935958
2. 新增套餐
2.1 需求分析
套餐其实就是检查组的集合,例如有一个套餐为“入职体检套餐”,这个体检套餐可以包括多个检查组:一般检查、血常规、尿常规、肝功三项等。所以在添加套餐时需要选择这个套餐包括的检查组。
套餐对应的实体类为Setmeal,对应的数据表为t_setmeal。套餐和检查组为多对多关系,所以需要中间表t_setmeal_checkgroup进行关联。
一个套餐 有多个检查组,一个检查组又有多个检查项
2.2 完善页面
套餐管理页面对应的是setmeal.html页面,根据产品设计的原型已经完成了页面基本结构的编写,现在需要完善页面动态效果。
2.2.1 弹出新增窗口
页面中已经提供了新增窗口,只是出于隐藏状态。只需要将控制展示状态的属性dialogFormVisible改为true接口显示出新增窗口。点击新建按钮时绑定的方法为handleCreate,所以在handleCreate方法中修改dialogFormVisible属性的值为true即可。同时为了增加用户体验度,需要每次点击新建按钮时清空表单输入项。
由于新增套餐时还需要选择此套餐包含的检查组,所以新增套餐窗口分为两部分信息:基本信息和检查组信息,如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AJ2RFCAw-1609427434542)(img/3.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g10YjD93-1609427434554)(img/4.png)]
新建按钮绑定单击事件,对应的处理函数为handleCreate
<el-button type="primary" class="butT" @click="handleCreate()">新建</el-button> // 重置表单 resetForm() { this.formData = {}; this.activeName='first'; this.checkgroupIds = []; this.imageUrl = null; } // 弹出添加窗口 handleCreate() { this.dialogFormVisible = true; this.resetForm(); }
2.2.2 动态展示检查组列表
现在虽然已经完成了新增窗口的弹出,但是在检查组信息标签页中需要动态展示所有的检查组信息列表数据,并且可以进行勾选。具体操作步骤如下:
(1)定义模型数据
tableData:[],//添加表单窗口中检查组列表数据 checkgroupIds:[],//添加表单窗口中检查组复选框对应id
(2)动态展示检查组列表数据,数据来源于上面定义的tableData模型数据
<table class="datatable"> <thead> <tr> <th>选择</th> <th>项目编码</th> <th>项目名称</th> <th>项目说明</th> </tr> </thead> <tbody> <tr v-for="c in tableData"> <td> <input :id="c.id" v-model="checkgroupIds" type="checkbox" :value="c.id"> </td> <td><label :for="c.id">{{c.code}}</label></td> <td><label :for="c.id">{{c.name}}</label></td> <td><label :for="c.id">{{c.remark}}</label></td> </tr> </tbody> </table>
(3)完善handleCreate方法,发送ajax请求查询所有检查组数据并将结果赋值给tableData模型数据用于页面表格展示
// 弹出添加窗口 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); } }); }
(4)分别在CheckGroupController、CheckGroupService、CheckGroupServiceImpl、CheckGroupDao、CheckGroupDao.xml中扩展方法查询所有检查组数据
CheckGroupController:
//查询所有 @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); }
CheckGroupService:
List<CheckGroup> findAll();
CheckGroupServiceImpl:
public List<CheckGroup> findAll() { return checkGroupDao.findAll(); }
CheckGroupDao:
List<CheckGroup> findAll();
CheckGroupDao.xml:
<select id="findAll" resultType="com.itheima.pojo.CheckGroup"> select * from t_checkgroup </select>
大作业:
1. 查询所有检查组 1. redis 2. 新增 编辑检查组的时候,更新redis中的数据 2. 查询所有检查项 1. redis 2. 新增 编辑检查组的时候,更新redis中的数据
2.2.3 图片上传并预览
此处使用的是ElementUI提供的上传组件el-upload,提供了多种不同的上传效果,上传成功后可以进行预览。
实现步骤:
(1)定义模型数据,用于后面上传文件的图片预览:
imageUrl:null,//模型数据,用于上传图片完成后图片预览
(2)定义上传组件:
<!-- el-upload:上传组件 action:上传的提交地址 auto-upload:选中文件后是否自动上传 name:上传文件的名称,服务端可以根据名称获得上传的文件对象 show-file-list:是否显示已上传文件列表 on-success:文件上传成功时的钩子 before-upload:上传文件之前的钩子 --> <el-upload class="avatar-uploader" action="/setmeal/upload.do" :auto-upload="autoUpload" name="imgFile" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <!--用于上传图片预览--> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <!--用于展示上传图标--> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload>
(3)定义对应的钩子函数:
//文件上传成功后的钩子,response为服务端返回的值,file为当前上传的文件封装成的js对象 handleAvatarSuccess(response, file) { this.imageUrl = "http://pqjroc654.bkt.clouddn.com/"+response.data; this.$message({ message: response.message, type: response.flag ? 'success' : 'error' }); //设置模型数据(图片名称),后续提交ajax请求时会提交到后台最终保存到数据库 this.formData.img = response.data; } //上传文件之前的钩子 beforeAvatarUpload(file) { const isJPG = file.type === 'image/jpeg'; const isLt2M = file.size / 1024 / 1024 < 2; if (!isJPG) { this.$message.error('上传套餐图片只能是 JPG 格式!'); } if (!isLt2M) { this.$message.error('上传套餐图片大小不能超过 2MB!'); } return isJPG && isLt2M; }
(4)创建SetmealController,接收上传的文件
package com.itheima.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.itheima.constant.MessageConstant; import com.itheima.entity.PageResult; import com.itheima.entity.QueryPageBean; import com.itheima.entity.Result; import com.itheima.pojo.CheckGroup; import com.itheima.pojo.Setmeal; import com.itheima.service.CheckGroupService; import com.itheima.service.SetmealService; import com.itheima.utils.QiniuUtils; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.util.List; import java.util.UUID; /** * 套餐管理 */ @RestController @RequestMapping("/setmeal") public class SetmealController { @Reference private SetmealService setmealService; //图片上传 @RequestMapping("/upload") public Result upload(@RequestParam("imgFile")MultipartFile imgFile){ try{ //获取原始文件名 String originalFilename = imgFile.getOriginalFilename(); int lastIndexOf = originalFilename.lastIndexOf("."); //获取文件后缀 String suffix = originalFilename.substring(lastIndexOf); //使用UUID随机产生文件名称,防止同名文件覆盖 String fileName = UUID.randomUUID().toString() + suffix; QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName); //图片上传成功 Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS); result.setData(fileName); return result; }catch (Exception e){ e.printStackTrace(); //图片上传失败 return new Result(false,MessageConstant.PIC_UPLOAD_FAIL); } } }
注意:别忘了在spring配置文件中配置文件上传组件
<!--文件上传组件--> <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>
2.2.4 提交请求
当用户点击新增窗口中的确定按钮时发送ajax请求将数据提交到后台进行数据库操作。提交到后台的数据分为两部分:套餐基本信息(对应的模型数据为formData)和检查组id数组(对应的模型数据为checkgroupIds)。
为确定按钮绑定单击事件,对应的处理函数为handleAdd
el-button type="primary" @click="handleAdd()">确定</el-button>
完善handleAdd方法
//添加 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(); }); }