quartz整合前端vue加后端springboot

因工作需求,需要能修改定时的任务,前端vue3,后端是springboot

看看页面效果:

首先maven加上引入

XML 复制代码
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.1</version>
        </dependency>

然后yaml加上配置(Quartz就这点好,自动给你建表了)

XML 复制代码
#服务器配置
server:
  port: 8080
  undertow:
    threads:
      # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
      io: 16
      # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
      worker: 400
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    buffer-size: 1024
    # 是否分配的直接内存
    direct-buffers: true

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    #driver-class-name: org.postgresql.Driver
    #driver-class-name: oracle.jdbc.OracleDriver
    #driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    druid:
      # MySql、PostgreSQL、SqlServer、DaMeng校验
      validation-query: select 1
      # Oracle、YashanDB校验
      #oracle: true
      #validation-query: select 1 from dual
      validation-query-timeout: 2000
      initial-size: 5
      max-active: 20
      min-idle: 5
      max-wait: 60000
      test-on-borrow: false
      test-on-return: false
      test-while-idle: true
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      stat-view-servlet:
        enabled: true
        login-username: 
        login-password: 
      web-stat-filter:
        enabled: true
        url-pattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
        session-stat-enable: true
        session-stat-max-count: 10
  quartz:
    # 任务存储类型
    job-store-type: "jdbc"
    # 关闭时等待任务完成
    wait-for-jobs-to-complete-on-shutdown: false
    # 是否覆盖已有的任务
    overwrite-existing-jobs: true
    # 是否自动启动计划程序
    auto-startup: true
    # 延迟启动
    startup-delay: 0s
    jdbc:
      # 数据库架构初始化模式(never:从不进行初始化;always:每次都清空数据库进行初始化;embedded:只初始化内存数据库(默认值))
      initialize-schema: "always"#todo 后续改
    # 相关属性配置
    properties:
      org:
        quartz:
          scheduler:
            # 调度器实例名称
            instanceName: QuartzScheduler
            # 分布式节点ID自动生成
            instanceId: AUTO
          jobStore:
            class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            # 表前缀
            tablePrefix: QRTZ_
            # 是否开启集群
            isClustered: true
            # 数据源别名(自定义)
            dataSource: quartz
            # 分布式节点有效性检查时间间隔(毫秒)
            clusterCheckinInterval: 10000
            useProperties: false
          # 线程池配置
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

然后开始正式后台代码:

java 复制代码
package org.springblade.etl.source.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.etl.source.entity.JobInfo;
import org.springblade.etl.source.service.QuartzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/quartz")
public class QuartzController {

    @Autowired
    private QuartzService quartzService;
    //创建任务
    @PostMapping("/save")
    public R createJob(@RequestBody JobInfo jobInfo) {
        return quartzService.addCronJob(jobInfo.getJobName(), jobInfo.getCron(), "org.springblade.etl.source.task.TaskJob").equals("SUCCESS")?R.status(true):R.status(false);//todo 类名写在这
    }
    //删除任务
    @PostMapping("/remove")
    public R deleteJob(@RequestParam("jobName")String jobName) {
        return quartzService.deleteCronJob(jobName, null, null, null).equals("SUCCESS")?R.status(true):R.status(false);
    }
    //执行一次
    @PostMapping("/executeImmediately")
    public String executeImmediately(@RequestBody JobInfo jobInfo) {
        return quartzService.executeImmediately(jobInfo.getJobName(), "org.springblade.etl.source.task.TaskJob");
    }


    //获取任务状态
    @PostMapping("/detail")
    public R<JobInfo> getJobStatus(@RequestParam("jobName")String jobName) {
        return R.data(quartzService.getJobStatus(jobName, null));
    }

    //获取所有任务
    @PostMapping("/list")
    public R getAllJob() {
        // 创建分页对象,指定当前页码和每页显示的数量
        long currentPage = 1; // 当前页码
        long pageSize = 10; // 每页显示数量
        Page<JobInfo> page = new Page<>(currentPage, pageSize);
        page.setRecords(quartzService.getAllJob());
        return R.data(page);
    }

