2.3 后台代码
2.3.1 Controller
在SetmealController中增加方法
//新增 @RequestMapping("/add") public Result add(@RequestBody Setmeal setmeal, Integer[] checkgroupIds){ try { setmealService.add(setmeal,checkgroupIds); }catch (Exception e){ //新增套餐失败 return new Result(false,MessageConstant.ADD_SETMEAL_FAIL); } //新增套餐成功 return new Result(true,MessageConstant.ADD_SETMEAL_SUCCESS); }
2.3.2 服务接口
创建SetmealService接口并提供新增方法
package com.itheima.service; import com.itheima.entity.PageResult; import com.itheima.pojo.CheckGroup; import com.itheima.pojo.Setmeal; import java.util.List; /** * 体检套餐服务接口 */ public interface SetmealService { public void add(Setmeal setmeal, Integer[] checkgroupIds); }
2.3.3 服务实现类
创建SetmealServiceImpl服务实现类并实现新增方法
package com.itheima.service; import com.alibaba.dubbo.config.annotation.Service; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.itheima.dao.SetmealDao; import com.itheima.entity.PageResult; import com.itheima.pojo.Setmeal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 体检套餐服务实现类 */ @Service(interfaceClass = SetmealService.class) @Transactional public class SetmealServiceImpl implements SetmealService { @Autowired private SetmealDao setmealDao; //新增套餐 public void add(Setmeal setmeal, Integer[] checkgroupIds) { setmealDao.add(setmeal); if(checkgroupIds != null && checkgroupIds.length > 0){ //绑定套餐和检查组的多对多关系 setSetmealAndCheckGroup(setmeal.getId(),checkgroupIds); } } //绑定套餐和检查组的多对多关系 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); } } }
2.3.4 Dao接口
创建SetmealDao接口并提供相关方法
package com.itheima.dao; import com.itheima.pojo.Setmeal; import java.util.Map; public interface SetmealDao { public void add(Setmeal setmeal); public void setSetmealAndCheckGroup(Map<String, Integer> map); }
2.3.5 Mapper映射文件
创建SetmealDao.xml文件并定义相关SQL语句
<?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" > <!--新增--> <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> <!--绑定套餐和检查组多对多关系--> <insert id="setSetmealAndCheckGroup" parameterType="hashmap"> insert into t_setmeal_checkgroup (setmeal_id,checkgroup_id) values (#{setmeal_id},#{checkgroup_id}) </insert> </mapper>
2.4 完善文件上传
前面我们已经完成了文件上传,将图片存储在了七牛云服务器中。但是这个过程存在一个问题,就是如果用户只上传了图片而没有最终保存套餐信息到我们的数据库,这时我们上传的图片就变为了垃圾图片。对于这些垃圾图片我们需要定时清理来释放磁盘空间。这就需要我们能够区分出来哪些是垃圾图片,哪些不是垃圾图片。如何实现呢?
方案就是利用redis来保存图片名称,具体做法为:
1、当用户上传图片后,将图片名称保存到redis的一个Set集合中,例如集合名称为setmealPicResources
2、当用户添加套餐后,将图片名称保存到redis的另一个Set集合中,例如集合名称为setmealPicDbResources
3、计算setmealPicResources集合与setmealPicDbResources集合的差值,结果就是垃圾图片的名称集合,清理这些图片即可
diff
redis set diff(多的集合,少的集合)= 垃圾图片的集合
本小节我们先来完成前面2个环节,第3个环节(清理图片环节)在后面会通过定时任务再实现。
实现步骤:
(1)在health_backend项目中提供Spring配置文件spring-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/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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/spring-context.xsd"> <!--Jedis连接池的相关配置--> <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)在health_common工程中提供Redis常量类
package com.itheima.constant; public class RedisConstant { //套餐图片所有图片名称 public static final String SETMEAL_PIC_RESOURCES = "setmealPicResources"; //套餐图片保存在数据库中的图片名称 public static final String SETMEAL_PIC_DB_RESOURCES = "setmealPicDbResources"; }
(3)完善SetmealController,在文件上传成功后将图片名称保存到redis集合中
@Autowired private JedisPool jedisPool; //图片上传 @RequestMapping("/upload") public Result upload(@RequestParam("imgFile")MultipartFile imgFile){ try{ //获取原始文件名 String originalFilename = imgFile.getOriginalFilename(); int lastIndexOf = originalFilename.lastIndexOf("."); //获取文件后缀 String suffix = originalFilename.substring(lastIndexOf - 1); //使用UUID随机产生文件名称,防止同名文件覆盖 String fileName = UUID.randomUUID().toString() + suffix; QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName); //图片上传成功 Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS); result.setData(fileName); //将上传图片名称存入Redis,基于Redis的Set集合存储 jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_RESOURCES,fileName); return result; }catch (Exception e){ e.printStackTrace(); //图片上传失败 return new Result(false,MessageConstant.PIC_UPLOAD_FAIL); } }
(4)在health_service_provider项目中提供Spring配置文件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/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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/spring-context.xsd"> <!--Jedis连接池的相关配置--> <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)完善SetmealServiceImpl服务类,在保存完成套餐信息后将图片名称存储到redis集合中
@Autowired private JedisPool jedisPool; //新增套餐 public void add(Setmeal setmeal, Integer[] checkgroupIds) { setmealDao.add(setmeal); if(checkgroupIds != null && checkgroupIds.length > 0){ setSetmealAndCheckGroup(setmeal.getId(),checkgroupIds); } //将图片名称保存到Redis savePic2Redis(setmeal.getImg()); } //将图片名称保存到Redis private void savePic2Redis(String pic){ jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,pic); }
小结
- elementUI 图片上传组件
<!-- 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>
- MultipartFile接收文件
- dubbo服务不能接受MultipartFile作为参数
- redis的使用,一般使用jedis来操作redis
- jedisPool.getResource().sadd(), redis的数据类型:Set集合,去重
redis 127.0.0.1:6379> SADD myset "hello" (integer) 1 redis 127.0.0.1:6379> SADD myset "foo" (integer) 1 redis 127.0.0.1:6379> SADD myset "hello" (integer) 0 redis 127.0.0.1:6379> SMEMBERS myset 1) "hello" 2) "foo"
3. 体检套餐分页
3.1 完善页面
3.1.1 定义分页相关模型数据
pagination: {//分页相关模型数据 currentPage: 1,//当前页码 pageSize:10,//每页显示的记录数 total:0,//总记录数 queryString:null//查询条件 }, dataList: [],//当前页要展示的分页列表数据
3.1.2 定义分页方法
在页面中提供了findPage方法用于分页查询,为了能够在setmeal.html页面加载后直接可以展示分页数据,可以在VUE提供的钩子函数created中调用findPage方法
//钩子函数,VUE对象初始化完成后自动执行 created() { this.findPage(); } //分页查询 findPage() { //分页参数 var param = { currentPage:this.pagination.currentPage,//页码 pageSize:this.pagination.pageSize,//每页显示的记录数 queryString:this.pagination.queryString//查询条件 }; //请求后台 axios.post("/setmeal/findPage.do",param).then((response)=> { //为模型数据赋值,基于VUE的双向绑定展示到页面 this.dataList = response.data.rows; this.pagination.total = response.data.total; }); }
3.1.3 完善分页方法执行时机
除了在created钩子函数中调用findPage方法查询分页数据之外,当用户点击查询按钮或者点击分页条中的页码时也需要调用findPage方法重新发起查询请求。
为查询按钮绑定单击事件,调用findPage方法
<el-button @click="findPage()" class="dalfBut">查询</el-button>
为分页条组件绑定current-change事件,此事件是分页条组件自己定义的事件,当页码改变时触发,对应的处理函数为handleCurrentChange
<el-pagination class="pagiantion" @current-change="handleCurrentChange" :current-page="pagination.currentPage" :page-size="pagination.pageSize" layout="total, prev, pager, next, jumper" :total="pagination.total"> </el-pagination>
定义handleCurrentChange方法
//切换页码 handleCurrentChange(currentPage) { //currentPage为切换后的页码 this.pagination.currentPage = currentPage; this.findPage(); }
3.2 后台代码
3.2.1 Controller
在SetmealController中增加分页查询方法
//分页查询 @RequestMapping("/findPage") public PageResult findPage(@RequestBody QueryPageBean queryPageBean){ PageResult pageResult = setmealService.pageQuery( queryPageBean.getCurrentPage(), queryPageBean.getPageSize(), queryPageBean.getQueryString() ); return pageResult; }
3.2.2 服务接口
在SetmealService服务接口中扩展分页查询方法
public PageResult pageQuery(Integer currentPage, Integer pageSize, String queryString);
3.2.3 服务实现类
在SetmealServiceImpl服务实现类中实现分页查询方法,基于Mybatis分页助手插件实现分页
public PageResult pageQuery(Integer currentPage, Integer pageSize, String queryString) { PageHelper.startPage(currentPage,pageSize); Page<CheckItem> page = checkGroupDao.selectByCondition(queryString); return new PageResult(page.getTotal(),page.getResult()); }
3.2.4 Dao接口
在SetmealDao接口中扩展分页查询方法
public Page<Setmeal> selectByCondition(String queryString); public Page<Setmeal> selectByCondition(@Param("queryString") String queryString);
3.2.5 Mapper映射文件
在SetmealDao.xml文件中增加SQL定义
<!--根据条件查询--> <select id="selectByCondition" parameterType="string" resultType="com.itheima.pojo.Setmeal"> select * from t_setmeal <if test="value != null and value.length > 0"> where code = #{value} or name = #{value} or helpCode = #{value} </if> </select>
4. 定时任务组件Quartz
Quartz定时任务组件:https://blog.csdn.net/ZGL_cyy/article/details/111935988