启动器dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-quartz/artifactId /dependency存放的都是版本号一分页查询点击检查项就会弹出所有的检查项前台 传出 paramcurrentPage: this.pagination.currentPage, // 第1个当前页码 pageSize: this.pagination.pageSize, // 第2个每页条数 queryString: this.pagination.queryString // 第3个搜索关键词后台需要返回this.dataList res.rows; // 当前页展示的数据集合 this.pagination.total res.total; // 总数数据量后端Controller层/** * 分页查询 * param queryPageBean 查询条件 * return */ RequestMapping(/findPage) public PageResult findPage(RequestBody QueryPageBean queryPageBean) { // 直接从 queryPageBean 里取 queryString 作为查询参数 return checkGroupService.findPage(queryPageBean, queryPageBean.getQueryString()); }serviceOverride//分页查询检查组 public PageResult findPage(QueryPageBean queryPageBean, String param) { // this.pagination.currentPage, 当前页码 // this.pagination.pageSize, 每页显示多少条数据 PageHelper.startPage(queryPageBean.getCurrentPage(),queryPageBean.getPageSize()); // 查询总记录数 ListCheckGroup checkGroupList checkGroupMapper.findPage(queryPageBean,param); // 分页查询 // PageInfo 封装了分页信息 PageInfo pageInfo new PageInfo(checkGroupList); // 封装PageResult return new PageResult(pageInfo.getTotal(),pageInfo.getList()); // 返回分页结果 }mapper :省略二查询检查组RequestMapping(/findAll) public Result findAll(){ try { ListCheckGroup checkGroups checkGroupService.findAll(); return new Result(true, MessageConstant.QUERY_CHECKGROUP_SUCCESS,checkGroups); }catch (Exception e){ return new Result(false, MessageConstant.QUERY_CHECKGROUP_FAIL); } }三一对多先获取前端 检查项的 [id ]/** * 添加检查组 * 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);//添加失败 } }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) { ListObject checkitemIdList new ArrayList(); checkitemIdList.add(checkitemId); checkGroupMapper.setCheckGroupAndCheckItem(checkGroupId,checkitemIdList); } }void add( CheckGroup checkGroup); //必须需要主键回填 //关联表 void setCheckGroupAndCheckItem(Param(checkGroupId) Integer checkGroupId, Param(checkitemIdList) ListObject checkitemIdList);四图片上传 过期自动删除图片上传服务器事件editFormData: {}, //新增表单窗口中检查组列表数据前端后端添加sql数据/** * 添加套餐 */ 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()); ListInteger ids dto.getCheckgroupIds(); Integer[] checkgroupIds ids ! null ? ids.toArray(new Integer[0]) : new Integer[0]; setmealService.add(setmeal, checkgroupIds); if (setmeal.getImg() ! null) { // 上传图片 添加一个集合当中 egreadis 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); } }图片上传服务器/** * 上传图片 */ 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//同理 关联表添加 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); } } }过期照片定时清理工具类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 定时清理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 { SetObject 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(); } } }图片清理过程项目启动 ↓ Spring 加载 QuartzUtil 配置类 ↓ 创建 SchedulerFactoryBean调度器 ↓ 注册 CronTrigger触发器每分钟执行 ↓ 绑定 MethodInvokingJobDetailFactoryBean ↓ 自动调用 DeleteJobImg.deleteImg()五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) {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()); ListInteger 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, 编辑套餐失败); } }RequestMapping(/findCheckGroupIdsBySetmealId) public Result findCheckGroupIdsBySetmealId(Integer id) { try { ListInteger 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// 异常处理示例 public class ExceptionHandling { public static void main(String[] args) { try { int result 10 / 0; } catch (ArithmeticException e) { System.out.println(Cannot divide by zero); } } }sqlinsert idaddSetmealAndCheckItem insert into t_setmeal_checkgroup(setmeal_id, checkgroup_id) values (#{setmealId}, #{checkgroupId}) /insert update idedit update t_setmeal set if testname ! nullname #{name},/if if testcode ! nullcode #{code},/if if testhelpCode ! nullhelpCode #{helpCode},/if if testsex ! nullsex #{sex},/if if testage ! nullage #{age},/if if testprice ! nullprice #{price},/if if testremark ! nullremark #{remark},/if if testattention ! nullattention #{attention},/if if testimg ! nullimg #{img},/if /set where id #{id} /update┌─────────────────────────────────────────────────┐ │ 1. 查套餐详情图片 基础信息 │ │ POST /setmeal/findById → 表单回填 图片显示 │ ├─────────────────────────────────────────────────┤ │ 2. 查全部检查组渲染可选列表 │ │ POST /checkgroup/findAll → 展示所有检查组 │ ├─────────────────────────────────────────────────┤ │ 3. 查当前套餐关联的检查组用于勾选⚠️关键 │ │ POST /setmeal/findCheckGroupIds → 返回 [3,5,7]│ └─────────────────────────────────────────────────┘