    //修改定时任务时间
    @PostMapping("/submit")
    public R updateJob(@RequestBody JobInfo jobInfo) {
        quartzService.deleteCronJob(jobInfo.getJobName(), jobInfo.getJobGroup(), jobInfo.getTriggerName(), jobInfo.getTriggerGroup());
        return quartzService.addCronJob(jobInfo.getJobName(), jobInfo.getCron(), "org.springblade.etl.source.task.TaskJob").equals("SUCCESS")?R.status(true):R.status(false);
    }


}
java 复制代码
package org.springblade.etl.source.service;

import org.springblade.etl.source.entity.JobInfo;

import java.util.List;

public interface QuartzService {

    /**
     * 新增
     *
     * @param jobName
     * @param cron
     * @param jobClassName
     * @return
     */
    String addCronJob(String jobName, String cron, String jobClassName);

    /**
     * 停止
     *
     * @param jobName
     * @param jobGroup
     * @param triggerName
     * @param triggerGroup
     * @return
     */
    String deleteCronJob(String jobName, String jobGroup, String triggerName, String triggerGroup);

    /**
     * 立即执行,不定时
     *
     * @param jobName
     * @param jobClassName
     * @return
     */
    String executeImmediately(String jobName, String jobClassName);

    // 暂停

    // 获取状态
    JobInfo getJobStatus(String jobName, String jobGroup);

