启动器
bash
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency
存放的都是版本号
一,分页查询

点击检查项就会弹出所有的检查项
前台 传出 param
bash
currentPage: this.pagination.currentPage, // 第1个:当前页码
pageSize: this.pagination.pageSize, // 第2个:每页条数
queryString: this.pagination.queryString // 第3个:搜索关键词
后台需要返回
bash
this.dataList = res.rows; // 当前页展示的数据集合
this.pagination.total = res.total; // 总数数据量
后端:
Controller层
javascript
/**
* 分页查询
* @param queryPageBean 查询条件
* @return
*/
@RequestMapping("/findPage")
public PageResult findPage(@RequestBody QueryPageBean queryPageBean) {
// 直接从 queryPageBean 里取 queryString 作为查询参数
return checkGroupService.findPage(queryPageBean, queryPageBean.getQueryString());
}
service:
javascript
@Override//分页查询检查组
public PageResult findPage(QueryPageBean queryPageBean, String param) {
// this.pagination.currentPage, 当前页码
// this.pagination.pageSize, 每页显示多少条数据
PageHelper.startPage(queryPageBean.getCurrentPage(),queryPageBean.getPageSize());
// 查询总记录数
List<CheckGroup> checkGroupList = checkGroupMapper.findPage(queryPageBean,param);
// 分页查询
// PageInfo 封装了分页信息
PageInfo pageInfo =new PageInfo(checkGroupList);
// 封装PageResult
return new PageResult(pageInfo.getTotal(),pageInfo.getList());
// 返回分页结果
}
mapper :省略
二,查询检查组

bash
@RequestMapping("/findAll")
public Result findAll(){
try {
List<CheckGroup> checkGroups = checkGroupService.findAll();
return new Result(true, MessageConstant.QUERY_CHECKGROUP_SUCCESS,checkGroups);
}catch (Exception e){
return new Result(false, MessageConstant.QUERY_CHECKGROUP_FAIL);
}
}
三,一对多


