Ver código fonte

任务增加几个字段

soft5566 2 anos atrás
pai
commit
8d412cff58

+ 32 - 3
src/main/java/com/template/api/Task.java

@@ -1,25 +1,54 @@
 package com.template.api;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.template.common.utils.CommonUtil;
+import com.template.common.utils.QuartzJobUtils;
+import com.template.mapper.SmartDataTaskMapper;
+import com.template.model.pojo.SmartDataTask;
+import com.template.services.impl.SmartDataTaskServiceImpl;
 import org.quartz.JobDetail;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
 import org.quartz.JobKey;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.Map;
 
+@Component
 public class Task extends QuartzJobBean {
+
+    @Autowired
+    private SmartDataTaskMapper smartDataTaskMapper;
+
     @Override
-    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
-        //输出当前时间
+    protected void executeInternal(JobExecutionContext jobExecutionContext) {
+        // 输出当前时间
         Date date = new Date();
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String dateString = dateFormat.format(date);
 
         JobDetail jobDetail = jobExecutionContext.getJobDetail();
         JobKey key = jobDetail.getKey();
-        //工作内容
+        // 工作内容
         System.out.println("定时任务名称:【" + key.getName() + "】,执行时间:" + dateString);
+        // 及时更新下次更新时间
+        QueryWrapper<SmartDataTask> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq(key.getName() != null, "tk_name", key.getName());
+        SmartDataTask smartDataTask = smartDataTaskMapper.selectOne(queryWrapper);
+        if (smartDataTask != null) {
+            // 下次执行的时间
+            String nextExeTime = QuartzJobUtils.getNextExeTime(smartDataTask.getTkCron());
+            smartDataTask.setTkNextExeTime(nextExeTime);
+            try {
+                smartDataTaskMapper.updateById(smartDataTask);
+            } catch (Exception e) {
+                System.out.println(e.getMessage());
+            }
+        }
     }
 }

+ 18 - 0
src/main/java/com/template/common/utils/CommonUtil.java

@@ -16,6 +16,8 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * 公共工具类
@@ -36,6 +38,13 @@ public class CommonUtil {
         return returnMap;
     }
 