    List<JobInfo> getAllJob();
}
java 复制代码
package org.springblade.etl.source.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.etl.source.entity.JobInfo;
import org.springblade.etl.source.service.QuartzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class QuartzServiceImpl implements QuartzService {

    @Autowired
    private Scheduler scheduler;

    private static final String DEFAULT_JOB_GROUP = "default_job_group";

    private static final String DEFAULT_TRIGGER_GROUP = "default_trigger_group";

    private static final String TRIGGER_PRE = "Trigger_";

    @Override
    public String addCronJob(String jobName, String cron, String jobClassName) {
        try {
            // 当前任务不存在才进行添加
            JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
            if (scheduler.checkExists(jobKey)) {
                log.info("[添加定时任务]已存在该作业,jobkey为:{}", jobKey);
                return "已存在该作业";
            }

            // 构建 Job
            JobDetail job = JobBuilder.newJob(getClass(jobClassName).getClass())
                    .withIdentity(jobKey).build();

            // cron表达式定时构造器
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

            // 构建 Trigger
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP))
//                .startAt(DateUtil.parseDate(start))
//                .endAt(DateUtil.parseDate(end))
                    .withSchedule(cronScheduleBuilder).build();

            // 启动调度器
            scheduler.scheduleJob(job, trigger);
            scheduler.start();
            return "SUCCESS";
        } catch (Exception e) {
            log.error("[新增定时任务]失败,报错:", e);
            return "FAIL";
        }

    }

    @Override
    public String deleteCronJob(String jobName, String jobGroup, String triggerName, String triggerGroup) {
        try {

            JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
            //如果triggerName和triggerGroup为空,则使用默认值
            if (StringUtil.isBlank(triggerName)&&StringUtil.isBlank(triggerGroup)){
                triggerName = TRIGGER_PRE + jobName;
                triggerGroup = DEFAULT_TRIGGER_GROUP;
            }
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);

            Trigger trigger = scheduler.getTrigger(triggerKey);

            if (null == trigger) {
                log.info("[停止定时任务]根据triggerName:{}和triggerGroup:{}未查询到相应的trigger!");
                return "SUCCESS";
            }
            //暂停触发器
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 删除任务
            scheduler.deleteJob(jobKey);

            log.info("[停止定时任务]jobName:{},jobGroup:{}, triggerName:{}, triggerGroup:{},停止--------------", jobName, jobGroup, triggerName, triggerGroup);

            return "SUCCESS";

        } catch (SchedulerException e) {
            log.error("[停止定时任务]失败,报错:", e);
            return "FAIL";
        }
    }


    public static Job getClass(String className) throws Exception {
        Class<?> classTemp = Class.forName(className);
        return (Job) classTemp.newInstance();
    }

    @Override
    public String executeImmediately(String jobName, String jobClassName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
            JobDetail job = JobBuilder.newJob(getClass(jobClassName).getClass())
                    .withIdentity(jobKey).build();

            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP))
                    .build();

            // 启动调度器
            scheduler.scheduleJob(job, trigger);
            scheduler.start();
            return "SUCCESS";
        } catch (Exception e) {
            log.error("[立即执行一次任务,不定时]失败,报错:", e);
            return "FAIL";
        }
    }





    @Override
    public JobInfo getJobStatus(String jobName, String jobGroup) {
        try {
            // 当前任务不存在才进行添加
            JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
            // 利用JobKey查找任务是否存在
            if (scheduler.checkExists(jobKey)) {
                log.info("查找到该任务,任务名:{}, 状态为:{}", jobName, scheduler.getTriggerState(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP)));

                // 获取Cron触发器,从而获得Cron表达式
                CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP));
                String cronExpression = cronTrigger.getCronExpression();
                JobInfo jobInfo = new JobInfo();
                jobInfo.setJobName(jobKey.getName());
                jobInfo.setJobGroup(jobKey.getGroup());
                jobInfo.setStatus( scheduler.getTriggerState(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP)).toString());
                jobInfo.setTriggerName(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP).getName());
                jobInfo.setTriggerGroup(DEFAULT_TRIGGER_GROUP);
                jobInfo.setCron(cronExpression);

                return jobInfo;
            } else {
                throw  new RuntimeException("任务不存在");
            }


        } catch (SchedulerException e) {
            log.error("[查询任务状态]失败,报错:", e);
            throw  new RuntimeException("任务不存在");
        }
    }

    @Override
    public List<JobInfo> getAllJob() {

        ArrayList<JobInfo> jobInfos = new ArrayList<JobInfo>();
        try {
            // 获取所有的触发器组
            for (String triggerGroup : scheduler.getTriggerGroupNames()) {
                // 获取指定触发器组下的所有触发器
                for (TriggerKey triggerKey : scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(triggerGroup))) {
                    Trigger trigger = scheduler.getTrigger(triggerKey);

                    // 判断触发器类型是否为 CronTrigger
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        JobKey jobKey = cronTrigger.getJobKey();
                        JobInfo jobInfo = new JobInfo();
                        jobInfo.setJobName(jobKey.getName());
                        jobInfo.setJobGroup(jobKey.getGroup());
                        jobInfo.setTriggerName(triggerKey.getName());
                        jobInfo.setTriggerGroup(triggerKey.getGroup());
                        //获取一下cron表达式
                        jobInfo.setCron(cronTrigger.getCronExpression());
                        jobInfo.setStatus( scheduler.getTriggerState(TriggerKey.triggerKey(TRIGGER_PRE + jobKey.getName(), DEFAULT_TRIGGER_GROUP)).toString());
                        jobInfos.add(jobInfo);
                    }
                }
            }

            if (jobInfos.size() == 0) {
                log.info("暂无定时任务");
                return null;
            }

        } catch (SchedulerException e) {
            log.error("[查询所有定时任务状态]失败,报错:", e);
            throw new RuntimeException("查询所有定时任务状态失败");
        }

        return jobInfos;
    }


}

这个时间转换cron是我的自己的业务需要(因为前段不能让用户输入cron表达式,所以我让用户输入时间即可转换适合的cron表达式)

java 复制代码
package org.springblade.common.utils;