先获取前端 检查项的 [id ]
javascript
/**
* 添加检查组
* @param checkGroup
* @param checkitemIds
* @return
*/
@RequestMapping("/add")
public Result add(@RequestBody CheckGroup checkGroup, Integer[] checkitemIds) {
try {
checkGroupService.add(checkGroup, checkitemIds);
return new Result(true, MessageConstant.ADD_CHECKGROUP_SUCCESS);//添加成功
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.ADD_CHECKGROUP_FAIL);//添加失败
}
}
javascript
@Override//添加检查组
public void add(CheckGroup checkGroup, Integer[] checkitemIds) {
try {
//添加检查组
checkGroupMapper.add(checkGroup);
//添加检查组和检查项的关联关系
if (checkitemIds != null && checkitemIds.length > 0) {
Integer checkGroupId = checkGroup.getId();
setCheckGroupAndCheckItem(checkGroupId, checkitemIds);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override //添加检查组和检查项的关联关系 关联表
public void setCheckGroupAndCheckItem(Integer checkGroupId, Integer[] checkitemIds){
checkGroupMapper.deleteCheckItemByCheckGroupId(checkGroupId);
for (Integer checkitemId : checkitemIds) {
List<Object> checkitemIdList = new ArrayList<>();
checkitemIdList.add(checkitemId);
checkGroupMapper.setCheckGroupAndCheckItem(checkGroupId,checkitemIdList);
}
}
javascript
void add( CheckGroup checkGroup); //必须需要主键回填
//关联表
void setCheckGroupAndCheckItem(@Param("checkGroupId") Integer checkGroupId, @Param("checkitemIdList") List<Object> checkitemIdList);
四图片上传 + 过期自动删除

图片上传服务器事件

bash
editFormData: {},
//新增表单窗口中检查组列表数据
前端

后端:
添加sql数据
javascript
/**
* 添加套餐
*/
@RequestMapping("/add")
public Result add(@RequestBody SetmealDTO dto) {
try {
// 将DTO转为Setmeal对象
Setmeal setmeal = new Setmeal();
setmeal.setName(dto.getName());
setmeal.setCode(dto.getCode());
setmeal.setHelpCode(dto.getHelpCode());
setmeal.setSex(dto.getSex());
setmeal.setAge(dto.getAge());
setmeal.setPrice(dto.getPrice());
setmeal.setRemark(dto.getRemark());
setmeal.setAttention(dto.getAttention());
setmeal.setImg(dto.getImg());
List<Integer> ids = dto.getCheckgroupIds();
Integer[] checkgroupIds = ids != null ? ids.toArray(new Integer[0]) : new Integer[0];
setmealService.add(setmeal, checkgroupIds);
if (setmeal.getImg() != null) {
// 上传图片 添加一个集合当中 eg:readis
redisClient.sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES, setmeal.getImg());
}
return new Result(true, MessageConstant.ADD_SETMEAL_SUCCESS);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.ADD_SETMEAL_FAIL);
}
}
图片上传服务器
javascript
/**
* 上传图片
*/
@RequestMapping("/upload")
public Result upload(MultipartFile imgFile) {
try {
// 生成文件名
String originalFilename = imgFile.getOriginalFilename();//得到图片名字.jpg/.png
String endfile = originalFilename.substring(originalFilename.lastIndexOf("."));//获取文件后缀名
String fileName = UUID.randomUUID() + endfile;//生成随机文件名
QiniuUtils.upload2Qiniu(imgFile.getBytes(), fileName); //上传到服务器
redisClient.sadd(RedisConstant.SETMEAL_PIC_RESOURCES, fileName); //添加到Redis
return new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS, fileName);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.PIC_UPLOAD_FAIL);
}
}
servlce
java
//同理 关联表添加
@Override
public void add(Setmeal setmeal, Integer[] checkgroupIds) {
setmealMapper.add(setmeal);
setmealCheckgroupIds(setmeal, checkgroupIds);
}
private void setmealCheckgroupIds(Setmeal setmeal, Integer[] checkgroupIds) {
if (checkgroupIds != null && checkgroupIds.length > 0) {
Integer setmealId = setmeal.getId();
for (Integer checkgroupId : checkgroupIds) {
setmealMapper.addSetmealAndCheckItem(setmealId, checkgroupId);
}
}
}
过期照片定时清理
工具类
java
package com.yunkukukukuku.util;
import com.yunkukukukuku.jop.DeleteJobImg;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
* 定时任务
*/
@Configuration
public class QuartzUtil {
/**
* 配置任务详情:绑定 任务类 + 执行方法
*/
@Bean
public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean(DeleteJobImg deleteJobImg) {
MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
// 绑定我们自己写的任务类
methodInvokingJobDetailFactoryBean.setTargetObject(deleteJobImg);
// 绑定要执行的方法名
methodInvokingJobDetailFactoryBean.setTargetMethod("deleteImg");
// 允许并发执行
methodInvokingJobDetailFactoryBean.setConcurrent(false);// 默认为 true
return methodInvokingJobDetailFactoryBean;
}
/**
* 配置触发器:设置 Cron 表达式
*/
@Bean
public CronTriggerFactoryBean cronTrigger(MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean) {
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(methodInvokingJobDetailFactoryBean.getObject());
// 每5秒执行一次
trigger.setCronExpression("* */1 * * * ?");
return trigger;
}
/**
* 配置调度器:启动定时任务
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTrigger) {
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setTriggers(cronTrigger.getObject());
// 项目启动时自动启动调度器
scheduler.setAutoStartup(true);
return scheduler;
}
}
jop 定时清理
java
package com.yunkukukukuku.jop;
import com.yunkukukukuku.constant.RedisConstant;
import com.yunkukukukuku.util.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Set;
/**
* 定时任务
*/
@Component
public class DeleteJobImg {
@Autowired
private RedisClient redisClient;//缓存服务层
public void deleteImg() {
try {
Set<Object> sdiffer = redisClient.sdiffer(RedisConstant.SETMEAL_PIC_RESOURCES, RedisConstant.SETMEAL_PIC_DB_RESOURCES);
if (sdiffer != null && !sdiffer.isEmpty()) {
for (Object imgname : sdiffer) {
//删除图片
redisClient.srem(RedisConstant.SETMEAL_PIC_DB_RESOURCES, imgname);
//删除图片
redisClient.srem(RedisConstant.SETMEAL_PIC_RESOURCES, imgname);
}
}
} catch (Exception e) {
System.err.println("清理图片失败:" + e.getMessage());
e.printStackTrace();
}
}
}
图片清理过程
java
项目启动
↓
Spring 加载 QuartzUtil 配置类
↓
创建 SchedulerFactoryBean(调度器)
↓
注册 CronTrigger(触发器,每分钟执行)
↓
绑定 MethodInvokingJobDetailFactoryBean
↓
自动调用 DeleteJobImg.deleteImg()
五,

java
const submitData = {
...this.editFormData,
checkgroupIds: this.editCheckgroupIds
};
//发送ajax请求,根据检查组ID查询当前检查组数据,用于基本信息的回显
this.$ajax.post("/setmeal/edit", submitData).then((res) => {
//发送ajax请求,查询所有的检查项数据,用于展示检查项列表
this.$ajax.get("/checkgroup/findAll").then((res) => { {//省略
//发送ajax请求,根据检查组ID查询当前检查组包含的检查项ID,用于页面复选框回显
this.$ajax.get("/setmeal/findCheckGroupIdsBySetmealId?id=" + row.id).then((res2) => {
java
@RequestMapping("/edit")
public Result edit(@RequestBody SetmealDTO dto) {
try {
// 将DTO转为Setmeal对象
Setmeal setmeal = new Setmeal();
setmeal.setId(dto.getId());
setmeal.setName(dto.getName());
setmeal.setCode(dto.getCode());
setmeal.setHelpCode(dto.getHelpCode());
setmeal.setSex(dto.getSex());
setmeal.setAge(dto.getAge());
setmeal.setPrice(dto.getPrice());
setmeal.setRemark(dto.getRemark());
setmeal.setAttention(dto.getAttention());
setmeal.setImg(dto.getImg());
List<Integer> ids = dto.getCheckgroupIds();
Integer[] checkgroupIds = ids != null ? ids.toArray(new Integer[0]) : new Integer[0];
setmealService.edit(setmeal, checkgroupIds);
if (setmeal.getImg() != null) {
redisClient.sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES, setmeal.getImg());
}
return new Result(true, "编辑套餐成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "编辑套餐失败");
}
}
java
@RequestMapping("/findCheckGroupIdsBySetmealId")
public Result findCheckGroupIdsBySetmealId(Integer id) {
try {
List<Integer> checkgroupIds = setmealService.findCheckGroupIdsBySetmealId(id);
return new Result(true, MessageConstant.QUERY_SETMEAL_SUCCESS, checkgroupIds);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.QUERY_CHECKGROUP_FAIL);
}
}
service
java
// 异常处理示例
public class ExceptionHandling {
public static void main(String[] args) {
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero");
}
}
}
sql
java
<insert id="addSetmealAndCheckItem" >
insert into t_setmeal_checkgroup(setmeal_id, checkgroup_id)
values (#{setmealId}, #{checkgroupId})
</insert>
<update id="edit">
update t_setmeal
<set>
<if test="name != null">name = #{name},</if>
<if test="code != null">code = #{code},</if>
<if test="helpCode != null">helpCode = #{helpCode},</if>
<if test="sex != null">sex = #{sex},</if>
<if test="age != null">age = #{age},</if>
<if test="price != null">price = #{price},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="attention != null">attention = #{attention},</if>
<if test="img != null">img = #{img},</if>
</set>
where id = #{id}
</update>
java
┌─────────────────────────────────────────────────┐
│ 1. 查套餐详情(图片 + 基础信息) │
│ POST /setmeal/findById → 表单回填 + 图片显示 │
├─────────────────────────────────────────────────┤
│ 2. 查全部检查组(渲染可选列表) │
│ POST /checkgroup/findAll → 展示所有检查组 │
├─────────────────────────────────────────────────┤
│ 3. 查当前套餐关联的检查组(用于勾选)⚠️关键 │
│ POST /setmeal/findCheckGroupIds → 返回 [3,5,7]│
└─────────────────────────────────────────────────┘