套餐其实就是检查组的集合,例如有一个套餐为“入职体检套餐”,这个体检套餐可以包括多个检查组:一般检查、血常规、尿常规、肝功三项等。所以在添加套餐时需要选择这个套餐包括的检查组。
套餐对应的实体类为Setmeal,对应的数据表为t_setmeal。套餐和检查组为多对多关系,所以需要中间表t_setmeal_checkgroup进行关联。
前端页面
弹出新增套餐页面功能
表单重置和默认选择tab项功能
动态列表显示检查组列表
在前端动态显示列表,就进行一个tableData的遍历即可,前端发送ajax请求到后台查询所有的记录并赋值给tableData,前端在对tableData进行处理
Controller
Service
ServiceImpl
Dao
Mapper
xml文件中的SQL语句,如果是查询所有数据,那么前端就不用传任何参数,只需发送一个get请求,sql语句中也不用写parameterType,只需要一个返回参数类型
<!-- 查询所有检查组-->
<select id="findAll" resultType="com.itheima.pojo.CheckGroup">
select * from t_checkgroup
</select>
parameterType="String" //查询是具有参数的,这个参数的类型是String
resultType="com.itheima.pojo.CheckGroup" //查询返回的参数类型
图片上传预览
此处使用的是ElementUI提供的上传组件el-upload,提供了多种不同的上传效果,上传成功后可以进行预览。
<!--
el-upload:上传组件
action:上传的提交地址
auto-upload:选中文件后是否自动上传
name:上传文件的名称,服务端可以根据名称获得上传的文件对象
show-file-list:是否显示已上传文件列表
on-success:文件上传成功时的钩子
before-upload:上传文件之前的钩子
-->
上传之前需要检验
//上传图片之前执行
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;
},
上传成功后,将图片的网络链接值赋给imageUr,imageUrll的值不为空,v-if条件成立,则显示图片的预览图
//文件上传成功后的钩子,response为服务端返回的值,file为当前上传的文件封装成的js对象
handleAvatarSuccess(response, file) {
this.imageUrl = 'http://rtb9a5bgc.hn-bkt.clouddn.com/' + response.data;
this.$message({
message: response.message,
type: response.flag ? 'success' : 'error'
});
//设置模型数据(图片名称),后续提交ajax请求时会提交到后台最终保存到数据库
this.formData.img = response.data;
},
Controller
springmvc中需要设置一个文件上传的组件
<!--文件上传组件-->
<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>
之前设置的七牛云图片上传工具类中设置了两种图片上传方法,使用byte数组上传方法
//文件上传
//图片上传
@RequestMapping("/upload")
public Result upload(@RequestParam("imgFile") MultipartFile imgFile){//使用springmvc的上传组件来上传文件,后台接收到文件
System.out.println(imgFile);
//获取原始文件名
String originalFilename = imgFile.getOriginalFilename();
int lastIndexOf = originalFilename.lastIndexOf(".");
//获取文件后缀
String suffix = originalFilename.substring(lastIndexOf - 1);
//使用UUID随机产生文件名称,防止同名文件覆盖
String fileName = UUID.randomUUID().toString() + suffix;
try {
QiniuUtils.upload2Qiniu(imgFile.getBytes(), fileName);//使用七牛云工具类的bytes数组上传文件方法,第二个参数为文件名
//图片上传成功
Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS);
result.setData(fileName);
return result;
} catch (IOException e) {
e.printStackTrace();
//图片上传失败
return new Result(false, MessageConstant.PIC_UPLOAD_FAIL);
}
}
完善新增套餐_提交表单
前端代码
//添加
handleAdd () {
//发送ajax请求,将表单数据(套餐信息,检查组ID)提交到后台进行处理
axios.post("/setmeal/add.do?checkgroupIds=" + this.checkgroupIds,this.formData).then((res) =>{
this.dialogFormVisible = false;
if(res.data.flag){//本次操作成功,controller成功响应
this.$message({
message: res.data.message,
type: 'success'
});
}else{
this.$message.error(res.data.message);
}
}).finally(()=> {//本次操作失败
this.findPage();
});
},
后台代码
完善图片上传
清理垃圾图片,释放磁盘空间
利用redis来保存图片名称,具体做法为:
1、当用户上传图片后,将图片名称保存到redis的一个Set集合中,例如集合名称为setmealPicResources
2、当用户添加套餐后,将图片名称保存到redis的另一个Set集合中,例如集合名称为setmealPicDbResources
3、计算setmealPicResources集合与setmealPicDbResources集合的差值,结果就是垃圾图片的名称集合,清理这些图片即可
配置好配置文件中,记得在springmvc.xml中引用
<import resource="spring-redis.xml"></import>
在health_common工程中提供Redis常量类
完善SetmealController,在文件上传成功后将图片名称保存到redis集合中
在health_service_provider项目中提供Spring配置文件applicationContext-redis.xml
查看是否能扫描到配置文件
完善SetmealServiceImpl服务类,在保存完成套餐信息后将图片名称存储到redis集合中
//将图片名称保存到Redis
savePic2Redis(setmeal.getImg());
}
//将图片名称保存到Redis
private void savePic2Redis(String pic){
jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,pic);
}
定时任务组件Quartz
Quartz是Job scheduling(作业调度)领域的一个开源项目,Quartz既可以单独使用也可以跟spring框架整合使用,在实际开发中一般会使用后者。使用Quartz可以开发一个或者多个定时任务,每个定时任务可以单独指定执行的时间,例如每隔1小时执行一次、每个月第一天上午10点执行一次、每个月最后一天下午5点执行一次等。
pom文件中导入坐标
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
自定义一个job
提供Spring配置文件spring-jobs.xml,配置自定义Job、任务描述、触发器、调度工厂等
<!-- 注册自定义Job -->
<bean id="jobDemo" class="com.itheima.jobs.JobDemo"></bean>
<!-- 注册JobDetail,作用是负责通过反射调用指定的Job -->
<bean id="jobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 注入目标对象 -->
<property name="targetObject" ref="jobDemo"/>
<!-- 注入目标方法 -->
<property name="targetMethod" value="run"/>
</bean>
<!-- 注册一个触发器,指定任务触发的时间 -->
<bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 注入JobDetail -->
<property name="jobDetail" ref="jobDetail"/>
<!-- 指定触发的时间,基于Cron表达式 -->
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
</bean>
<!-- 注册一个统一的调度工厂,通过这个调度工厂调度任务 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 注入多个触发器 -->
<property name="triggers">
<list>
<ref bean="myTrigger"/>
</list>
</property>
</bean>
编写一个main方法来测试
Cron表达式
cron表达式分为七个域,之间使用空格分隔。其中最后一个域(年)可以为空。每个域都有自己允许的值和一些特殊字符构成。使用这些特殊字符可以使我们定义的表达式更加灵活。
下面是对这些特殊字符的介绍:
逗号(,):指定一个值列表,例如使用在月域上1,4,5,7表示1月、4月、5月和7月
横杠(-):指定一个范围,例如在时域上3-6表示3点到6点(即3点、4点、5点、6点)
星号(*):表示这个域上包含所有合法的值。例如,在月份域上使用星号意味着每个月都会触发
斜线(/):表示递增,例如使用在秒域上0/15表示每15秒
问号(?):只能用在日和周域上,但是不能在这两个域上同时使用。表示不指定
井号(#):只能使用在周域上,用于指定月份中的第几周的哪一天,例如6#3,意思是某月的第三个周五 (6=星期五,3意味着月份中的第三周)
L:某域上允许的最后一个值。只能使用在日和周域上。当用在日域上,表示的是在月域上指定的月份的最后一天。用于周域上时,表示周的最后一天,就是星期六
W:W 字符代表着工作日 (星期一到星期五),只能用在日域上,它用来指定离指定日的最近的一个工作日
cron表达式在线生成器
在线Cron表达式生成器
利用Quartz实现定时清理垃圾图片
创建maven工程health_jobs,打包方式为war,导入Quartz等相关坐标
导入坐标
配置web.xml
配置log4j.properties
配置applicationContext-redis.xml
配置applicationContext-jobs.xml
创建ClearImgJob定时任务类
套餐分页查询
定义分页相关的模型数据
pagination: {//分页相关模型数据
currentPage: 1,//当前页码
pageSize:10,//每页显示的记录数
total:0,//总记录数
queryString:null//查询条件
},
dataList: [],//当前页要展示的分页列表数据
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;
});
}
时机:钩子函数,查询按钮,分页条组件
后端开发同检查组后台开发