import org.quartz.CronExpression;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CronTimeConverter {
    public static String convertCronToTime(String cronExpression) {
        try {
            CronExpression cron = new CronExpression(cronExpression);
            Date nextExecutionTime = cron.getTimeAfter(new Date());
            // 转换为指定的时间格式,比如 HH:mm
            // 这里使用 SimpleDataFormat 进行格式化
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
            return sdf.format(nextExecutionTime);
        } catch (ParseException e) {
            e.printStackTrace();
            return ""; // 处理异常情况,返回空字符串或其他默认值
        }
    }

//    public static void main(String[] args) {
//        String cronExpression = "0 40 14 * * ?";
//        String time = convertCronToTime(cronExpression);
//        System.out.println("Time based on cron expression " + cronExpression + " is: " + time);
//    }


    public static String convertTimeToCron(String time) {
        String[] timeParts = time.split(":");
        if (timeParts.length != 2) {
            return ""; // 处理异常情况,返回空字符串或其他默认值
        }

        String cronExpression = String.format("0 %s %s * * ?", timeParts[1], timeParts[0]);
        return cronExpression;
    }

    public static void main(String[] args) {
        String time = "14:40";
        String cronExpression = convertTimeToCron(time);
        System.out.println("Cron expression for time " + time + " is: " + cronExpression);
    }
}

你需要一个entity对象:

java 复制代码
package org.springblade.etl.source.entity;

import lombok.Data;
import org.springblade.common.utils.CronTimeConverter;
import org.springblade.core.tool.utils.StringUtil;

import java.time.*;
import java.time.format.DateTimeFormatter;

@Data
public class JobInfo {

    private String jobName;
    private String time = "2024-03-19T08:26:58.000Z" ;

    private String cron = "0 16 10 ? * *";

    private String jobGroup;

    private String triggerName;

    private String triggerGroup;

    private String status;



    public void setCron(String cron) {
        //顺便将时间写入
        if (StringUtil.isNotBlank(cron)) {
            this.cron = cron;
            String time = CronTimeConverter.convertCronToTime(cron);
            LocalTime localTime = LocalTime.parse(time);

            // 将当天的本地时间与当天的日期结合,并转换为ZonedDateTime对象
            ZonedDateTime localDateTime = ZonedDateTime.now().withHour(localTime.getHour()).withMinute(localTime.getMinute());


            // 将本地时间转换为UTC时间,并进行格式化
            ZonedDateTime utcDateTime = localDateTime.withZoneSameInstant(ZoneOffset.UTC);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            this.time = utcDateTime.format(formatter);
        }
    }

    public void setTime(String utcTime){

        if (StringUtil.isNotBlank(utcTime)) {
            this.time =utcTime;
            //顺便将cron表达式写入
            // 将UTC时间字符串转换为Instant对象
            Instant instant = Instant.parse(utcTime);

            // 将Instant对象转换为本地时间
            ZonedDateTime localTime = instant.atZone(ZoneId.systemDefault());

            // 格式化本地时间为 "HH:mm" 形式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
            String formattedTime = localTime.format(formatter);
            String cron = CronTimeConverter.convertTimeToCron(formattedTime);
            this.cron = cron;
        }
    }



        public static void main(String[] args) {
            // UTC时间字符串
            String utcTime = "2024-03-19T08:26:58.000Z";

            // 将UTC时间字符串转换为Instant对象
            Instant instant = Instant.parse(utcTime);

            // 将Instant对象转换为本地时间
            ZonedDateTime localTime = instant.atZone(ZoneId.systemDefault());

            // 格式化本地时间为 "HH:mm" 形式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
            String formattedTime = localTime.format(formatter);

            System.out.println("本地时间(HH:mm):" + formattedTime);
            System.out.println("UTC时间:" + instant);
            System.out.println("本地时间:" + formattedTime);
        }

}

下面是前端vue