+    /**
+     * 生成日志对象
+     *
+     * @param str                字符串
+     * @param httpServletRequest 请求对象
+     * @return 返回对象
+     */
     public static SmartDataSourceLog generateLog(String str, HttpServletRequest httpServletRequest) {
         String serverIp = null;
         try {
@@ -66,6 +75,15 @@ public class CommonUtil {
         return smartDataSourceLog;
     }
 
+    public static String getNumberFromString(String string) {
+        Pattern pattern = Pattern.compile("\\d+");
+        Matcher matcher = pattern.matcher(string);
+        if (matcher.find()) {
+            return matcher.group();
+        }
+        return null;
+    }
+
     /**
      * 获取ip
      *

+ 26 - 2
src/main/java/com/template/common/utils/QuartzJobUtils.java

@@ -4,6 +4,9 @@ import com.template.model.pojo.SmartDataTask;
 import com.template.model.result.CommonResult;
 import org.quartz.*;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.Map;
 
 public class QuartzJobUtils {
@@ -17,6 +20,7 @@ public class QuartzJobUtils {
      * @param smartDataTask 定时任务信息类
      */
     public static Map<String, Object> createScheduleJob(Scheduler scheduler, SmartDataTask smartDataTask) {
+        // 判断是否存在该任务
         Map<String, Object> exists = exists(scheduler, smartDataTask.getTkName());
         if ("0".equals(exists.get("code"))) {
             return exists;
@@ -35,7 +39,7 @@ public class QuartzJobUtils {
                     .withIdentity(smartDataTask.getTkName())
                     .withSchedule(cronScheduleBuilder)
                     .build();
-            //把触发器与任务进行绑定
+            // 把触发器与任务进行绑定
             scheduler.scheduleJob(jobDetail, cronTrigger);
 
             return CommonUtil.getReturnMap(String.valueOf(0), "定时任务【" + smartDataTask.getTkName() + "】创建成功!");
@@ -46,6 +50,26 @@ public class QuartzJobUtils {
         }
     }
 
+    public static String getNextExeTime(String cronExpression) {
+        // 创建CronExpression对象
+        CronExpression cron;
+        try {
+            cron = new CronExpression(cronExpression);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        // 获取当前时间
+        long currentTimeMillis = System.currentTimeMillis();
+
+        // 计算下次执行时间
+        Date nextValidTimeMillis = cron.getNextValidTimeAfter(new Date(currentTimeMillis));
+
+        // 格式化输出
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        return sdf.format(nextValidTimeMillis);
+    }
+
     /**
      * 根据任务暂停定时任务
      *
@@ -67,7 +91,7 @@ public class QuartzJobUtils {
         }
     }
 
-    public static Map<String, Object> exists(Scheduler scheduler, String jobName) {
+    private static Map<String, Object> exists(Scheduler scheduler, String jobName) {
         JobKey jobKey = new JobKey(jobName);
         try {
             if (scheduler.getJobDetail(jobKey) != null) {

+ 11 - 6
src/main/java/com/template/controller/SmartDataTaskController.java

@@ -224,21 +224,26 @@ public class SmartDataTaskController implements SmartDataTaskControllerAPI {
     @Override
     public CommonResult deleteSmartDataTaskById(int id, HttpServletRequest httpServletRequest) {
 
-        SmartDataTask data = smartDataTaskService.getSmartById(id);
+        SmartDataTask smartDataTask = smartDataTaskService.getSmartById(id);
 
-        if (data == null) {
+        if (smartDataTask == null) {
             return CommonResult.fail("当前数据不存在,删除失败!");
         }
 
+        if (smartDataTask.getTkDeleted() == 1) {
+            return CommonResult.fail("当前数据已是标记为删除状态,删除失败!");
+        }
+
         SmartDataSourceLog smartDataSourceLog =
-                CommonUtil.generateLog("删除数据源数据交换任务|【数据交换中心】→【数据源数据交换任务】|删除【数据源数据交换任务】|delete", httpServletRequest);
-        int result = smartDataTaskService.deleteSmartDataTaskById(id);
+                CommonUtil.generateLog("标记为删除数据源数据交换任务|【数据交换中心】→【数据源数据交换任务】|标记为删除【数据源数据交换任务】|delete", httpServletRequest);
+        smartDataTask.setTkDeleted(1);
+        int result = smartDataTaskService.deleteSmartDataTaskById(smartDataTask);
         if (result > 0) {
             smartDataSourceLog.setLogActionStatus(1);
             smartDataSourceLogService.insertSmartDataSourceLog(smartDataSourceLog);
-            return CommonResult.ok("删除成功");
+            return CommonResult.ok("标记为删除状态成功");
         } else {
-            return CommonResult.fail("删除失败");
+            return CommonResult.fail("标记为删除状态失败");
         }
     }
 }

+ 23 - 10
src/main/java/com/template/mapper/SmartDataTaskMapper.java

@@ -3,6 +3,7 @@ package com.template.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.template.model.pojo.SmartDataTask;
 import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
 import org.springframework.stereotype.Repository;
 
 import java.util.List;
@@ -17,21 +18,33 @@ import java.util.List;
  */
 @Repository
 public interface SmartDataTaskMapper extends BaseMapper<SmartDataTask> {
-
     @Select("SELECT " +
-            "        tk_id, " +
-            "        tk_ds_id, " +
-            "        tk_name, " +
-            "        tk_cron, " +
-            "        tk_sql, " +
-            "        tk_activation, " +
-            "        tk_descrition, " +
-            "        tk_create_time, " +
-            "        tk_update_time  " +
+            "        tk_id " +
+            "        ,tk_name " +
+            "        ,tk_ds_id_source " +
+            "        ,tk_sync_policy " +
+            "        ,tk_sql, " +
+            "        tk_ds_id_destination " +
+            "        ,tk_dest_table " +
+            "        ,tk_manual_or_auto " +
+            "        ,tk_descrition " +
             "    FROM " +
             "        smart_data_task  " +
             "    WHERE " +
             "        tk_name = #{tkName} " +
             "        AND tk_id != #{tkId} ")
     List<SmartDataTask> isRepeatTaskName(SmartDataTask smartDataTask);
+
+    @Update("UPDATE smart_data_task " +
+            "SET tk_deleted = 1 " +
+            "WHERE " +
+            "       tk_id = #{tkId} ")
+    Integer deleteMarkTaskById(SmartDataTask smartDataTask);
+
+    @Update("UPDATE smart_data_task " +
+            "SET tk_activation = #{tkActivation} " +
+            "    ,tk_next_exe_time = #{tkNextExeTime} " +
+            "WHERE " +
+            "       tk_id = #{tkId} ")
+    Integer markTaskById(SmartDataTask smartDataTask);
 }

+ 36 - 8
src/main/java/com/template/model/pojo/SmartDataTask.java

@@ -33,24 +33,52 @@ public class SmartDataTask implements Serializable {
     @TableId(value = "tk_id", type = IdType.AUTO)
     private Integer tkId;
 
-    @ApiModelProperty(value = "数据源id")
-    private Integer tkDsId;
-
     @ApiModelProperty(value = "任务名称")
     private String tkName;
 
-    @ApiModelProperty(value = "任务定时表达式")
-    private String tkCron;
+    @ApiModelProperty(value = "来源数据源id")
+    private Integer tkDsIdSource;
+
+    @ApiModelProperty(value = "同步策略:0插入更新,1更新标记,2清空插入")
+    private Integer tkSyncPolicy;
+
+    @ApiModelProperty(value = "交换方式:0自定义SQL语句,1数据视图,2数据表")
+    private Integer tkExchangeType;
 
     @ApiModelProperty(value = "任务使用的SQL语言")
     private String tkSql;
 
-    @ApiModelProperty(value = "是否激活")
-    private Integer tkActivation;
+    @ApiModelProperty(value = "目标数据源id")
+    private Integer tkDsIdDestination;
+
+    @ApiModelProperty(value = "目标数据表")
+    private String tkDestTable;
+
+    @ApiModelProperty(value = "任务定时表达式")
+    private String tkCron;
+
+    @ApiModelProperty(value = "手动或者定时执行:0定时执行,1手动执行")
+    private Integer tkManualOrAuto;
+
+    @ApiModelProperty(value = "执行方式:0间隔执行,1定点执行,2每天,3每周,4每月")
+    private Integer tkExeType;
+
+    @ApiModelProperty(value = "重复时间")
+    private String tkRepetTime;
 
     @ApiModelProperty(value = "任务描述")
     private String tkDescrition;
 
+    @ApiModelProperty(value = "是否激活")
+    private Integer tkActivation;
+
+    @ApiModelProperty(value = "删除标记")
+    private Integer tkDeleted;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty(value = "下次执行时间")
+    private String tkNextExeTime;
+
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     @ApiModelProperty(value = "创建时间")
     private Date tkCreateTime;
@@ -58,4 +86,4 @@ public class SmartDataTask implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     @ApiModelProperty(value = "更新时间")
     private Date tkUpdateTime;
-}
+}

+ 1 - 1
src/main/java/com/template/services/SmartDataTaskService.java

@@ -23,7 +23,7 @@ public interface SmartDataTaskService extends IService<SmartDataTask> {
 
     PageUtils<SmartDataTask> queryPageSmartDataTasks(int currentPage, int pageCount, SmartDataTask smartDataTask);
 
-    int deleteSmartDataTaskById(int id);
+    int deleteSmartDataTaskById(SmartDataTask smartDataTask);
 
     SmartDataTask getSmartById(int id);
 

+ 229 - 40
src/main/java/com/template/services/impl/SmartDataTaskServiceImpl.java

@@ -14,6 +14,7 @@ import com.template.model.pojo.SmartDataTask;
 import com.template.model.result.CommonResult;
 import com.template.model.result.PageUtils;
 import com.template.services.SmartDataTaskService;
+import lombok.val;
 import org.quartz.CronExpression;
 import org.quartz.JobKey;
 import org.quartz.Scheduler;
@@ -23,7 +24,12 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
 import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * <p>
@@ -58,33 +64,68 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
             return CommonUtil.getReturnMap("1", "任务名有重名!");
         }
         // 检测必要参数是否为null
-        if (smartDataTask.getTkDsId() == null) {
-            return CommonUtil.getReturnMap("1", "【数据源id】不能为空!");
+        if (smartDataTask.getTkDsIdSource() == null) {
+            return CommonUtil.getReturnMap("1", "【来源数据源id】不能为空!");
         }
-        SmartDataSource smartDataSource = smartDataSourceMapper.selectById(smartDataTask.getTkDsId());
+        SmartDataSource smartDataSource = smartDataSourceMapper.selectById(smartDataTask.getTkDsIdSource());
         if (smartDataSource == null) {
-            return CommonUtil.getReturnMap("1", "选择的【数据源】不存在!");
+            return CommonUtil.getReturnMap("1", "选择的【来源数据源】不存在!");
         }
-        if (smartDataTask.getTkCron() == null) {
-            return CommonUtil.getReturnMap("1", "【定时表达式】不能为空!");
+        if (smartDataTask.getTkSyncPolicy() == null) {
+            return CommonUtil.getReturnMap("1", "【同步策略】不能为空!");
         }
-        if (CronExpression.isValidExpression(smartDataTask.getTkCron())) {
-            return CommonUtil.getReturnMap("1", "【定时表达式】不正确!");
+        if (smartDataTask.getTkExchangeType() == null) {
+            return CommonUtil.getReturnMap("1", "【交换方式】不能为空!");
         }
         if (smartDataTask.getTkSql() == null) {
-            return CommonUtil.getReturnMap("1", "【任务sql】不能为空!");
+            return CommonUtil.getReturnMap("1", "【数据来源SQL语句】不能为空!");
+        }
+        if (smartDataTask.getTkDsIdDestination() == null) {
+            return CommonUtil.getReturnMap("1", "【目标数据源id】不能为空!");
+        }
+        smartDataSource = smartDataSourceMapper.selectById(smartDataTask.getTkDsIdDestination());
+        if (smartDataSource == null) {
+            return CommonUtil.getReturnMap("1", "选择的【目标数据源】不存在!");
+        }
+        if (smartDataTask.getTkDestTable() == null) {
+            return CommonUtil.getReturnMap("1", "【目标数据表】不能为空!");
+        }
+        if (smartDataTask.getTkManualOrAuto() == null) {
+            return CommonUtil.getReturnMap("1", "【手动或定时执行】不能为空!");
+        }
+        if (smartDataTask.getTkManualOrAuto() == 0) {
+            if (smartDataTask.getTkExeType() == null) {
+                return CommonUtil.getReturnMap("1", "【执行方式】不能为空!");
+            }
+            if (smartDataTask.getTkRepetTime() == null) {
+                return CommonUtil.getReturnMap("1", "【重复时间】不能为空!");
+            }
+            // 生成cron表达式
+            Map<String, Object> stringObjectMap = generateCron(smartDataTask.getTkExeType(), smartDataTask.getTkRepetTime());
+            if (stringObjectMap.get("code") == "1") {
+                return stringObjectMap;
+            }
+            String cron = (String) stringObjectMap.get("msg");
+            if (CronExpression.isValidExpression(cron)) {
+                smartDataTask.setTkCron(cron);
+            } else {
+                return CommonUtil.getReturnMap("1", "生成的【定时表达式】不正确!请联系管理员!" + cron);
+            }
+        } else {
+            smartDataTask.setTkExeType(-1);
+            smartDataTask.setTkRepetTime("");
         }
         if (smartDataTask.getTkDescrition() == null) {
             return CommonUtil.getReturnMap("1", "【任务描述】不能为空!");
         }
-        if (smartDataTask.getTkActivation() == null) {
-            return CommonUtil.getReturnMap("1", "【是否启用】不能为空!");
-        }
-        queryWrapper.eq(smartDataTask.getTkDsId() != null, "tk_ds_id", smartDataTask.getTkDsId());
-        queryWrapper.eq(StringUtils.hasText(smartDataTask.getTkCron()), "tk_cron", smartDataTask.getTkCron());
+        queryWrapper.eq(smartDataTask.getTkDsIdSource() != null, "tk_ds_id_source", smartDataTask.getTkDsIdSource());
+        queryWrapper.eq(smartDataTask.getTkSyncPolicy() != null, "tk_sync_policy", smartDataTask.getTkSyncPolicy());
+        queryWrapper.eq(smartDataTask.getTkExchangeType() != null, "tk_exchange_type", smartDataTask.getTkExchangeType());
         queryWrapper.eq(StringUtils.hasText(smartDataTask.getTkSql()), "tk_sql", smartDataTask.getTkSql());
+        queryWrapper.eq(smartDataTask.getTkDsIdDestination() != null, "tk_ds_id_destination", smartDataTask.getTkDsIdDestination());
+        queryWrapper.eq(smartDataTask.getTkDestTable() != null, "tk_dest_table", smartDataTask.getTkDestTable());
+        queryWrapper.eq(smartDataTask.getTkManualOrAuto() != null, "tk_manual_or_auto", smartDataTask.getTkManualOrAuto());
         queryWrapper.eq(StringUtils.hasText(smartDataTask.getTkDescrition()), "tk_descrition", smartDataTask.getTkDescrition());
-        queryWrapper.eq(smartDataTask.getTkActivation() != null, "tk_activation", smartDataTask.getTkActivation());
         sdt = smartDataTaskMapper.selectOne(queryWrapper);
         if (sdt != null) {
             return CommonUtil.getReturnMap("1", "有重复记录!");
@@ -98,6 +139,117 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
         }
     }
 
+    // 生成cron表达式
+    private Map<String, Object> generateCron(Integer exeType, String repetTime) {
+        if (exeType == 0) {
+            if (repetTime.endsWith("天")) {
+                String n = CommonUtil.getNumberFromString(repetTime);
+                if (n != null) {
+                    return CommonUtil.getReturnMap("0", "0 0 0 1/" + n + " * ?");
+                } else {
+                    return CommonUtil.getReturnMap("1", "【重复时间】格式错误,要求:x天");
+                }
+            } else if (repetTime.endsWith("小时")) {
+                String n = CommonUtil.getNumberFromString(repetTime);
+                if (n != null) {
+                    return CommonUtil.getReturnMap("0", "0 0 0/" + n + " * * ?");
+                } else {
+                    return CommonUtil.getReturnMap("1", "【重复时间】格式错误,要求:x小时");
+                }
+            } else if (repetTime.endsWith("分钟")) {
+                String n = CommonUtil.getNumberFromString(repetTime);
+                if (n != null) {
+                    return CommonUtil.getReturnMap("0", "0 0/" + n + " * * * ?");
+                } else {
+                    return CommonUtil.getReturnMap("1", "【重复时间】格式错误,要求:x分钟");
+                }
+            } else {
+                return CommonUtil.getReturnMap("1", "【重复时间】格式错误,要求:x天 或者 x小时 或者 x分钟");
+            }
+        } else if (exeType == 1) {
+            // 检查是否是格式:2023-12-19 09:40
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+            try {
+                LocalDateTime dateTime = LocalDateTime.parse(repetTime, formatter);
+                int year = dateTime.getYear();
+                int month = dateTime.getMonthValue();
+                int day = dateTime.getDayOfMonth();
+                int hour = dateTime.getHour();
+                int minute = dateTime.getMinute();
+
+                return CommonUtil.getReturnMap("0", String.format("0 %d %d %d %d ? %d", minute, hour, day, month, year));
+            } catch (DateTimeParseException e) {
+                return CommonUtil.getReturnMap("1", "【重复时间】格式错误,要求:2023-12-19 09:40");
+            }
+        } else if (exeType == 2) {
+            // 检查是否是格式:09:40
+            if (isOnlyHourAndMinute(repetTime)) {
+                String[] split = repetTime.split(":");
+                int hour = Integer.parseInt(split[0]);
+                int minute = Integer.parseInt(split[1]);
+                return CommonUtil.getReturnMap("0", String.format("0 %d %d 1/1 * ?", minute, hour));
+            } else {
+                return CommonUtil.getReturnMap("1", "【重复时间】格式错误,要求:09:40");
+            }
+        } else if (exeType == 3) {
+            // 检查是否是格式:周日 09:40
+            String[] split = repetTime.split(" ");
+            if (split.length != 2) {
+                return CommonUtil.getReturnMap("1", "【重复时间】格式错误1,要求:周日 09:40");
+            }
+
+            String weekday = ""; // MON, TUE, WED, THU, FRI, SAT, SUN
+            if ("周一".equals(split[0])) weekday = "MON";
+            else if ("周二".equals(split[0])) weekday = "TUE";
+            else if ("周三".equals(split[0])) weekday = "WED";
+            else if ("周四".equals(split[0])) weekday = "THU";
+            else if ("周五".equals(split[0])) weekday = "FRI";
+            else if ("周六".equals(split[0])) weekday = "SAT";
+            else if ("周日".equals(split[0])) weekday = "SUN";
+            else CommonUtil.getReturnMap("1", "【重复时间】格式错误2,要求:周日 09:40");
+
+            if (isOnlyHourAndMinute(split[1])) {
+                String[] hour_minute = split[1].split(":");
+                int hour = Integer.parseInt(hour_minute[0]);
+                int minute = Integer.parseInt(hour_minute[1]);
+
+                return CommonUtil.getReturnMap("0", String.format("0 %d %d ? * %s", minute, hour, weekday));
+            } else  {
+                return CommonUtil.getReturnMap("1", "【重复时间】格式错误3,要求:周日 09:40");
+            }
+        } else if (exeType == 4) {
+            // 检查是否是格式:19 09:40
+            String[] split = repetTime.split(" ");
+            if (split.length != 2) {
+                return CommonUtil.getReturnMap("1", "【重复时间】格式错误1,要求:19 09:40");
+            }
+
+            int day = Integer.parseInt(split[0]);
+            if (day > 30 || day < 1)
+                CommonUtil.getReturnMap("1", "【重复时间】格式错误2,要求:19 09:40");
+
+            if (isOnlyHourAndMinute(split[1])) {
+                String[] hour_minute = split[1].split(":");
+                int hour = Integer.parseInt(hour_minute[0]);
+                int minute = Integer.parseInt(hour_minute[1]);
+
+                return CommonUtil.getReturnMap("0", String.format("0 %d %d %d * ?", minute, hour, day));
+            } else  {
+                return CommonUtil.getReturnMap("1", "【重复时间】格式错误3,要求:19 09:40");
+            }
+        } else {
+            return CommonUtil.getReturnMap("1", "【执行方式】格式错误,要求:0间隔执行,1定点执行,2每天,3每周,4每月");
+        }
+    }
+
+    // 判断时分
+    private boolean isOnlyHourAndMinute(String time) {
+        String regex = "^([01]?[0-9]|2[0-3]):[0-5][0-9]$";
+        Pattern pattern = Pattern.compile(regex);
+        Matcher matcher = pattern.matcher(time);
+        return matcher.matches();
+    }
+
     @Override
     public Map<String, Object> updateSmartDataTaskById(SmartDataTask smartDataTask) {
         if (smartDataTask.getTkId() == null) {
@@ -115,36 +267,65 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
         if (sdc == null) {
             return CommonUtil.getReturnMap("1", "要修改的【任务】不存在!");
         }
-        if (smartDataTask.getTkDsId() == null) {
-            return CommonUtil.getReturnMap("1", "【数据源id】不能为空!");
+        if (smartDataTask.getTkDsIdSource() == null) {
+            return CommonUtil.getReturnMap("1", "【来源数据源id】不能为空!");
         }
-        SmartDataSource smartDataSource = smartDataSourceMapper.selectById(smartDataTask.getTkDsId());
+        SmartDataSource smartDataSource = smartDataSourceMapper.selectById(smartDataTask.getTkDsIdSource());
         if (smartDataSource == null) {
-            return CommonUtil.getReturnMap("1", "选择的【数据源】不存在!");
+            return CommonUtil.getReturnMap("1", "选择的【来源数据源】不存在!");
         }
-        if (smartDataTask.getTkCron() == null) {
-            return CommonUtil.getReturnMap("1", "【定时表达式】不能为空!");
+        if (smartDataTask.getTkSyncPolicy() == null) {
+            return CommonUtil.getReturnMap("1", "【同步策略】不能为空!");
         }
-        if (CronExpression.isValidExpression(smartDataTask.getTkCron())) {
-            return CommonUtil.getReturnMap("1", "【定时表达式】不正确!");
+        if (smartDataTask.getTkExchangeType() == null) {
+            return CommonUtil.getReturnMap("1", "【交换方式】不能为空!");
         }
         if (smartDataTask.getTkSql() == null) {
-            return CommonUtil.getReturnMap("1", "【任务sql】不能为空!");
+            return CommonUtil.getReturnMap("1", "【数据来源SQL语句】不能为空!");
+        }
+        if (smartDataTask.getTkDsIdDestination() == null) {
+            return CommonUtil.getReturnMap("1", "【目标数据源id】不能为空!");
+        }
+        smartDataSource = smartDataSourceMapper.selectById(smartDataTask.getTkDsIdDestination());
+        if (smartDataSource == null) {
+            return CommonUtil.getReturnMap("1", "选择的【目标数据源】不存在!");
+        }
+        if (smartDataTask.getTkDestTable() == null) {
+            return CommonUtil.getReturnMap("1", "【目标数据表】不能为空!");
+        }
+        if (smartDataTask.getTkManualOrAuto() == null) {
+            return CommonUtil.getReturnMap("1", "【手动或定时执行】不能为空!");
+        }
+        if (smartDataTask.getTkManualOrAuto() == 0) {
+            if (smartDataTask.getTkExeType() == null) {
+                return CommonUtil.getReturnMap("1", "【执行方式】不能为空!");
+            }
+            if (smartDataTask.getTkRepetTime() == null) {
+                return CommonUtil.getReturnMap("1", "【重复时间】不能为空!");
+            }
+            // 生成cron表达式
+            Map<String, Object> stringObjectMap = generateCron(smartDataTask.getTkExeType(), smartDataTask.getTkRepetTime());
+            if (stringObjectMap.get("code") == "1") {
+                return stringObjectMap;
+            }
+            smartDataTask.setTkCron((String) stringObjectMap.get("msg"));
+        } else {
+            smartDataTask.setTkExeType(0);
+            smartDataTask.setTkRepetTime("");
         }
         if (smartDataTask.getTkDescrition() == null) {
             return CommonUtil.getReturnMap("1", "【任务描述】不能为空!");
         }
-        if (smartDataTask.getTkActivation() == null) {
-            return CommonUtil.getReturnMap("1", "【是否启动】不能为空!");
-        }
         QueryWrapper<SmartDataTask> queryWrapper = new QueryWrapper<>();
-        queryWrapper.eq(smartDataTask.getTkId() != null, "tk_id", smartDataTask.getTkId());
-        queryWrapper.eq(smartDataTask.getTkDsId() != null, "tk_ds_id", smartDataTask.getTkDsId());
         queryWrapper.eq(smartDataTask.getTkName() != null, "tk_name", smartDataTask.getTkName());
-        queryWrapper.eq(StringUtils.hasText(smartDataTask.getTkCron()), "tk_cron", smartDataTask.getTkCron());
+        queryWrapper.eq(smartDataTask.getTkDsIdSource() != null, "tk_ds_id_source", smartDataTask.getTkDsIdSource());
+        queryWrapper.eq(smartDataTask.getTkSyncPolicy() != null, "tk_sync_policy", smartDataTask.getTkSyncPolicy());
+        queryWrapper.eq(smartDataTask.getTkExchangeType() != null, "tk_exchange_type", smartDataTask.getTkExchangeType());
         queryWrapper.eq(StringUtils.hasText(smartDataTask.getTkSql()), "tk_sql", smartDataTask.getTkSql());
+        queryWrapper.eq(smartDataTask.getTkDsIdDestination() != null, "tk_ds_id_destination", smartDataTask.getTkDsIdDestination());
+        queryWrapper.eq(smartDataTask.getTkDestTable() != null, "tk_dest_table", smartDataTask.getTkDestTable());
+        queryWrapper.eq(smartDataTask.getTkManualOrAuto() != null, "tk_manual_or_auto", smartDataTask.getTkManualOrAuto());
         queryWrapper.eq(StringUtils.hasText(smartDataTask.getTkDescrition()), "tk_descrition", smartDataTask.getTkDescrition());
-        queryWrapper.eq(smartDataTask.getTkActivation() != null, "tk_activation", smartDataTask.getTkActivation());
         SmartDataTask sdt = smartDataTaskMapper.selectOne(queryWrapper);
         if (sdt != null) {
             return CommonUtil.getReturnMap("1", "数据未修改,请修改后再提交!");
@@ -159,7 +340,7 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
     }
 
     // 判断之前状态是否启用
-    private Map<String, Object> updateSmartDataTaskActivation(SmartDataTask smartDataTask) {
+    public Map<String, Object> updateSmartDataTaskActivation(SmartDataTask smartDataTask) {
         // 检测参数,还有是否存在重复记录
         if (smartDataTask.getTkId() == null) {
             return CommonUtil.getReturnMap("1", "【任务id】不能为空!");
@@ -172,7 +353,7 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
             return CommonUtil.getReturnMap("1", "【是否启用】不能为空!");
         }
 
-        int result = smartDataTaskMapper.updateById(smartDataTask);
+        int result = smartDataTaskMapper.markTaskById(smartDataTask);
         if (result > 0) {
             return CommonUtil.getReturnMap(String.valueOf(result), "标注成功!");
         } else {
@@ -188,8 +369,12 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
     public PageUtils<SmartDataTask> queryPageSmartDataTasks(int currentPage, int pageCount, SmartDataTask smartDataTask) {
         Page<SmartDataTask> page = new Page<>(currentPage, pageCount);
         QueryWrapper<SmartDataTask> queryWrapper = new QueryWrapper<>();
-        queryWrapper.eq(smartDataTask.getTkDsId() != null, "tk_ds_id", smartDataTask.getTkDsId());
         queryWrapper.like(smartDataTask.getTkName() != null, "tk_name", smartDataTask.getTkName());
+        queryWrapper.eq(smartDataTask.getTkDsIdSource() != null, "tk_ds_id_source", smartDataTask.getTkDsIdSource());
+        queryWrapper.eq(smartDataTask.getTkDsIdDestination() != null, "tk_ds_id_destination", smartDataTask.getTkDsIdDestination());
+        queryWrapper.eq(smartDataTask.getTkExchangeType() != null, "tk_exchange_type", smartDataTask.getTkExchangeType());
+        queryWrapper.eq(smartDataTask.getTkExeType() != null, "tk_exe_type", smartDataTask.getTkExeType());
+        queryWrapper.like(smartDataTask.getTkDestTable() != null, "tk_dest_table", smartDataTask.getTkDestTable());
         queryWrapper.eq(smartDataTask.getTkActivation() != null, "tk_activation", smartDataTask.getTkActivation());
         queryWrapper.like(smartDataTask.getTkDescrition() != null, "tk_descrition", smartDataTask.getTkDescrition());
         queryWrapper.orderByDesc("tk_update_time");
@@ -198,18 +383,16 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
     }
 
     @Override
-    public int deleteSmartDataTaskById(int id) {
-        int result = smartDataTaskMapper.deleteById(id);
-        return result;
+    public int deleteSmartDataTaskById(SmartDataTask smartDataTask) {
+        return smartDataTaskMapper.deleteMarkTaskById(smartDataTask);
     }
 
     @Override
     public SmartDataTask getSmartById(int id) {
-        SmartDataTask result = smartDataTaskMapper.selectById(id);
-        return result;
+        return smartDataTaskMapper.selectById(id);
     }
 
-    private Map<String, Object> TaskNameValidator(SmartDataTask smartDataTask) {
+    public Map<String, Object> TaskNameValidator(SmartDataTask smartDataTask) {
         if (smartDataTask.getTkName() == null) {
             return CommonUtil.getReturnMap(String.valueOf(1), "任务名称为空!");
         }
@@ -234,6 +417,10 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
         Map<String, Object> returnMap = QuartzJobUtils.createScheduleJob(scheduler, smartDataTask_return);
         if ("0".equals(returnMap.get("code"))) {
             smartDataTask.setTkId(smartDataTask_return.getTkId());
+            // 下次执行的时间
+            String nextExeTime = QuartzJobUtils.getNextExeTime(smartDataTask_return.getTkCron());
+            // 更新数据库中的下次执行时间
+            smartDataTask.setTkNextExeTime(nextExeTime);
             smartDataTask.setTkActivation(1);
             Map<String, Object> stringStringMap = updateSmartDataTaskActivation(smartDataTask);
             String msg;
@@ -296,6 +483,8 @@ public class SmartDataTaskServiceImpl extends ServiceImpl<SmartDataTaskMapper, S
         Map<String, Object> returnMap = QuartzJobUtils.deleteScheduleJob(scheduler, smartDataTask_return.getTkName());
         if ("0".equals(returnMap.get("code"))) {
             smartDataTask.setTkId(smartDataTask_return.getTkId());
+            // 更新数据库中的下次执行时间
+            smartDataTask.setTkNextExeTime(null);
             smartDataTask.setTkActivation(0);
             Map<String, Object> stringStringMap = updateSmartDataTaskActivation(smartDataTask);
             String msg;