Prechádzať zdrojové kódy

更新了调度逻辑

“lifuquan” 1 rok pred
rodič
commit
621c887e72
28 zmenil súbory, kde vykonal 248 pridanie a 1289 odobranie
  1. 7 7
      doc/开发环境/2023年适配/2024年适配.md
  2. BIN
      doc/数据订阅/能力商店/河北客户体验管理系统移网网络体验明细日信息/.~XLSX 工作表.xlsx
  3. BIN
      doc/数据订阅/能力商店/河北客户体验管理系统移网网络体验明细日信息/河北客户体验管理系统移网网络体验明细日信息_HE_D_CEM_MOBILE_EXPERIENCE_LIST.xlsx
  4. 24 0
      src/main/java/com/nokia/tsl_data/config/SpringContextHolder.java
  5. 2 0
      src/main/java/com/nokia/tsl_data/config/TslDataConfig.java
  6. 0 52
      src/main/java/com/nokia/tsl_data/scheduling/controller/RegisteredTaskController.java
  7. 0 79
      src/main/java/com/nokia/tsl_data/scheduling/controller/ScheduledTaskController.java
  8. 0 42
      src/main/java/com/nokia/tsl_data/scheduling/dao/DatabaseInitializeMapper.java
  9. 0 50
      src/main/java/com/nokia/tsl_data/scheduling/dao/RegisteredTaskMapper.java
  10. 0 101
      src/main/java/com/nokia/tsl_data/scheduling/dao/ScheduledTaskMapper.java
  11. 0 77
      src/main/java/com/nokia/tsl_data/scheduling/dao/handler/JsonTypeHandler.java
  12. 0 13
      src/main/java/com/nokia/tsl_data/scheduling/entity/OperateRecord.java
  13. 0 23
      src/main/java/com/nokia/tsl_data/scheduling/entity/RegisteredTask.java
  14. 75 0
      src/main/java/com/nokia/tsl_data/scheduling/entity/RunnableTask.java
  15. 0 41
      src/main/java/com/nokia/tsl_data/scheduling/entity/ScheduledTask.java
  16. 0 37
      src/main/java/com/nokia/tsl_data/scheduling/entity/_enum/ScheduledStatus.java
  17. 0 23
      src/main/java/com/nokia/tsl_data/scheduling/entity/_enum/ScheduledType.java
  18. 0 39
      src/main/java/com/nokia/tsl_data/scheduling/entity/pojo/CallableTask.java
  19. 0 67
      src/main/java/com/nokia/tsl_data/scheduling/entity/pojo/RunnableTask.java
  20. 0 52
      src/main/java/com/nokia/tsl_data/scheduling/entity/pojo/ScheduledParameter.java
  21. 0 28
      src/main/java/com/nokia/tsl_data/scheduling/service/DatabaseInitializeService.java
  22. 0 112
      src/main/java/com/nokia/tsl_data/scheduling/service/RegisteredTaskService.java
  23. 0 178
      src/main/java/com/nokia/tsl_data/scheduling/service/SchedulingService.java
  24. 0 59
      src/main/java/com/nokia/tsl_data/scheduling/service/TaskAutoManagementService.java
  25. 84 168
      src/main/java/com/nokia/tsl_data/scheduling/service/TaskScheduleService.java
  26. 18 0
      src/main/java/com/nokia/tsl_data/service/DataWarehouseService.java
  27. 11 0
      src/main/java/com/nokia/tsl_data/service/ManagementDetailService.java
  28. 27 41
      src/main/java/com/nokia/tsl_data/service/TaskService.java

+ 7 - 7
doc/开发环境/2023年适配/2024年适配.md

@@ -157,7 +157,7 @@ from t1 group by real_name order by real_name
 POST http://192.168.10.7:22222/tsl_data/report/generate/v3
 Content-Type: application/json
 
-20240103
+20240104
 ```
 
 ### 2. 数据入库
@@ -168,7 +168,7 @@ Content-Type: application/json
 POST http://192.168.10.7:22222/tsl_data/source/warehouse/mobile_complaint
 Content-Type: application/json
 
-20240102
+20240104
 ```
 
 ### 2.2 high_quality_count
@@ -177,7 +177,7 @@ Content-Type: application/json
 POST http://192.168.10.7:22222/tsl_data/source/warehouse/high_quality_count
 Content-Type: application/json
 
-20240102
+20240104
 ```
 
 ### 2.3 high_quality_list
@@ -186,7 +186,7 @@ Content-Type: application/json
 POST http://192.168.10.7:22222/tsl_data/source/warehouse/high_quality_list
 Content-Type: application/json
 
-20240102
+20240104
 ```
 
 ### 2.4 complaint_details_fix_ywd
@@ -195,7 +195,7 @@ Content-Type: application/json
 POST http://192.168.10.7:22222/tsl_data/source/warehouse/complaint_details_fix_ywd
 Content-Type: application/json
 
-20240102
+20240104
 ```
 
 ### 2.5 management_detail
@@ -204,7 +204,7 @@ Content-Type: application/json
 POST http://192.168.10.7:22222/tsl_data/source/update/management_detail
 Content-Type: application/json
 
-20240102
+20240104
 ```
 
 ### 2.6 highQualityData
@@ -213,7 +213,7 @@ Content-Type: application/json
 POST http://192.168.10.7:22222/tsl_data/source/highQualityData/generate
 Content-Type: application/json
 