javascript 复制代码
<template>
  <basic-container>
    <avue-crud :option="option"
               v-model:search="search"
               v-model:page="page"
               v-model="form"
               :table-loading="loading"
               :data="data"
               :permission="permissionList"
               :before-open="beforeOpen"
               ref="crud"
               @row-update="rowUpdate"
               @row-save="rowSave"
               @row-del="rowDel"
               @search-change="searchChange"
               @search-reset="searchReset"
               @selection-change="selectionChange"
               @current-change="currentChange"
               @size-change="sizeChange"
               @refresh-change="refreshChange"
               @on-load="onLoad">
      <template #menu-left>
        <el-button type="primary"
                   icon="el-icon-s-promotion"
                   @click="handleManualTrigger">手动触发
        </el-button>
<!--        <el-button type="danger"-->
<!--                   icon="el-icon-delete"-->
<!--                   plain-->
<!--                   v-if="permission.jobInfo_delete"-->
<!--                   @click="handleDelete">删 除-->
<!--        </el-button>-->
<!--        <el-button type="warning"-->
<!--                   plain-->
<!--                   icon="el-icon-download"-->
<!--                   @click="handleExport">导 出-->
<!--        </el-button>-->
      </template>
    </avue-crud>
  </basic-container>
</template>

<script>
  import {getList, getDetail, add, update, remove,startETLForSYNL} from "@/api/source/jobInfo";
  import option from "@/option/source/jobInfo";
  import {mapGetters} from "vuex";
  import {exportBlob} from "@/api/common";
  import {getToken} from '@/utils/auth';
  import {downloadXls} from "@/utils/util";
  import {dateNow} from "@/utils/date";
  import NProgress from 'nprogress';
  import 'nprogress/nprogress.css';

  export default {
    data() {
      return {
        form: {},
        query: {},
        search: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        selectionList: [],
        option: option,
        data: []
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          addBtn: this.validData(this.permission.jobInfo_add, false),
          viewBtn: this.validData(this.permission.jobInfo_view, false),
          delBtn: this.validData(this.permission.jobInfo_delete, false),
          editBtn: this.validData(this.permission.jobInfo_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
      }
    },
    methods: {
      rowSave(row, done, loading) {
        row.cron = null;//表达式不往后端传
        add(row).then(() => {
          this.onLoad(this.page);
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          done();
        }, error => {
          loading();
          window.console.log(error);
        });
      },
      rowUpdate(row, index, done, loading) {
        row.cron = null;表达式不往后端传
        update(row).then(() => {
          this.onLoad(this.page);
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          done();
        }, error => {
          loading();
          console.log(error);
        });
      },
      rowDel(row) {
        this.$confirm("确定将选择数据删除?", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            return remove(row.jobName);
          })
          .then(() => {
            this.onLoad(this.page);
            this.$message({
              type: "success",
              message: "操作成功!"
            });
          });
      },
      handleDelete() {
        if (this.selectionList.length === 0) {
          this.$message.warning("请选择至少一条数据");
          return;
        }
        this.$confirm("确定将选择数据删除?", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            return remove(this.jobName);
          })
          .then(() => {
            this.onLoad(this.page);
            this.$message({
              type: "success",
              message: "操作成功!"
            });
            this.$refs.crud.toggleSelection();
          });
      },
      handleExport() {
        let downloadUrl = `/blade-jobInfo/jobInfo/export-jobInfo?${this.website.tokenHeader}=${getToken()}`;
        const {
        } = this.query;
        let values = {
        };
        this.$confirm("是否导出数据?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(() => {
          NProgress.start();
          exportBlob(downloadUrl, values).then(res => {
            downloadXls(res.data, `自动任务表${dateNow()}.xlsx`);
            NProgress.done();
          })
        });
      },
      beforeOpen(done, type) {
        if (["edit", "view"].includes(type)) {
          getDetail(this.form.jobName).then(res => {
            this.form = res.data.data;
          });
        }
        done();
      },
      searchReset() {
        this.query = {};
        this.onLoad(this.page);
      },
      searchChange(params, done) {
        this.query = params;
        this.page.currentPage = 1;
        this.onLoad(this.page, params);
        done();
      },
      selectionChange(list) {
        this.selectionList = list;
      },
      selectionClear() {
        this.selectionList = [];
        this.$refs.crud.toggleSelection();
      },
      currentChange(currentPage){
        this.page.currentPage = currentPage;
      },
      sizeChange(pageSize){
        this.page.pageSize = pageSize;
      },
      refreshChange() {
        this.onLoad(this.page, this.query);
      },
      onLoad(page, params = {}) {
        this.loading = true;

        const {
        } = this.query;

        let values = {
        };

        getList(page.currentPage, page.pageSize, values).then(res => {
          console.log("定时任务得到的数据=",res);
          const data = res.data.data;
          this.page.total = data.total;
          this.data = data.records;
          this.loading = false;
          this.selectionClear();
        });
      },
      handleManualTrigger() {
        this.$confirm("确定手动触发定时任务?", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
            .then(() => {
              this.$message({
                type: "success",
                message: "操作成功!"
              });
              // 调用 startETLForSYNL 方法
              startETLForSYNL().then(response => {
                const result = response.data.data; // 获取返回值
                console.log("返回值=",response)
                this.$message({
                  type: "info",
                  message: ` ${result}`
                });
              }).catch(error => {
                this.$message.error("操作失败");
              });
            });
      }

    }
  };
