项目总结一

启动器

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]│
└─────────────────────────────────────────────────┘
相关推荐
JimmtButler2 小时前
一台电脑,两个 Git 身份:公司 GitLab + 个人 GitHub 共存
后端
Mintopia2 小时前
接口设计为什么越改越乱:新手最容易踩的三个坑
前端
全栈王校长2 小时前
Nest 中间件 Middleware - 就像 Vue 的路由守卫
后端·nestjs
code小生2 小时前
微软 Microsoft Edge 浏览器插件开发者注册指南
前端·microsoft·edge·edge浏览器·浏览器插件开发者
无巧不成书02182 小时前
Java 21 LTS 高级特性零基础通关:静态导入、项目目录规范、泛型全实战
java·开发语言·标准目录结构·泛型原理·类型安全实现
敖正炀2 小时前
AQS-模板方法
java
橘子编程2 小时前
Hermes Agent 完整知识总结与使用教程
java·人工智能·ai·tomcat·maven·ai编程
全栈王校长2 小时前
Nest ValidationPipe 参数验证 - 就像前端的表单校验
后端·nestjs
沃尔威武2 小时前
Spring Cloud Gateway实战:微服务API网关从零到一
java·spring·微服务