-20240102
+20240104
 ```
 
 ### 2.7 work_flow_basic_data

BIN
doc/数据订阅/能力商店/河北客户体验管理系统移网网络体验明细日信息/.~XLSX 工作表.xlsx


BIN
doc/数据订阅/能力商店/河北客户体验管理系统移网网络体验明细日信息/河北客户体验管理系统移网网络体验明细日信息_HE_D_CEM_MOBILE_EXPERIENCE_LIST.xlsx


+ 24 - 0
src/main/java/com/nokia/tsl_data/config/SpringContextHolder.java

@@ -0,0 +1,24 @@
+package com.nokia.tsl_data.config;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * 注入以后可以通过静态方式使用Spring的上下文
+ */
+@Component
+public class SpringContextHolder implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextHolder.applicationContext = applicationContext;
+    }
+    
+    public static Object getBean(String beanName) {
+        return applicationContext.getBean(beanName);
+    }
+}

+ 2 - 0
src/main/java/com/nokia/tsl_data/config/TslDataConfig.java

@@ -13,9 +13,11 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 
 @Configuration
+@EnableScheduling
 @EnableConfigurationProperties({ TslDataProperties.class, DataWarehouseProperties.class, OutputProperties.class,
         TargetProperties.class })
 public class TslDataConfig {

+ 0 - 52
src/main/java/com/nokia/tsl_data/scheduling/controller/RegisteredTaskController.java

@@ -1,52 +0,0 @@
-package com.nokia.tsl_data.scheduling.controller;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.nokia.tsl_data.entity.vo.R;
-import com.nokia.tsl_data.scheduling.entity.RegisteredTask;
-import com.nokia.tsl_data.scheduling.service.RegisteredTaskService;
-
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping("common/scheduling/task/registered")
-public class RegisteredTaskController {
-
-    private final RegisteredTaskService registeredTaskService;
-    private final ObjectMapper objectMapper;
-
-    public RegisteredTaskController(RegisteredTaskService registeredTaskService, ObjectMapper objectMapper) {
-        this.registeredTaskService = registeredTaskService;
-        this.objectMapper = objectMapper;
-    }
-
-    @PostMapping("add")
-    public R add(@RequestBody String body) {
-        try {
-            RegisteredTask registeredTask = objectMapper.readValue(body, RegisteredTask.class);
-            registeredTaskService.add(registeredTask);
-            return R.ok().message("注册成功");
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.error().message(e.getMessage());
-        }
-    }
-
-    @PostMapping("delete")
-    public R delete(@RequestBody Long id) {
-        try {
-            registeredTaskService.deleteById(id);
-            return R.ok().message("删除成功");
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.error().message(e.getMessage());
-        }
-    }
-
-    @PostMapping("list/all")
-    public R listAll() {
-        return R.ok().data(registeredTaskService.listAll());
-    }
-}

+ 0 - 79
src/main/java/com/nokia/tsl_data/scheduling/controller/ScheduledTaskController.java

@@ -1,79 +0,0 @@
-package com.nokia.tsl_data.scheduling.controller;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.nokia.tsl_data.entity.vo.R;
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-import com.nokia.tsl_data.scheduling.service.SchedulingService;
-
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping("common/scheduling/task/scheduled")
-public class ScheduledTaskController {
-
-    private final SchedulingService schedulingService;
-    private final ObjectMapper objectMapper;
-
-    public ScheduledTaskController(SchedulingService schedulingService, ObjectMapper objectMapper) {
-        this.schedulingService = schedulingService;
-        this.objectMapper = objectMapper;
-    }
-
-    @PostMapping("add")
-    public R add(@RequestBody String body) {
-        try {
-            ScheduledTask task = objectMapper.readValue(body, ScheduledTask.class);
-            schedulingService.add(task);
-            return R.ok();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.error().message(e.getMessage());
-        }
-    }
-
-    @PostMapping("delete")
-    public R delete(@RequestBody Long id) {
-        try {
-            schedulingService.deleteById(id);
-            return R.ok();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.error().message(e.getMessage());
-        }
-    }
-
-    @PostMapping("update")
-    public R update(@RequestBody String body) {
-        try {
-            ScheduledTask task = objectMapper.readValue(body, ScheduledTask.class);
-            schedulingService.update(task);
-            return R.ok();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.error().message(e.getMessage());
-        }
-    }
-
-    @PostMapping("list/all")
-    public R listAll() {
-        try {
-            return R.ok().data(schedulingService.listAll());
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.error().message(e.getMessage());
-        }
-    }
-
-    @PostMapping("list/scheduled")
-    public R listScheduled() {
-        try {
-            return R.ok().data(schedulingService.listScheduled());
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.error().message(e.getMessage());
-        }
-    }
-}

+ 0 - 42
src/main/java/com/nokia/tsl_data/scheduling/dao/DatabaseInitializeMapper.java

@@ -1,42 +0,0 @@
-package com.nokia.tsl_data.scheduling.dao;
-
-import org.apache.ibatis.annotations.Insert;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
-import org.apache.ibatis.annotations.Update;
-
-@Mapper
-public interface DatabaseInitializeMapper {
-
-    @Select("select count(1) from information_schema.schemata where schema_name = 'scheduling'")
-    boolean ifSchemaExists();
-
-    @Insert("create schema if not exists scheduling ")
-    int createSchema();
-
-    @Update("CREATE TABLE if not exists scheduling.registered_task (\n" +
-            "    id bigint NOT NULL primary key,\n" +
-            "    bean_name text NOT NULL,\n" +
-            "    method_name text NOT NULL,\n" +
-            "    description text,\n" +
-            "    with_parameter boolean,\n" +
-            "    create_time timestamp without time zone\n" +
-            ")")
-    int createTableRegisteredTask();
-
-    @Update("CREATE TABLE if not exists scheduling.scheduled_task (\n" +
-            "    id bigint NOT NULL primary key,\n" +
-            "    name text NOT NULL,\n" +
-            "    registered_task_id bigint NOT NULL,\n" +
-            "    status text DEFAULT false,\n" +
-            "    method_parameter text,\n" +
-            "    scheduled_type text,\n" +
-            "    scheduled_parameter text,\n" +
-            "    fail_reason text,\n" +
-            "    description text,\n" +
-            "    is_delete boolean DEFAULT false NOT NULL,\n" +
-            "    create_time timestamp without time zone,\n" +
-            "    last_modify timestamp without time zone\n" +
-            ")")
-    int createTableScheduledTask();
-}

+ 0 - 50
src/main/java/com/nokia/tsl_data/scheduling/dao/RegisteredTaskMapper.java

@@ -1,50 +0,0 @@
-package com.nokia.tsl_data.scheduling.dao;
-
-import org.apache.ibatis.annotations.*;
-
-import com.nokia.tsl_data.scheduling.entity.RegisteredTask;
-
-import java.util.List;
-
-/**
- * RegisteredTask 增删查,采用逻辑删除方式
- */
-@Mapper
-public interface RegisteredTaskMapper {
-
-    @Insert("insert into scheduling.registered_task \n" +
-            "(id, bean_name, method_name, description, with_parameter, create_time) VALUES \n" +
-            "(#{id}, #{beanName}, #{methodName}, #{description}, #{withParameter}, now())")
-    int insertOne(RegisteredTask registeredTask);
-
-    @Results(id = "registeredTaskResults", value = {
-            @Result(property = "id", column = "id", id = true),
-            @Result(property = "beanName", column = "bean_name"),
-            @Result(property = "methodName", column = "method_name"),
-            @Result(property = "description", column = "description"),
-            @Result(property = "withParameter", column = "with_parameter"),
-            @Result(property = "createTime", column = "create_time")
-    })
-    @Select("select * from scheduling.registered_task \n" +
-            "where bean_name = #{beanName} and method_name = #{methodName}")
-    RegisteredTask selectByBeanNameAndMethodName(@Param("beanName") String beanName, @Param("methodName") String methodName);
-
-    default RegisteredTask selectByBeanNameAndMethodName(RegisteredTask registeredTask) {
-        return selectByBeanNameAndMethodName(registeredTask.getBeanName(), registeredTask.getMethodName());
-    }
-
-    @ResultMap("registeredTaskResults")
-    @Select("select * from scheduling.registered_task where id = #{id}")
-    RegisteredTask selectById(long id);
-
-    @ResultMap("registeredTaskResults")
-    @Select("select * from scheduling.registered_task order by id ")
-    List<RegisteredTask> selectAll();
-
-    @Delete("delete from scheduling.registered_task where id = #{id}")
-    int deleteById(long id);
-
-    @ResultMap("registeredTaskResults")
-    @Select("select * from scheduling.registered_task where name = #{name}")
-    RegisteredTask selectByName(String name);
-}

+ 0 - 101
src/main/java/com/nokia/tsl_data/scheduling/dao/ScheduledTaskMapper.java

@@ -1,101 +0,0 @@
-package com.nokia.tsl_data.scheduling.dao;
-
-import org.apache.ibatis.annotations.*;
-import org.apache.ibatis.mapping.FetchType;
-import org.apache.ibatis.type.JdbcType;
-
-import com.nokia.tsl_data.scheduling.dao.handler.JsonTypeHandler;
-import com.nokia.tsl_data.scheduling.entity.RegisteredTask;
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-
-import java.util.List;
-
-/**
- * 使用逻辑删除方式 is_delete字段为逻辑删除标识
- */
-@Mapper
-public interface ScheduledTaskMapper {
-
-    @Insert("insert into scheduling.scheduled_task (id, name, registered_task_id, status, method_parameter, scheduled_type, " +
-            "scheduled_parameter, fail_reason, description, create_time, last_modify) values " +
-            "(#{id}, #{name}, #{registeredTask.id}, #{status}, #{methodParameter}, #{scheduledType}, " +
-            "#{scheduledParameter, jdbcType=VARCHAR, typeHandler=com.nokia.tsl_data.scheduling.dao.handler.JsonTypeHandler}," +
-            "#{failReason}, #{description}, now(), now())")
-    int insertOne(ScheduledTask scheduledTask);
-
-    @Update("<script> update scheduling.scheduled_task set " +
-            "<if test = \"registeredTask != null and registeredTask.id != null \"> " +
-            "registered_task_id = #{registeredTask.id}, </if> " +
-            "<if test = \"status != null \"> status = #{status}, </if> " +
-            "<if test = \"methodParameter != null and methodParameter != '' \"> " +
-            "method_parameter = #{methodParameter}, </if> " +
-            "<if test = \"scheduledType != null\"> scheduled_type = #{scheduledType}, </if> " +
-            "<if test = \"scheduledParameter != null\"> scheduled_parameter = " +
-            "#{scheduledParameter, jdbcType=VARCHAR, typeHandler=com.nokia.tsl_data.scheduling.dao.handler.JsonTypeHandler}, </if> " +
-            "<if test = \"failReason != null\"> fail_reason = #{failReason}, </if> " +
-            "<if test = \"description != null\"> description = #{description}, </if> " +
-            "is_delete = false, last_modify = now() where id = #{id} </script>")
-    int insertOneExists(ScheduledTask scheduledTask);
-
-    @Update("update scheduling.scheduled_task set is_delete = true, last_modify = now() where id = #{id}")
-    int deleteById(long id);
-
-    @Update("<script> update scheduling.scheduled_task <set> " +
-            "<if test = \"name != null and name != '' \"> name = #{name}, </if> " +
-            "<if test = \"registeredTask != null and registeredTask.id != null \"> " +
-            "registered_task_id = #{registeredTask.id}, </if> " +
-            "<if test = \"status != null \"> status = #{status}, </if> " +
-            "<if test = \"methodParameter != null and methodParameter != '' \"> " +
-            "method_parameter = #{methodParameter}, </if> " +
-            "<if test = \"scheduledType != null\"> scheduled_type = #{scheduledType}, </if> " +
-            "<if test = \"scheduledParameter != null\"> scheduled_parameter = " +
-            "#{scheduledParameter, jdbcType=VARCHAR, typeHandler=com.nokia.tsl_data.scheduling.dao.handler.JsonTypeHandler}, </if> " +
-            "<if test = \"failReason != null\"> fail_reason = #{failReason}, </if> " +
-            "<if test = \"description != null\"> description = #{description}, </if> " +
-            "last_modify = now() </set> where id = #{id} </script>")
-    int updateById(ScheduledTask scheduledTask);
-
-    @Results(id = "scheduledTaskResults", value = {
-            @Result(property = "id", column = "id", id = true),
-            @Result(property = "name", column = "name"),
-            @Result(property = "registeredTask", column = "registered_task_id", javaType = RegisteredTask.class,
-                    one = @One(select = "com.nokia.tsl_data.scheduling.dao.RegisteredTaskMapper.selectById", fetchType = FetchType.EAGER)),
-            @Result(property = "status", column = "status"),
-            @Result(property = "methodParameter", column = "method_parameter"),
-            @Result(property = "scheduledType", column = "scheduled_type"),
-            @Result(property = "scheduledParameter", column = "scheduled_parameter", jdbcType = JdbcType.VARCHAR, typeHandler = JsonTypeHandler.class),
-            @Result(property = "failReason", column = "fail_reason"),
-            @Result(property = "description", column = "description"),
-            @Result(property = "createTime", column = "create_time"),
-            @Result(property = "lastModify", column = "last_modify")
-    })
-    @Select("select * from scheduling.scheduled_task where is_delete = false order by id ")
-    List<ScheduledTask> selectAll();
-
-    @ResultMap("scheduledTaskResults")
-    @Select("select * from scheduling.scheduled_task where id = #{id} and is_delete = false limit 1 ")
-    ScheduledTask selectById(long id);
-
-    @ResultMap("scheduledTaskResults")
-    @Select("select * from scheduling.scheduled_task where name = #{name} and is_delete = false limit 1 ")
-    ScheduledTask selectByName(String name);
-
-    @Select("select id from scheduling.scheduled_task where name = #{name} and is_delete = false limit 1 ")
-    Long selectIdByName(String name);
-
-    @Select("select id from scheduling.scheduled_task where name = #{name} and is_delete = true limit 1 ")
-    Long selectDeletedIdByName(String name);
-
-    @Select("select count(1) from scheduling.scheduled_task where id = #{id} ")
-    boolean isIdExists(long id);
-
-    @Select("select count(1) from scheduling.scheduled_task where id = #{id} and is_delete = true ")
-    boolean isIdDeleted(long id);
-
-    /**
-     * 选择需要初始化的任务
-     */
-    @ResultMap("scheduledTaskResults")
-    @Select("select * from scheduling.scheduled_task where is_delete = false and status = 'ON' order by id")
-    List<ScheduledTask> selectTaskToInit();
-}

+ 0 - 77
src/main/java/com/nokia/tsl_data/scheduling/dao/handler/JsonTypeHandler.java

@@ -1,77 +0,0 @@
-package com.nokia.tsl_data.scheduling.dao.handler;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import org.apache.ibatis.type.BaseTypeHandler;
-import org.apache.ibatis.type.JdbcType;
-
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * 用于在mybatis中将java类型转化成json字符串存入数据库和从数据库读取json数据转化为java类型
- * 无法转化集合类型
- */
-public class JsonTypeHandler<T> extends BaseTypeHandler<T> {
-
-    private static final ObjectMapper MAPPER = new ObjectMapper();
-
-    static {
-        JavaTimeModule module = new JavaTimeModule();
-        MAPPER.registerModule(module);
-    }
-
-    private final Class<T> clz;
-
-    public JsonTypeHandler(Class<T> clz) {
-        this.clz = clz;
-    }
-
-    @Override
-    public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
-        if (columnName == null || columnName.isEmpty()) {
-            return null;
-        }
-        return toObject(resultSet.getString(columnName), clz);
-    }
-
-    @Override
-    public T getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
-        return toObject(resultSet.getString(columnIndex), clz);
-    }
-
-    @Override
-    public T getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
-        return toObject(callableStatement.getString(columnIndex), clz);
-    }
-
-    @Override
-    public void setNonNullParameter(PreparedStatement preparedStatement, int columnIndex, T parameter,
-                                    JdbcType jdbcType)
-            throws SQLException {
-        preparedStatement.setString(columnIndex, toJson(parameter));
-    }
-
-    private String toJson(T parameter) {
-        try {
-            return MAPPER.writeValueAsString(parameter);
-        } catch (JsonProcessingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private T toObject(String content, Class<T> clz) {
-        if (content == null || content.isEmpty()) {
-            return null;
-        }
-        try {
-            return MAPPER.readValue(content, clz);
-        } catch (JsonProcessingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}

+ 0 - 13
src/main/java/com/nokia/tsl_data/scheduling/entity/OperateRecord.java

@@ -1,13 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity;
-
-import lombok.Data;
-
-/**
- * 操作记录
- */
-@Data
-public class OperateRecord {
-
-    private Long id;
-    private String operate;
-}

+ 0 - 23
src/main/java/com/nokia/tsl_data/scheduling/entity/RegisteredTask.java

@@ -1,23 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity;
-
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-import java.time.Instant;
-
-/**
- * 已注册的任务 对应数据库表 scheduling.registered_task
- * 只增删,不更新,使用物理删除方式
- */
-@Data
-@Accessors(chain = true)
-public class RegisteredTask {
-
-    private Long id;
-    private String beanName;
-    private String methodName;
-    // 是否携带参数 默认不带参
-    private Boolean withParameter = false;
-    private String description;
-    private Instant createTime;
-}

+ 75 - 0
src/main/java/com/nokia/tsl_data/scheduling/entity/RunnableTask.java

@@ -0,0 +1,75 @@
+package com.nokia.tsl_data.scheduling.entity;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.StringUtils;
+
+import com.nokia.tsl_data.config.SpringContextHolder;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Data
+@Accessors(chain = true)
+public class RunnableTask implements Runnable {
+
+    private String taskId = "";
+    private String beanName;
+    private String methodName;
+    private String methodParameter = "";
+    private Long delay = 0L;
+
+    @Override
+    public void run() {
+        try {
+            Object bean = SpringContextHolder.getBean(beanName);
+            Method method;
+            if (StringUtils.hasLength(methodParameter)) {
+                method = bean.getClass().getMethod(methodName, String.class);
+                ReflectionUtils.makeAccessible(method);
+                method.invoke(bean, methodParameter);
+            } else {
+                method = bean.getClass().getMethod(methodName);
+                ReflectionUtils.makeAccessible(method);
+                method.invoke(bean);
+            }
+        } catch (NoSuchMethodException e) {
+            log.error("未找到方法: {}.{}()", beanName, methodName);
+            e.printStackTrace();
+        } catch (SecurityException e) {
+            log.error("{}.{}() 方法报错 SecurityException", beanName, methodName);
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            log.error("{}.{}() 方法不允许访问", beanName, methodName);
+            e.printStackTrace();
+        } catch (IllegalArgumentException e) {
+            log.error("{}.{}() 方法参数错误", beanName, methodName);
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            log.error("{}.{}() 方法执行出错:{}", beanName, methodName, e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof RunnableTask))
+            return false;
+        RunnableTask t = (RunnableTask) o;
+        return taskId.equals(t.getTaskId())
+                && beanName.equals(t.getBeanName())
+                && methodName.equals(t.getMethodName())
+                && methodParameter.equals(t.getMethodParameter())
+                && delay.equals(t.getDelay());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(taskId, beanName, methodName, methodParameter, delay);
+    }
+}

+ 0 - 41
src/main/java/com/nokia/tsl_data/scheduling/entity/ScheduledTask.java

@@ -1,41 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity;
-
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-import java.time.Instant;
-import java.util.Objects;
-
-import com.nokia.tsl_data.scheduling.entity._enum.ScheduledStatus;
-import com.nokia.tsl_data.scheduling.entity._enum.ScheduledType;
-import com.nokia.tsl_data.scheduling.entity.pojo.ScheduledParameter;
-
-@Data
-@Accessors(chain = true)
-public class ScheduledTask {
-
-    private Long id;
-    private String name;
-    private RegisteredTask registeredTask;
-    private ScheduledStatus status;
-    private String methodParameter;
-    private ScheduledType scheduledType;
-    private ScheduledParameter scheduledParameter;
-    private String failReason;
-    private String description;
-    private Instant createTime;
-    private Instant lastModify;
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        ScheduledTask that = (ScheduledTask) o;
-        return id.equals(that.id) || name.equals(that.name);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id);
-    }
-}

+ 0 - 37
src/main/java/com/nokia/tsl_data/scheduling/entity/_enum/ScheduledStatus.java

@@ -1,37 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity._enum;
-
-/**
- * 任务调度状态
- * ON 启动 只有ON是需要调度的
- * OFF 关闭
- * DONE 结束
- * TIMEOUT 超时
- * FAILED 任务失败
- */
-public enum ScheduledStatus {
-    ON, OFF, DONE, TIMEOUT, FAILED;
-
-    public static ScheduledStatus ofValue(String value) {
-        for (ScheduledStatus status : values()) {
-            if (status.toString().equalsIgnoreCase(value)) {
-                return status;
-            }
-        }
-        throw new RuntimeException("不存在 " + value +
-                " 对应的ScheduledStatus,允许的状态包括: ON, OFF, COMPLETE, TIMEOUT");
-    }
-
-    /**
-     * 是否需要启动调度
-     */
-    public boolean needToStartSchedule() {
-        return this.equals(ON);
-    }
-
-    /**
-     * 是否需要停止调度
-     */
-    public boolean needToStopSchedule() {
-        return this.equals(OFF);
-    }
-}

+ 0 - 23
src/main/java/com/nokia/tsl_data/scheduling/entity/_enum/ScheduledType.java

@@ -1,23 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity._enum;
-
-/**
- * 任务调度类型
- * IMMEDIATELY 立即调度 无需指定任何参数
- * ONCE 按指定的时间或者延时调度一次 需要指定 startTime 或 delayOfSeconds
- * CRON 定时调度 必须指定cronExpression
- * INTERVAL 周期调度, 两次调度开始之间经过固定的周期,必须指定 delayOfSeconds,可选指定 startTime
- * FIXED_DELAY 固定延时, 上一次调度的结束和下次任务调度开始之间经过固定时间,必须指定delayOfSeconds,可选指定startTime
- */
-public enum ScheduledType {
-    IMMEDIATELY, ONCE, CRON, INTERVAL, FIXED_DELAY;
-
-    public static ScheduledType ofValue(String value) {
-        for (ScheduledType type : values()) {
-            if (type.toString().equalsIgnoreCase(value)) {
-                return type;
-            }
-        }
-        throw new RuntimeException("不存在 " + value +
-                " 对应的ScheduledType,允许的类型包括: IMMEDIATELY, ONCE, CRON, INTERVAL, FIXED_DELAY");
-    }
-}

+ 0 - 39
src/main/java/com/nokia/tsl_data/scheduling/entity/pojo/CallableTask.java

@@ -1,39 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity.pojo;
-
-import lombok.Data;
-import org.springframework.context.ApplicationContext;
-import org.springframework.util.ReflectionUtils;
-import org.springframework.util.StringUtils;
-
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.Callable;
-
-@Data
-public class CallableTask implements Callable<Void> {
-
-    private final ApplicationContext applicationContext;
-    private final ScheduledTask scheduledTask;
-
-    public CallableTask(ApplicationContext applicationContext, ScheduledTask scheduledTask) {
-        this.applicationContext = applicationContext;
-        this.scheduledTask = scheduledTask;
-    }
-
-    @Override
-    public Void call() throws Exception {
-        Object bean = applicationContext.getBean(scheduledTask.getRegisteredTask().getBeanName());
-        Method method;
-        if (!StringUtils.hasLength(scheduledTask.getMethodParameter())) {
-            method = bean.getClass().getMethod(scheduledTask.getRegisteredTask().getMethodName());
-            ReflectionUtils.makeAccessible(method);
-            method.invoke(bean);
-        } else {
-            method = bean.getClass().getMethod(scheduledTask.getRegisteredTask().getMethodName(),
-                    String.class);
-            method.invoke(bean, scheduledTask.getMethodParameter());
-        }
-        return null;
-    }
-}

+ 0 - 67
src/main/java/com/nokia/tsl_data/scheduling/entity/pojo/RunnableTask.java

@@ -1,67 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity.pojo;
-
-import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.util.ReflectionUtils;
-import org.springframework.util.StringUtils;
-
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-import com.nokia.tsl_data.scheduling.entity._enum.ScheduledStatus;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * 执行任务的实体类
- */
-@Slf4j
-@Data
-public class RunnableTask implements Runnable {
-
-    private final ApplicationContext applicationContext;
-    private final ScheduledTask scheduledTask;
-
-    public RunnableTask(ApplicationContext applicationContext, ScheduledTask scheduledTask) {
-        this.applicationContext = applicationContext;
-        this.scheduledTask = scheduledTask;
-    }
-
-    @Override
-    public void run() {
-        try {
-            Object bean = applicationContext.getBean(scheduledTask.getRegisteredTask().getBeanName());
-            Method method;
-            if (!StringUtils.hasLength(scheduledTask.getMethodParameter())) {
-                method = bean.getClass().getMethod(scheduledTask.getRegisteredTask().getMethodName());
-                ReflectionUtils.makeAccessible(method);
-                method.invoke(bean);
-            } else {
-                method = bean.getClass().getMethod(scheduledTask.getRegisteredTask().getMethodName(),
-                        String.class);
-                method.invoke(bean, scheduledTask.getMethodParameter());
-            }
-        } catch (NoSuchBeanDefinitionException e) {
-            handleException(e);
-            log.error("未找到任务--任务:{}", scheduledTask.getName());
-        } catch (NoSuchMethodException e) {
-            handleException(e);
-            log.error("未找到方法--任务:{}", scheduledTask.getName());
-        } catch (IllegalAccessException e) {
-            scheduledTask.setStatus(ScheduledStatus.FAILED);
-            scheduledTask.setFailReason(e.getMessage());
-            e.printStackTrace();
-            log.error("方法不允许访问--任务:{}", scheduledTask.getName());
-        } catch (InvocationTargetException e) {
-            handleException(e);
-            log.error("方法执行出错--任务:{}", scheduledTask.getName());
-        }
-    }
-
-    private void handleException(Exception e) {
-        scheduledTask.setStatus(ScheduledStatus.FAILED);
-        scheduledTask.setFailReason(e.getMessage());
-        e.printStackTrace();
-    }
-}

+ 0 - 52
src/main/java/com/nokia/tsl_data/scheduling/entity/pojo/ScheduledParameter.java

@@ -1,52 +0,0 @@
-package com.nokia.tsl_data.scheduling.entity.pojo;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-import java.time.Instant;
-
-/**
- * 调度参数
- */
-@Data
-@Accessors(chain = true)
-public class ScheduledParameter {
-
-    /**
-     * 定时任务表达式
-     */
-    private String cronExpression;
-
-    /**
-     * 启动时间
-     */
-    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
-    private Instant startTime;
-
-    /**
-     * 以秒计算的数字,表示周期
-     */
-    private Long periodOfSeconds;
-
-    /**
-     * 以秒计算的数字,表示延时
-     */
-    private Long delayOfSeconds;
-
-    public static ScheduledParameter ofInstant(Instant instant) {
-        return new ScheduledParameter().setStartTime(instant);
-    }
-
-    public static ScheduledParameter ofPeriod(long period) {
-        return new ScheduledParameter().setPeriodOfSeconds(period);
-    }
-
-    public static ScheduledParameter ofDelay(long delay) {
-        return new ScheduledParameter().setDelayOfSeconds(delay);
-    }
-
-    public static ScheduledParameter ofExpression(String expression) {
-        return new ScheduledParameter().setCronExpression(expression);
-    }
-}

+ 0 - 28
src/main/java/com/nokia/tsl_data/scheduling/service/DatabaseInitializeService.java

@@ -1,28 +0,0 @@
-package com.nokia.tsl_data.scheduling.service;
-
-import lombok.extern.slf4j.Slf4j;
-
-import org.springframework.beans.factory.annotation.Autowired;
-
-import com.nokia.tsl_data.scheduling.dao.DatabaseInitializeMapper;
-
-import javax.annotation.PostConstruct;
-
-@Slf4j
-public class DatabaseInitializeService {
-
-    @Autowired
-    private DatabaseInitializeMapper databaseInitializeMapper;
-
-    @PostConstruct
-    public void checkAndInitializeDatabase() {
-        if (databaseInitializeMapper.ifSchemaExists()) {
-            log.warn("模式 scheduling 已存在...");
-        } else {
-            databaseInitializeMapper.createSchema();
-        }
-        databaseInitializeMapper.createTableRegisteredTask();
-        databaseInitializeMapper.createTableScheduledTask();
-        log.info("已完成scheduling数据库初始化...");
-    }
-}

+ 0 - 112
src/main/java/com/nokia/tsl_data/scheduling/service/RegisteredTaskService.java

@@ -1,112 +0,0 @@
-package com.nokia.tsl_data.scheduling.service;
-
-import com.nokia.tsl_data.scheduling.dao.RegisteredTaskMapper;
-import com.nokia.tsl_data.scheduling.entity.RegisteredTask;
-import com.nokia.tsl_data.util.SnowFlakeUtil;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
-
-import java.util.List;
-
-/**
- * RegisteredTask 增删 查 不提供修改
- */
-@Service
-public class RegisteredTaskService {
-
-    private final RegisteredTaskMapper registeredTaskMapper;
-    private final ApplicationContext applicationContext;
-
-    public RegisteredTaskService(RegisteredTaskMapper registeredTaskMapper, ApplicationContext applicationContext) {
-        this.registeredTaskMapper = registeredTaskMapper;
-        this.applicationContext = applicationContext;
-    }
-
-    /**
-     * 注册新任务
-     */
-    public void add(RegisteredTask registeredTask) {
-        // 检查是否已存在
-        RegisteredTask task = findByBeanNameAndMethodName(registeredTask.getBeanName(), registeredTask.getMethodName());
-        if (task != null) {
-            // 已存在相同beanName和methodName的实例
-            throw new RuntimeException(String.format("存在已注册的相同RegisteredTask==beanName: %s, methodName: %s ...",
-                    registeredTask.getBeanName(), registeredTask.getMethodName()));
-        }
-        // 检查是否在容器中存在beanName和methodName
-        Object bean;
-        try {
-            bean = applicationContext.getBean(registeredTask.getBeanName());
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException("注册失败, 容器中未找到bean: " + registeredTask.getBeanName());
-        }
-        if (registeredTask.getWithParameter()) {
-            try {
-                bean.getClass().getMethod(registeredTask.getMethodName(), String.class);
-            } catch (NoSuchMethodException e) {
-                // 容器中不存在beanName和methodName对应的方法
-                throw new RuntimeException(String.format("注册失败,容器中未找到方法== %s.%s()",
-                        registeredTask.getBeanName(), registeredTask.getMethodName()));
-            }
-        } else {
-            try {
-                bean.getClass().getMethod(registeredTask.getMethodName());
-            } catch (NoSuchMethodException e) {
-                // 容器中不存在beanName和methodName对应的方法
-                throw new RuntimeException(String.format("注册失败,容器中未找到方法== %s.%s()",
-                        registeredTask.getBeanName(), registeredTask.getMethodName()));
-            }
-        }
-        // 使用雪花算法给出id
-        registeredTask.setId(SnowFlakeUtil.getSnowFlakeId());
-        registeredTaskMapper.insertOne(registeredTask);
-    }
-
-    /**
-     * 删除已注册任务
-     */
-    public void deleteById(long id) {
-        registeredTaskMapper.deleteById(id);
-    }
-
-    /**
-     * 查找全部
-     */
-    public List<RegisteredTask> listAll() {
-        return registeredTaskMapper.selectAll();
-    }
-
-    public RegisteredTask findById(long id) {
-        return registeredTaskMapper.selectById(id);
-    }
-
-    /**
-     * 根据beanName和methodName查找
-     */
-    public RegisteredTask findByBeanNameAndMethodName(String beanName, String methodName) {
-        return registeredTaskMapper.selectByBeanNameAndMethodName(beanName, methodName);
-    }
-
-    /**
-     * 检查并返回数据库存储的RegisteredTask,id为第一优先级,否则按照beanName和methodName查找
-     */
-    public RegisteredTask check(RegisteredTask registeredTask) {
-        RegisteredTask result = null;
-        if (registeredTask == null) {
-            throw new RuntimeException("注册任务不能为空...");
-        }
-        if (registeredTask.getId() != null) {
-            result = findById(registeredTask.getId());
-        } else if (StringUtils.hasLength(registeredTask.getBeanName())
-                && StringUtils.hasLength(registeredTask.getMethodName())) {
-            result = findByBeanNameAndMethodName(registeredTask.getBeanName(), registeredTask.getMethodName());
-        }
-        if (result == null) {
-            throw new RuntimeException("注册任务不存在...");
-        }
-        return result;
-    }
-}

+ 0 - 178
src/main/java/com/nokia/tsl_data/scheduling/service/SchedulingService.java

@@ -1,178 +0,0 @@
-package com.nokia.tsl_data.scheduling.service;
-
-import com.nokia.tsl_data.scheduling.dao.ScheduledTaskMapper;
-import com.nokia.tsl_data.scheduling.entity.RegisteredTask;
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-import com.nokia.tsl_data.util.SnowFlakeUtil;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.StringUtils;
-
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.util.List;
-
-/**
- * ScheduledTask增删改查
- */
-@Slf4j
-@Service
-public class SchedulingService {
-
-    private final ScheduledTaskMapper scheduledTaskMapper;
-    private final RegisteredTaskService registeredTaskService;
-    private final TaskScheduleService taskScheduleService;
-
-    public SchedulingService(ScheduledTaskMapper scheduledTaskMapper, RegisteredTaskService registeredTaskService, TaskScheduleService taskScheduleService) {
-        this.scheduledTaskMapper = scheduledTaskMapper;
-        this.registeredTaskService = registeredTaskService;
-        this.taskScheduleService = taskScheduleService;
-    }
-
-    public RegisteredTask findRegisteredTaskByBeanNameAndMethodName(String beanName, String methodName) {
-        return registeredTaskService.findByBeanNameAndMethodName(beanName, methodName);
-    }
-
-    /**
-     * 新增
-     */
-    @Transactional(rollbackFor = Exception.class)
-    public void add(ScheduledTask scheduledTask) {
-        // 检查 RegisteredTask 是否已注册
-        scheduledTask.setRegisteredTask(registeredTaskService.check(scheduledTask.getRegisteredTask()));
-        // 检查status
-        if (scheduledTask.getStatus() == null) {
-            throw new RuntimeException("任务状态 status 不能为空...");
-        }
-        if (scheduledTask.getScheduledType() == null) {
-            throw new RuntimeException("任务类型 scheduledType 不能为空...");
-        }
-        // 检查methodParameter
-        if (scheduledTask.getRegisteredTask().getWithParameter()) {
-            if (scheduledTask.getMethodParameter() == null) {
-                throw new RuntimeException("方法参数 methodParameter 不能为空...");
-            }
-        } else {
-            // 对于不需要参数的情况,直接忽略输出的参数
-            scheduledTask.setMethodParameter(null);
-        }
-        // 检查name是否为空
-        String name = scheduledTask.getName();
-        // name为空时按照默认方式命名
-        if (!StringUtils.hasLength(name)) {
-            name = getDefaultName(scheduledTask);
-            scheduledTask.setName(name);
-        }
-        // 检查是否已存在同名
-        Long id = scheduledTaskMapper.selectIdByName(name);
-        if (id != null) {
-            throw new RuntimeException("已存在同名任务: " + name);
-        }
-        // 检查是否存在同名已删除任务
-        id = scheduledTaskMapper.selectDeletedIdByName(name);
-        if (id != null) {
-            scheduledTaskMapper.insertOneExists(scheduledTask.setId(id));
-        } else {
-            // 保存任务 通过雪花算法计算id
-            scheduledTask.setId(SnowFlakeUtil.getSnowFlakeId());
-            scheduledTaskMapper.insertOne(scheduledTask);
-        }
-        // 调度的任务是保存后的任务
-        if (scheduledTask.getStatus().needToStartSchedule()) {
-            ScheduledTask task = scheduledTaskMapper.selectById(scheduledTask.getId());
-            taskScheduleService.schedule(task);
-        }
-    }
-
-    /**
-     * 删除
-     */
-    @Transactional(rollbackFor = Exception.class)
-    public void deleteById(long id) {
-        ScheduledTask scheduledTask = scheduledTaskMapper.selectById(id);
-        if (scheduledTask == null) {
-            throw new RuntimeException("无法删除不存在的任务: id = " + id);
-        }
-        scheduledTaskMapper.deleteById(scheduledTask.getId());
-        if (scheduledTask.getStatus().needToStartSchedule()) {
-            if (taskScheduleService.isTaskScheduled(scheduledTask)) {
-                taskScheduleService.remove(scheduledTask);
-            }
-        }
-    }
-
-    /**
-     * 更新 默认需要更新的都是已存在的
-     */
-    @Transactional(rollbackFor = Exception.class)
-    public void update(ScheduledTask scheduledTask) {
-        Long id = scheduledTask.getId();
-        // 检查id是否为空
-        if (id == null) {
-            throw new RuntimeException("更新 ScheduledTask 时 id 不能为空...");
-        }
-        // 检查id是否存在
-        if (!scheduledTaskMapper.isIdExists(id)) {
-            throw new RuntimeException("更新 ScheduledTask 时指定的 id: " + id + " 不存在...");
-        }
-        // 检查id是否已删除
-        if (scheduledTaskMapper.isIdDeleted(id)) {
-            throw new RuntimeException("无法更新已删除的 ScheduledTask 任务...");
-        }
-        // 检查 RegisteredTask 如果不存在 则会设置为null
-        if (scheduledTask.getRegisteredTask() != null) {
-            scheduledTask.setRegisteredTask(registeredTaskService.check(scheduledTask.getRegisteredTask()));
-        }
-        // 更新数据库表
-        scheduledTaskMapper.updateById(scheduledTask);
-        if (scheduledTask.getStatus() != null) {
-            // 更新数据库表后
-            ScheduledTask task = scheduledTaskMapper.selectById(scheduledTask.getId());
-            if (task.getStatus().needToStartSchedule()) {
-                // 需要启动调度
-                taskScheduleService.schedule(task);
-            } else if(task.getStatus().needToStopSchedule()) {
-                // 需要停止调度
-                taskScheduleService.remove(task);
-            }
-        }
-    }
-
-    public List<ScheduledTask> listAll() {
-        return scheduledTaskMapper.selectAll();
-    }
-
-    public List<ScheduledTask> listScheduled() {
-        return taskScheduleService.ListTasksScheduled();
-    }
-
-    /**
-     * 默认的命名方式
-     */
-    private String getDefaultName(ScheduledTask scheduledTask) {
-        switch (scheduledTask.getScheduledType()) {
-            case CRON:
-            case INTERVAL:
-            case FIXED_DELAY:
-                log.warn("重复执行的任务建议不要使用默认命名...");
-                // beanName_methodName
-                return String.format("%s_%s",
-                        scheduledTask.getRegisteredTask().getBeanName(),
-                        scheduledTask.getRegisteredTask().getMethodName()
-                );
-            case ONCE:
-            case IMMEDIATELY:
-            default:
-                // beanName_methodName_时间字符串 common.schedulingService_test1_20231123104500
-                return String.format(
-                        "%s_%s_%s",
-                        scheduledTask.getRegisteredTask().getBeanName(),
-                        scheduledTask.getRegisteredTask().getMethodName(),
-                        DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Asia/Shanghai")).format(Instant.now())
-                );
-        }
-    }
-}

+ 0 - 59
src/main/java/com/nokia/tsl_data/scheduling/service/TaskAutoManagementService.java

@@ -1,59 +0,0 @@
-package com.nokia.tsl_data.scheduling.service;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
-import org.springframework.scheduling.support.CronTrigger;
-import com.nokia.tsl_data.scheduling.dao.ScheduledTaskMapper;
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import java.util.List;
-
-/**
- * 用于在启动时、运行中、停止时自动调度任务并更新调度任务的状态
- */
-@Slf4j
-public class TaskAutoManagementService {
-
-    private final TaskScheduleService taskScheduleService;
-    private final ScheduledTaskMapper scheduledTaskMapper;
-    private final ThreadPoolTaskScheduler taskScheduler;
-
-    public TaskAutoManagementService(TaskScheduleService taskScheduleService, ScheduledTaskMapper scheduledTaskMapper, ThreadPoolTaskScheduler taskScheduler) {
-        this.taskScheduleService = taskScheduleService;
-        this.scheduledTaskMapper = scheduledTaskMapper;
-        this.taskScheduler = taskScheduler;
-    }
-
-    /**
-     * 周期更新, 每20分钟更新任务状态
-     */
-    public void updateTasksScheduledMap() {
-        taskScheduler.schedule(()->{
-            taskScheduleService.refreshStatus();
-            log.info("已刷新任务状态...");
-        }, new CronTrigger("0 0/20 * * * *"));
-        log.info("");
-    }
-
-    /**
-     * 在系统启动时初始化调度任务
-     */
-    @PostConstruct
-    public void PostConstruct() {
-        List<ScheduledTask> tasks = scheduledTaskMapper.selectTaskToInit();
-        tasks.forEach(taskScheduleService::schedule);
-        log.info("已完成任务的初始化...");
-    }
-
-    /**
-     * 退出时保存任务状态
-     * 使用kill-15 或者 context.close() 才能触发
-     */
-    @PreDestroy
-    public void preDestroy() {
-        taskScheduleService.cancelAll();
-        log.info("已完成任务回收...");
-    }
-}

+ 84 - 168
src/main/java/com/nokia/tsl_data/scheduling/service/TaskScheduleService.java

@@ -1,29 +1,27 @@
 package com.nokia.tsl_data.scheduling.service;
 
-import lombok.extern.slf4j.Slf4j;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+
+import javax.annotation.PreDestroy;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
-import org.springframework.scheduling.Trigger;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
-import org.springframework.scheduling.support.CronTrigger;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
 
-import com.nokia.tsl_data.scheduling.dao.ScheduledTaskMapper;
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-import com.nokia.tsl_data.scheduling.entity._enum.ScheduledStatus;
-import com.nokia.tsl_data.scheduling.entity.pojo.RunnableTask;
-import com.nokia.tsl_data.scheduling.entity.pojo.ScheduledParameter;
+import com.nokia.tsl_data.scheduling.entity.RunnableTask;
 
-import java.time.Duration;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledFuture;
+import lombok.extern.slf4j.Slf4j;
 
 /**
- * 任务调度的核心服务
+ * 马上调度或者延时调度
  */
 @Slf4j
 @Service
@@ -31,203 +29,121 @@ public class TaskScheduleService {
     /**
      * 存储任务调度信息
      */
-    private ConcurrentHashMap<ScheduledTask, ScheduledFuture<?>> tasksScheduledMap = new ConcurrentHashMap<>();
+    private ConcurrentHashMap<RunnableTask, ScheduledFuture<?>> tasksSchedulingMap = new ConcurrentHashMap<>();
+
     @Autowired
     private ThreadPoolTaskScheduler taskScheduler;
+
     @Autowired
     private ApplicationContext applicationContext;
-    @Autowired
-    private ScheduledTaskMapper scheduledTaskMapper;
 
     /**
      * 调度任务
      */
-    public void schedule(ScheduledTask scheduledTask) {
-        if (tasksScheduledMap.containsKey(scheduledTask)) {
-            // 如果是重复调度,直接返回
-            ScheduledFuture<?> future = tasksScheduledMap.get(scheduledTask);
+    public void schedule(RunnableTask task) {
+        // 检查任务是否合法
+        checkRunnableTask(task);
+        // 检查是否已调度过
+        if (tasksSchedulingMap.containsKey(task)) {
+            ScheduledFuture<?> future = tasksSchedulingMap.get(task);
             if (!future.isDone()) {
-                // 任务尚未完成
-                log.warn("任务{}已调度但未完成,不要重复调度...", scheduledTask.getName());
-                return;
+                log.error("任务 {} 已调度但未完成,不要重复调度...", task);
+                throw new RuntimeException(String.format("任务 %s 已调度但未完成,不要重复调度...", task));
+            } else {
+                log.debug("任务 {} 已完成,将重新调度...", task);
             }
         }
-        Runnable runnable = new RunnableTask(applicationContext, scheduledTask);
-        if (scheduledTask.getStatus().needToStartSchedule()) {
-            ScheduledFuture<?> future = null;
-            ScheduledParameter scheduledParameter = scheduledTask.getScheduledParameter();
-            switch (scheduledTask.getScheduledType()) {
-                case CRON:
-                    if (scheduledParameter == null) {
-                        throw new RuntimeException("定时任务(CRON)调度参数 scheduledParameter 必须指定 cronExpression ...");
-                    }
-                    try {
-                        // 调度定时任务 必须指定cronExpression
-                        Trigger trigger = new CronTrigger(scheduledParameter.getCronExpression());
-                        // 开始时间为空或者早于当前时间
-                        future = taskScheduler.schedule(runnable, trigger);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                        throw new RuntimeException("定时任务(CRON)调度出错: " + e.getMessage());
-                    }
-                    break;
-                case INTERVAL:
-                    // 周期任务
-                    if (scheduledParameter == null) {
-                        throw new RuntimeException(
-                                "周期任务(INTERVAL)调度参数 scheduledParameter 必须指定 periodOfSeconds 可选 startTime ...");
-                    }
-                    if (scheduledParameter.getPeriodOfSeconds() == null
-                            || scheduledParameter.getPeriodOfSeconds() <= 0) {
-                        throw new RuntimeException("周期任务(INTERVAL)调度参数 scheduledParameter.periodOfSeconds 必须为正整数: "
-                                + scheduledParameter.getPeriodOfSeconds());
-                    }
-                    Duration period = Duration.ofSeconds(scheduledParameter.getPeriodOfSeconds());
-                    if (instantNullOrBeforeNow(scheduledParameter.getStartTime())) {
-                        // 开始时间为空或者早于当前时间
-                        future = taskScheduler.scheduleAtFixedRate(runnable, period);
-                    } else {
-                        future = taskScheduler.scheduleAtFixedRate(runnable,
-                                scheduledParameter.getStartTime(), period);
-                    }
-                    break;
-                case FIXED_DELAY:
-                    // 延时调度
-                    if (scheduledParameter == null) {
-                        throw new RuntimeException(
-                                "固定延时任务(FIXED_DELAY)调度参数 scheduledParameter 必须指定 delayOfSeconds 可选 startTime ...");
-                    }
-                    if (scheduledParameter.getDelayOfSeconds() == null || scheduledParameter.getDelayOfSeconds() <= 0) {
-                        throw new RuntimeException("固定延时任务(FIXED_DELAY)调度参数 scheduledParameter.delayOfSeconds 必须为正整数: "
-                                + scheduledParameter.getDelayOfSeconds());
-                    }
-                    // 如果 scheduledTask.getScheduledParameter().getDelayOfSeconds() 为空会报空指针
-                    Duration delay = Duration.ofSeconds(scheduledParameter.getDelayOfSeconds());
-                    if (instantNullOrBeforeNow(scheduledParameter.getStartTime())) {
-                        // 开始时间为空或者早于当前时间
-                        future = taskScheduler.scheduleWithFixedDelay(runnable, delay);
-                    } else {
-                        future = taskScheduler.scheduleWithFixedDelay(runnable,
-                                scheduledParameter.getStartTime(), delay);
-                    }
-                    break;
-                case ONCE:
-                    // 单次任务
-                    if (scheduledParameter == null) {
-                        throw new RuntimeException(
-                                "单次任务(ONCE)必须指定调度参数 scheduledParameter 的 startTime 或 delayOfSeconds ... ");
-                    }
-                    Instant startTimeForOnceTask = scheduledParameter.getStartTime();
-                    Long delayOfSeconds = scheduledParameter.getDelayOfSeconds();
-                    if (startTimeForOnceTask == null && delayOfSeconds == null) {
-                        throw new RuntimeException(
-                                "单次任务(ONCE)必须指定调度参数 scheduledParameter 的 startTime 或 delayOfSeconds ... ");
-                    } else if (startTimeForOnceTask != null) {
-                        // startTime 优先级高于 delay
-                        if (startTimeForOnceTask.isAfter(Instant.now())) {
-                            // 单次任务只有在启动时间大于等于当前时间时才启动调度
-                            future = taskScheduler.schedule(runnable, startTimeForOnceTask);
-                        } else {
-                            // 当启动时间早于当前时间时,更新状态为超时
-                            log.info("单次任务(ONCE) startTime: {} 早于当前时间: {} 直接跳过", startTimeForOnceTask, Instant.now());
-                            scheduledTask.setStatus(ScheduledStatus.TIMEOUT);
-                            scheduledTaskMapper.updateById(scheduledTask);
-                        }
-                    } else if (delayOfSeconds > 0) {
-                        future = taskScheduler.schedule(runnable, Instant.now().plusSeconds(delayOfSeconds));
-                    } else {
-                        throw new RuntimeException("单次任务(ONCE)指定的调度参数 scheduledParameter 中 delayOfSeconds 必须大于 0 ...");
-                    }
-                    break;
-                case IMMEDIATELY:
-                    // 马上执行的任务
-                default:
-                    future = taskScheduler.schedule(runnable, Instant.now());
-                    break;
-            }
-            if (future != null) {
-                tasksScheduledMap.put(scheduledTask, future);
-            }
+        // 调度任务
+        Long delay = task.getDelay();
+        if (delay != null) {
+            // 延时调度
+            tasksSchedulingMap.put(task, taskScheduler.schedule(task, Instant.now().plus(Duration.ofSeconds(delay))));
+        } else {
+            // 马上执行
+            tasksSchedulingMap.put(task, taskScheduler.schedule(task, Instant.now()));
         }
     }
 
     /**
      * 删除任务
      */
-    public void remove(ScheduledTask scheduledTask) {
-        if (tasksScheduledMap.containsKey(scheduledTask)) {
-            ScheduledFuture<?> future = tasksScheduledMap.remove(scheduledTask);
+    public void remove(RunnableTask task) {
+        if (tasksSchedulingMap.contains(task)) {
+            ScheduledFuture<?> future = tasksSchedulingMap.remove(task);
             if (future.isDone()) {
-                scheduledTask.setStatus(ScheduledStatus.DONE);
-                scheduledTaskMapper.updateById(scheduledTask);
+                log.debug("要删除的任务 {} 已完成...", task);
             } else {
+                log.debug("要删除的任务 {} 尚未完成...", task);
                 future.cancel(true);
             }
+        } else {
+            log.warn("尝试删除不存在的任务 {} ...", task);
         }
     }
 
     /**
-     * 获取调度的任务
+     * 获取正在调度的任务
      */
-    public List<ScheduledTask> ListTasksScheduled() {
-        refreshStatus();
-        return new ArrayList<>(tasksScheduledMap.keySet());
+    public List<RunnableTask> listTasksScheduling() {
+        tasksSchedulingMap.forEach((task, future) -> {
+            if (future.isDone()) {
+                log.debug(" {} 任务已完成...", task);
+                tasksSchedulingMap.remove(task);
+            }
+        });
+        return new ArrayList<>(tasksSchedulingMap.keySet());
     }
 
     /**
-     * 结束任务
+     * 周期更新任务状态 每10分钟更新任务状态
      */
-    public void cancelAll() {
-        // 遍历,刷新已完成的任务
-        tasksScheduledMap.forEach((task, future) -> {
+    @Scheduled(cron = "0 0/10 * * * *")
+    public void cronUpdate() {
+        log.debug("开始调度周期更新任务状态...");
+        tasksSchedulingMap.forEach((task, future) -> {
             if (future.isDone()) {
-                handleTaskIsDone(task);
-            } else {
-                future.cancel(true);
+                log.debug(" {} 任务已完成...", task);
+                tasksSchedulingMap.remove(task);
             }
         });
-    }
-
-    public boolean isTaskScheduled(ScheduledTask task) {
-        ScheduledFuture<?> future = tasksScheduledMap.get(task);
-        if (future == null)
-            return false;
-        if (future.isDone()) {
-            handleTaskIsDone(task);
-            return false;
-        }
-        return true;
+        log.debug("周期更新任务状态已完成...");
     }
 
     /**
-     * 刷新任务状态
+     * 在退出时结束全部任务
+     * 这里不做记录,也就是说不支持重新加载未完成的任务
      */
-    public void refreshStatus() {
-        // 遍历,刷新已完成的任务
-        tasksScheduledMap.forEach((task, future) -> {
+    @PreDestroy
+    public void cancelAll() {
+        tasksSchedulingMap.forEach((task, future) -> {
             if (future.isDone()) {
-                handleTaskIsDone(task);
+                log.debug("退出时任务 {} 已完成...", task);
+            } else {
+                log.warn("退出时任务 {} 尚未完成...", task);
+                future.cancel(true);
             }
         });
     }
 
     /**
-     * 处理已完成任务
+     * 检查任务
      */
-    private void handleTaskIsDone(ScheduledTask task) {
-        if (!ScheduledStatus.FAILED.equals(task.getStatus())) {
-            // 如果执行出现异常,会修改状态,所以如果状态未改变则认为执行未出现异常
-            task.setStatus(ScheduledStatus.DONE);
+    public void checkRunnableTask(RunnableTask task) {
+        try {
+            Object bean = applicationContext.getBean(task.getBeanName());
+            if (bean == null) {
+                throw new RuntimeException(String.format("%s 不存在...", task.getBeanName()));
+            }
+            if (!StringUtils.hasLength(task.getMethodParameter())) {
+                bean.getClass().getMethod(task.getMethodName());
+            } else {
+                bean.getClass().getMethod(task.getMethodName(), String.class);
+            }
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(String.format("未找到 %s.%s() ...", task.getBeanName(), task.getMethodName()));
+        } catch (SecurityException e) {
+            throw new RuntimeException(
+                    String.format("%s.%s() 出错: %s", task.getBeanName(), task.getMethodName(), e.getMessage()));
         }
-        tasksScheduledMap.remove(task);
-        scheduledTaskMapper.updateById(task);
-        log.debug("任务 {}=={} 已完成...", task.getName(), task.getDescription());
-    }
-
-    /**
-     * 输入时间为空或者早于当前时间
-     */
-    private boolean instantNullOrBeforeNow(Instant instant) {
-        return instant == null || instant.isBefore(Instant.now());
     }
 }

+ 18 - 0
src/main/java/com/nokia/tsl_data/service/DataWarehouseService.java

@@ -43,6 +43,9 @@ public class DataWarehouseService {
     @Autowired
     private DataWarehouseProperties dataWarehouseProperties;
 
+    /**
+     * 入库前检查数据源是否具备
+     */
     public String checkSource(String day) {
         StringBuffer stringBuffer = new StringBuffer();
         // 注意,只有文件已存在时才能 checkMD5, 否则读取MD5文件时必出异常
@@ -67,6 +70,14 @@ public class DataWarehouseService {
         } else if (!checkMD5(highQualityCountDayFile)) {
             stringBuffer.append("河北_CEM高品质2日统计_HE_D_HIGH_QUALITY_COUNT表账期 ").append(day).append(" MD5验证未通过");
         }
+        // 河北客户体验管理智能定责投诉明细月累计接口日
+        File complaintDetailsFixYwdDayFile = getComplaintDetailsFixYwdDayFile(day);
+        if (!complaintDetailsFixYwdDayFile.exists()) {
+            stringBuffer.append("河北客户体验管理智能定责投诉明细月累计接口日 表账期 ").append(day).append(" 数据未到达");
+        } else if (!checkMD5(complaintDetailsFixYwdDayFile)) {
+            stringBuffer.append("河北客户体验管理智能定责投诉明细月累计接口日 表账期 ").append(day).append(" MD5验证未通过");
+        }
+        // 
         return stringBuffer.toString();
     }
 
@@ -90,6 +101,11 @@ public class DataWarehouseService {
         } else {
             log.warn("MobileComplaint 账期 {} 已存在 {} 条数据,已跳过...", day, count);
         }
+        if ((count = complaintDetailsFixYwdDayMapper.countForDay(day)) == 0) {
+            warehouseComplaintDetailsFixYwdDay(day);
+        } else {
+            log.warn("complaintDetailsFixYwdDay 账期 {} 已存在 {} 条数据,已跳过...", day, count);
+        }
     }
 
     /**
@@ -263,6 +279,7 @@ public class DataWarehouseService {
         }
     }
 
+    // 河北客户体验管理智能定责投诉明细月累计接口日
     private void warehouseComplaintDetailsFixYwdDay(File file) {
         try (Reader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
             // SOH作为分割符
@@ -305,6 +322,7 @@ public class DataWarehouseService {
         return Paths.get(dataWarehouseProperties.getDirOfHighQualityCountDay(), fileName).toFile();
     }
 
+    // 河北客户体验管理智能定责投诉明细月累计接口日
     private File getComplaintDetailsFixYwdDayFile(String day) {
         String fileName = dataWarehouseProperties.getPrefixOfComplaintDetailsFixYwdDay() + day + ".csv";
         return Paths.get(dataWarehouseProperties.getDirOfComplaintDetailsFixYwdDay(), fileName).toFile();

+ 11 - 0
src/main/java/com/nokia/tsl_data/service/ManagementDetailService.java

@@ -44,6 +44,17 @@ public class ManagementDetailService {
         }
     }
 
+    /**
+     * 生成某个帐期的数据
+     */
+    public void generateForDay(String day) {
+        if (managementDetailMapper.selectCountofStatDay(day) != 0) {
+            throw new RuntimeException("managementDetail 帐期 " + day + " 已存在数据...");
+        }
+        managementDetailMapper.insertFromMobileComplaint(day);
+        managementDetailMapper.insertFromComplaintDetailsFixYwd(day);
+    }
+
     /**
      * 2024年适配需求 统计数据在原有基础(河北_CEM移网质量投诉明细全量数据)上增加新订阅的 河北客户体验管理智能定责投诉明细月累计接口日 表中
      * 日定责问题分类(duty_reason_id_day) 字段值为 业务使用>>基础业务使用>>移网主被叫>>手机无法主被叫 的部分。

+ 27 - 41
src/main/java/com/nokia/tsl_data/service/TaskService.java

@@ -6,16 +6,14 @@ import com.nokia.tsl_data.dao.TaskRecordRepository;
 import com.nokia.tsl_data.dao.TslDataDao;
 import com.nokia.tsl_data.entity.TaskRecord;
 import com.nokia.tsl_data.properties.TslDataProperties;
-import com.nokia.tsl_data.scheduling.entity.ScheduledTask;
-import com.nokia.tsl_data.scheduling.entity._enum.ScheduledStatus;
-import com.nokia.tsl_data.scheduling.entity._enum.ScheduledType;
-import com.nokia.tsl_data.scheduling.entity.pojo.ScheduledParameter;
-import com.nokia.tsl_data.scheduling.service.SchedulingService;
+import com.nokia.tsl_data.scheduling.entity.RunnableTask;
+import com.nokia.tsl_data.scheduling.service.TaskScheduleService;
 import com.nokia.tsl_data.util.DateFormatUtil;
 
 import lombok.extern.slf4j.Slf4j;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
@@ -43,60 +41,56 @@ public class TaskService {
     @Autowired
     private MessageService messageService;
     @Autowired
-    private ReportServiceV1 tslReportService;
-    @Autowired
     private HighQualityDataService highQualityDataService;
     @Autowired
-    private SchedulingService schedulingService;
+    private TaskScheduleService taskScheduleService;
     @Autowired
     private ReportServiceV3 reportServiceV3;
     @Autowired
     private TslDataProperties tslDataProperties;
+    @Autowired
+    private ManagementDetailService managementDetailService;
 
     /**
-     * 每日定时任务
+     * 每日定时任务 每天中午1点半执行入库任务
      */
+    @Scheduled(cron = "0 30 13 * * *")
     public void dailyWarehouseTask() {
         // 这里的时间要向前一天
         String day = DateFormatUtil.ofPattern("yyyyMMdd").format(Instant.now().plus(-1L, ChronoUnit.DAYS));
         // 调度一次 taskService.wareHouseTask(day)
-        ScheduledTask task = new ScheduledTask()
-                .setRegisteredTask(schedulingService.findRegisteredTaskByBeanNameAndMethodName(
-                        "taskService", "wareHouseTask"))
-                .setMethodParameter(day)
-                .setStatus(ScheduledStatus.ON)
-                // 马上调度
-                .setScheduledType(ScheduledType.IMMEDIATELY)
-                .setDescription(day + " 报表生成");
-        schedulingService.add(task);
+        RunnableTask task = new RunnableTask()
+                .setTaskId("warehouse_cron_" + day)
+                .setBeanName("taskService")
+                .setMethodName("warehouseTask")
+                .setMethodParameter(day);
+        taskScheduleService.schedule(task);
     }
 
     /**
      * 指定日期任务
      */
     public void wareHouseTask(String day) {
+        // 检查源是否具备
         String result = dataWarehouseService.checkSource(day);
         if (StringUtils.hasLength(result)) {
-            // 存在异常情况
+            // 存在异常情况,发送运维消息
             messageService.error(result);
             // 延时调度,间隔一段时间后再次调度
-            ScheduledTask task = new ScheduledTask()
-                    .setRegisteredTask(schedulingService.findRegisteredTaskByBeanNameAndMethodName(
-                            "taskService", "wareHouseTask"))
-                    .setDescription("延时调度每日报表入库、生成、截图任务")
+            taskScheduleService.schedule(new RunnableTask()
+                    .setTaskId("warehouse_rescedule_" + day + "_" + System.currentTimeMillis())
+                    .setBeanName("taskService")
+                    .setMethodName("warehouseTask")
                     .setMethodParameter(day)
-                    .setStatus(ScheduledStatus.ON)
-                    .setScheduledType(ScheduledType.ONCE)
-                    // 延时 1800L 调度
-                    .setScheduledParameter(ScheduledParameter.ofDelay(1800L));
-            // 调度任务
-            schedulingService.add(task);
+                    .setDelay(3600L));
         } else {
             try {
                 // 执行入库任务
                 dataWarehouseService.wareHouse(day);
                 // 生成HighQualityData
                 highQualityDataService.generateHighQualityData(day);
+                // 生成ManagementDetail
+                managementDetailService.generateForDay(day);
                 // 报表+截图
                 generateReportV3(day);
             } catch (Exception e) {
@@ -107,16 +101,6 @@ public class TaskService {
         }
     }
 
-    /**
-     * 生成第二版报表
-     */
-    public void generateReportV2(String day) {
-        // 生成报表
-        tslReportService.generateReportV2(day);
-        // 截图
-        tslReportService.screenShotV2(day);
-    }
-
     /**
      * 生成第三版报表
      */
@@ -139,8 +123,9 @@ public class TaskService {
 
     /**
      * 从工单系统定时更新数据
-     * 调度周期每小时
+     * 调度周期每小时的10分调度一次
      */
+    @Scheduled(cron = "0 10 * * * *")
     public void updateWorkFlowBasicDataTask() {
         log.info("从工单系统定时更新数据 任务开始...");
         Instant start = taskRecordRepository.findLastSuccessUpdateWorkFlowBasicDataTaskEndInstant();
@@ -152,8 +137,9 @@ public class TaskService {
 
     /**
      * 定时删除过期的临时表
-     * 调度周期,每天
+     * 调度周期,每天凌晨1点调度一次
      */
+    @Scheduled(cron = "0 0 1 * * *")
     public void tempTableCleanCronTask() {
         log.info("定时删除过期的临时表 任务开始...");
         TaskRecord taskRecord = new TaskRecord();