</script>

<style>
</style>
javascript 复制代码
export default {
  height:'auto',
  calcHeight: 30,
  tip: false,
  searchShow: true,
  searchMenuSpan: 6,
  // border: true,
  // index: true,
  // viewBtn: true,
  selection: true,
  // dialogClickModal: false,
  column: [
    {
      label: "",
      prop: "id",
      type: "input",
      addDisplay: false,
      editDisplay: false,
      viewDisplay: false,
      hide: true,
    },
    {
      label: "任务名称",
      prop: "jobName",
      type: "input",
    },
    {
      label: "执行时间",
      prop: "time",
      type: "time",
      format: "HH:mm" // 设置时间格式,例如 "HH:mm"
    },
    {
      label: "定时表达式",
      prop: "cron",
      type: "input",
      editDisplay: false,
      addDisplay: false,
    },
    {
      label: "任务分组",
      prop: "jobGroup",
      type: "input",
      addDisplay: false,
      editDisplay: false,
      hide: true
    },
    {
      label: "触发器名称",
      prop: "triggerName",
      type: "input",
      addDisplay: false,
      editDisplay: false,
      hide: true
    },
    {
      label: "触发器分组",
      prop: "triggerGroup",
      type: "input",
      addDisplay: false,
      editDisplay: false,
      hide: true
    },
    {
      label: "状态",
      prop: "status",
      type: "input",
      addDisplay: false,
      editDisplay: false,
    }

  ]
}
javascript 复制代码
import request from '@/axios';

export const getList = (current, size, params) => {
  return request({
    url: '/quartz/list',
    method: 'post',
    params: {
      ...params,
      current,
      size,
    }
  })
}

export const getDetail = (jobName) => {
  return request({
    url: '/quartz/detail',
    method: 'post',
    params: {
      jobName
    }
  })
}

export const remove = (jobName) => {
  return request({
    url: '/quartz/remove',
    method: 'post',
    params: {
      jobName,
    }
  })
}

export const add = (row) => {
  return request({
    url: '/quartz/submit',
    method: 'post',
    data: row
  })
}

export const update = (row) => {
  return request({
    url: '/quartz/submit',
    method: 'post',
    data: row
  })
}

export const startETLForSYNL = () => {
  return request({
    url: '/startETLForSYNL',
    method: 'get'
  })
}
相关推荐
小小小小宇3 小时前
LLM 长期记忆构建
前端
lichenyang4533 小时前
从 Express 老项目到 NestJS + Docker:一次车辆管理系统的渐进式重构
前端
Momo__5 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富5 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇5 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇5 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆5 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马5 小时前
Verilog开发常见问题汇总解析
前端
子兮曰5 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端