From d830d5dc98737262b07d35e74a01d6bd1b10f8fa Mon Sep 17 00:00:00 2001 From: lidongyang <506508008@qq.com> Date: Mon, 22 Dec 2025 10:14:25 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=AF=B9=E6=8E=A5=E6=B5=B7=E8=91=B5?= =?UTF-8?q?=E4=BA=91=E3=80=81EP=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sdm/common/utils/FilesUtil.java | 130 ++++++++++++ .../sdm/outbridge/mode/HkUploadFileReq.java | 2 + project/pom.xml | 14 ++ .../generator/UniqueFileNameGenerator.java | 34 ++++ .../com/sdm/project/config/QuartzConfig.java | 36 ++++ .../controller/MultiJobController.java | 90 +++++++++ .../SimulationLyricNodeController.java | 41 +++- ...imulationProjectSchedulerConfigMapper.java | 17 ++ .../SimulationTodoSchedulerConfigMapper.java | 16 ++ .../com/sdm/project/job/ProjectSyncJob.java | 21 ++ .../java/com/sdm/project/job/TodoSyncJob.java | 23 +++ .../sdm/project/manager/MultiJobManager.java | 100 ++++++++++ .../manager/MultiJobStartupRunner.java | 48 +++++ .../SimulationProjectSchedulerConfig.java | 42 ++++ .../entity/SimulationTodoSchedulerConfig.java | 42 ++++ .../model/req/ProcessDataDetailReq.java | 14 ++ .../sdm/project/model/req/ProcessDataReq.java | 17 ++ .../sdm/project/model/req/PushReportReq.java | 23 +++ .../sdm/project/model/req/SchedulerReq.java | 10 + .../service/ILyricInternalService.java | 18 ++ ...mulationProjectSchedulerConfigService.java | 18 ++ ...ISimulationTodoSchedulerConfigService.java | 20 ++ .../impl/LyricInternalServiceImpl.java | 186 ++++++++++++++++++ ...va => SimulationLyricNodeServiceImpl.java} | 4 +- ...tionProjectSchedulerConfigServiceImpl.java | 24 +++ ...ulationTodoSchedulerConfigServiceImpl.java | 21 ++ .../src/main/resources/application-local.yml | 4 + 27 files changed, 1011 insertions(+), 4 deletions(-) create mode 100644 project/src/main/java/com/sdm/project/common/generator/UniqueFileNameGenerator.java create mode 100644 project/src/main/java/com/sdm/project/config/QuartzConfig.java create mode 100644 project/src/main/java/com/sdm/project/controller/MultiJobController.java create mode 100644 project/src/main/java/com/sdm/project/dao/SimulationProjectSchedulerConfigMapper.java create mode 100644 project/src/main/java/com/sdm/project/dao/SimulationTodoSchedulerConfigMapper.java create mode 100644 project/src/main/java/com/sdm/project/job/ProjectSyncJob.java create mode 100644 project/src/main/java/com/sdm/project/job/TodoSyncJob.java create mode 100644 project/src/main/java/com/sdm/project/manager/MultiJobManager.java create mode 100644 project/src/main/java/com/sdm/project/manager/MultiJobStartupRunner.java create mode 100644 project/src/main/java/com/sdm/project/model/entity/SimulationProjectSchedulerConfig.java create mode 100644 project/src/main/java/com/sdm/project/model/entity/SimulationTodoSchedulerConfig.java create mode 100644 project/src/main/java/com/sdm/project/model/req/ProcessDataDetailReq.java create mode 100644 project/src/main/java/com/sdm/project/model/req/ProcessDataReq.java create mode 100644 project/src/main/java/com/sdm/project/model/req/PushReportReq.java create mode 100644 project/src/main/java/com/sdm/project/model/req/SchedulerReq.java create mode 100644 project/src/main/java/com/sdm/project/service/ILyricInternalService.java create mode 100644 project/src/main/java/com/sdm/project/service/ISimulationProjectSchedulerConfigService.java create mode 100644 project/src/main/java/com/sdm/project/service/ISimulationTodoSchedulerConfigService.java create mode 100644 project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java rename project/src/main/java/com/sdm/project/service/impl/{ISimulationLyricNodeServiceImpl.java => SimulationLyricNodeServiceImpl.java} (87%) create mode 100644 project/src/main/java/com/sdm/project/service/impl/SimulationProjectSchedulerConfigServiceImpl.java create mode 100644 project/src/main/java/com/sdm/project/service/impl/SimulationTodoSchedulerConfigServiceImpl.java diff --git a/common/src/main/java/com/sdm/common/utils/FilesUtil.java b/common/src/main/java/com/sdm/common/utils/FilesUtil.java index c1ddb463..856d7834 100644 --- a/common/src/main/java/com/sdm/common/utils/FilesUtil.java +++ b/common/src/main/java/com/sdm/common/utils/FilesUtil.java @@ -11,6 +11,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.FileTime; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Vector; @@ -409,6 +410,135 @@ public class FilesUtil { } } + /** + * 获取指定目录下的所有文件(不递归子目录) + * @param dirPath 目录路径 + * @return 目录下所有文件的List集合 + * @throws IllegalArgumentException 目录路径不合法时抛出 + */ + public static List getAllFiles(String dirPath) { + return getAllFiles(dirPath, false); + } + + /** + * 获取指定目录下的所有文件 + * @param dirPath 目录路径 + * @param recursive 是否递归遍历子目录 + * @return 目录下所有文件的List集合 + * @throws IllegalArgumentException 目录路径不合法时抛出 + */ + public static List getAllFiles(String dirPath, boolean recursive) { + // 1. 校验目录路径合法性 + File directory = validateDirectory(dirPath); + // 2. 初始化文件集合 + List fileList = new ArrayList<>(); + // 3. 遍历目录收集文件 + collectFiles(directory, fileList, recursive); + return fileList; + } + + /** + * 校验目录合法性 + * @param dirPath 目录路径 + * @return 合法的目录File对象 + * @throws IllegalArgumentException 目录不合法时抛出异常 + */ + private static File validateDirectory(String dirPath) { + if (dirPath == null || dirPath.trim().isEmpty()) { + throw new IllegalArgumentException("目录路径不能为空"); + } + File directory = new File(dirPath); + if (!directory.exists()) { + throw new IllegalArgumentException("目录不存在: " + dirPath); + } + if (!directory.isDirectory()) { + throw new IllegalArgumentException("指定路径不是目录: " + dirPath); + } + if (!directory.canRead()) { + throw new IllegalArgumentException("没有目录读取权限: " + dirPath); + } + return directory; + } + + /** + * 递归收集目录下的文件 + * @param directory 目录 + * @param fileList 文件集合 + * @param recursive 是否递归 + */ + private static void collectFiles(File directory, List fileList, boolean recursive) { + // 获取目录下的所有文件/子目录 + File[] files = directory.listFiles(); + // 空目录直接返回 + if (files == null || files.length == 0) { + return; + } + for (File file : files) { + if (file.isFile()) { + // 是文件则加入集合 + fileList.add(file); + } else if (file.isDirectory() && recursive) { + // 是目录且需要递归则继续遍历 + collectFiles(file, fileList, recursive); + } + } + } + + /** + * 非递归删除:仅删除指定文件夹下的一级文件/空文件夹,最后删除文件夹本身 + * @param folderPath 目标文件夹路径 + * @throws IOException 文件夹不存在、非文件夹、删除失败时抛出异常 + */ + public static void deleteFolderNonRecursive(String folderPath) throws IOException { + // 1. 校验文件夹合法性 + File targetFolder = new File(folderPath); + if (!targetFolder.exists()) { + throw new IOException("文件夹不存在: " + folderPath); + } + if (!targetFolder.isDirectory()) { + throw new IOException("指定路径不是文件夹: " + folderPath); + } + // 2. 非递归遍历一级内容 + File[] files = targetFolder.listFiles(); + if (files != null) { // 处理权限问题导致listFiles返回null的情况 + for (File file : files) { + if (file.isFile()) { + // 删除一级文件 + boolean deleted = file.delete(); + if (deleted) { + log.info("已删除文件:{}" , file.getAbsolutePath()); + } else { + log.error("删除文件失败:{}" , file.getAbsolutePath()); + } + } else if (file.isDirectory()) { + // 仅删除空的一级子文件夹,非空则跳过 + if (file.listFiles() == null || file.listFiles().length == 0) { + boolean deleted = file.delete(); + if (deleted) { + log.info("已删除空文件夹: {}" , file.getAbsolutePath()); + } else { + log.error("删除空文件夹失败: {}" , file.getAbsolutePath()); + } + } else { + log.info("跳过非空子文件夹: {}" , file.getAbsolutePath()); + } + } + } + } + // 3. 检查目标文件夹是否为空,为空则删除本身 + File[] remainingFiles = targetFolder.listFiles(); + if (remainingFiles == null || remainingFiles.length == 0) { + boolean folderDeleted = targetFolder.delete(); + if (folderDeleted) { + log.info("已删除目标文件夹本身: {}" , targetFolder.getAbsolutePath()); + } else { + throw new IOException("删除目标文件夹失败,可能是权限不足: " + folderPath); + } + } else { + throw new IOException("目标文件夹仍有非空内容,无法删除本身: " + folderPath); + } + } + } diff --git a/outbridge/src/main/java/com/sdm/outbridge/mode/HkUploadFileReq.java b/outbridge/src/main/java/com/sdm/outbridge/mode/HkUploadFileReq.java index 1d47be76..a1c4286d 100644 --- a/outbridge/src/main/java/com/sdm/outbridge/mode/HkUploadFileReq.java +++ b/outbridge/src/main/java/com/sdm/outbridge/mode/HkUploadFileReq.java @@ -1,10 +1,12 @@ package com.sdm.outbridge.mode; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; import java.util.ArrayList; import java.util.List; +@Data public class HkUploadFileReq { @Schema(description = "权限编码") public String filePower = "2456236750149124114"; diff --git a/project/pom.xml b/project/pom.xml index d7cb0a6a..072990a6 100644 --- a/project/pom.xml +++ b/project/pom.xml @@ -100,6 +100,20 @@ + + org.quartz-scheduler + quartz + 2.5.0 + + + + org.springframework + spring-context-support + 6.1.14 + + + + diff --git a/project/src/main/java/com/sdm/project/common/generator/UniqueFileNameGenerator.java b/project/src/main/java/com/sdm/project/common/generator/UniqueFileNameGenerator.java new file mode 100644 index 00000000..8cd140c8 --- /dev/null +++ b/project/src/main/java/com/sdm/project/common/generator/UniqueFileNameGenerator.java @@ -0,0 +1,34 @@ +package com.sdm.project.common.generator; + +import java.security.SecureRandom; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class UniqueFileNameGenerator { + + // 定义随机字符串的字符集(字母+数字,避免混淆的字符如0/O、1/l已剔除) + private static final String CHARACTERS = "abcdefghjkmnpqrstuvwxyz"; + private static final int RANDOM_LENGTH = 12; // 随机字符串长度 + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); // 安全随机数生成器 + // 日期格式化器(年月日,如20251221) + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); + + /** + * 生成唯一文件名:年月日 + 12位随机字符串 + * @return 格式化后的文件名(如20251221akdesgdiujfs) + */ + public static String generateUniqueFileName() { + // 1. 获取当前年月日并格式化 + String currentDate = LocalDate.now().format(DATE_FORMATTER); + // 2. 生成12位随机字符串 + StringBuilder randomStr = new StringBuilder(RANDOM_LENGTH); + for (int i = 0; i < RANDOM_LENGTH; i++) { + // 随机获取字符集索引 + int randomIndex = SECURE_RANDOM.nextInt(CHARACTERS.length()); + randomStr.append(CHARACTERS.charAt(randomIndex)); + } + // 3. 拼接日期和随机字符串 + return currentDate + "_" + randomStr; + } + +} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/config/QuartzConfig.java b/project/src/main/java/com/sdm/project/config/QuartzConfig.java new file mode 100644 index 00000000..365aef29 --- /dev/null +++ b/project/src/main/java/com/sdm/project/config/QuartzConfig.java @@ -0,0 +1,36 @@ +package com.sdm.project.config; + +import org.quartz.Scheduler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; + +/** + * 适配Spring 6.1.14的Quartz配置类 + * 关键:通过SchedulerFactoryBean实例获取Scheduler,而非静态方法 + */ +@Configuration +public class QuartzConfig { + + /** + * 创建SchedulerFactoryBean(Quartz的核心工厂类) + */ + @Bean + public SchedulerFactoryBean schedulerFactoryBean() { + SchedulerFactoryBean factoryBean = new SchedulerFactoryBean(); + // 可选:设置Quartz属性(如线程池大小、集群配置等) + // Properties props = new Properties(); + // props.put("org.quartz.threadPool.threadCount", "10"); + // factoryBean.setQuartzProperties(props); + return factoryBean; + } + + /** + * 注入Scheduler实例(从factoryBean中获取,适配Spring 6非静态方法) + */ + @Bean + public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) { + // 这里调用的是实例方法getScheduler(),而非静态方法 + return schedulerFactoryBean.getScheduler(); + } +} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/controller/MultiJobController.java b/project/src/main/java/com/sdm/project/controller/MultiJobController.java new file mode 100644 index 00000000..51aa3890 --- /dev/null +++ b/project/src/main/java/com/sdm/project/controller/MultiJobController.java @@ -0,0 +1,90 @@ +package com.sdm.project.controller; + +import com.sdm.common.common.SdmResponse; +import com.sdm.project.job.ProjectSyncJob; +import com.sdm.project.job.TodoSyncJob; +import com.sdm.project.manager.MultiJobManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.quartz.SchedulerException; + +import java.text.ParseException; +import java.util.Collections; + +/** + * 手动管理多Job的接口 + */ +@RestController +@RefreshScope +public class MultiJobController { + + @Autowired + private MultiJobManager multiJobManager; + + private static final String TODO_SYNC_JOB_NAME = "todoSyncJob"; + + private static final String PROJECT_SYNC_JOB_NAME = "projectSyncJob"; + + @Value("${scheduler.todo}") + private String schedulerTodoTime; + + @Value("${scheduler.project}") + private String schedulerProjectTime; + + // 暂停指定分组的Job(比如暂停数据同步任务:/pauseJob/dataSyncGroup) + @GetMapping("/pauseJob/{jobGroup}") + public String pauseJob(@PathVariable String jobGroup) { + try { + multiJobManager.pauseJobGroup(jobGroup); + return "已暂停分组[" + jobGroup + "]的所有任务"; + } catch (SchedulerException e) { + return "暂停失败:" + e.getMessage(); + } + } + + // 恢复指定分组的Job + @GetMapping("/resumeJob/{jobGroup}") + public String resumeJob(@PathVariable String jobGroup) { + try { + multiJobManager.resumeJobGroup(jobGroup); + return "已恢复分组[" + jobGroup + "]的所有任务"; + } catch (SchedulerException e) { + return "恢复失败:" + e.getMessage(); + } + } + + // 删除指定分组的Job + @GetMapping("/deleteJob") + public String deleteJob(@RequestParam String jobGroup) { + try { + multiJobManager.deleteJobGroup(jobGroup); + return "已删除分组[" + jobGroup + "]的所有任务"; + } catch (SchedulerException e) { + return "删除失败:" + e.getMessage(); + } + } + + // 新增指定分组的Job + @GetMapping("/createJob") + public SdmResponse createJob(@RequestParam String jobGroup) { + try { + multiJobManager.deleteJobGroup(jobGroup); + if (TODO_SYNC_JOB_NAME.equals(jobGroup)) { + multiJobManager.createJob(TodoSyncJob.class,jobGroup, Collections.singletonList(schedulerTodoTime.replaceAll("\\.",":"))); + }else { + multiJobManager.createJob(ProjectSyncJob.class,jobGroup, Collections.singletonList(schedulerProjectTime.replaceAll("\\.",":"))); + } + return SdmResponse.success("创建" + jobGroup + "任务成功"); + } catch (SchedulerException e) { + return SdmResponse.failed("创建" + jobGroup + "任务失败"); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + +} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java index 797caf44..ad98cd4d 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java @@ -2,17 +2,28 @@ package com.sdm.project.controller; import com.alibaba.excel.util.StringUtils; import com.sdm.common.common.SdmResponse; +import com.sdm.common.utils.RandomUtil; +import com.sdm.outbridge.mode.HkUploadFileReq; import com.sdm.outbridge.service.lyric.LyricIntegrateService; import com.sdm.project.common.ApprovalStatusEnum; import com.sdm.project.model.entity.SimulationNode; +import com.sdm.project.model.req.ProcessDataReq; +import com.sdm.project.model.req.PushReportReq; +import com.sdm.project.service.ILyricInternalService; import com.sdm.project.service.ISimulationLyricNodeService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Collections; +import java.util.List; @RestController @RequestMapping(value = "/node") @@ -23,7 +34,7 @@ public class SimulationLyricNodeController { private ISimulationLyricNodeService nodeService; @Autowired - private LyricIntegrateService lyricIntegrateService; + private ILyricInternalService lyricInternalService; @GetMapping("/updateApprovalStatus") @Operation(summary = "仿真节点审批状态更新", description = "仿真节点审批状态更新") @@ -34,7 +45,33 @@ public class SimulationLyricNodeController { @GetMapping("/getTodoList") @Operation(summary = "获取待办列表", description = "获取待办列表") public SdmResponse getTodoList() { - return lyricIntegrateService.getTodoList(); + return lyricInternalService.getTodoList(); + } + + @GetMapping("/getProjectList") + @Operation(summary = "获取项目列表", description = "获取项目列表") + public SdmResponse getProjectList() { + return lyricInternalService.getProjectList(); + } + + /** + * 查询审批实例id + * @return + */ + @GetMapping("/getProcessData") + @Operation(summary = "查询审批实例id", description = "查询审批实例id") + public SdmResponse getProcessData(ProcessDataReq req) { + return lyricInternalService.getProcessData(req); + } + + /** + * 推送报告 + * @return + */ + @PostMapping("/pushReport") + @Operation(summary = "推送报告", description = "推送报告") + public SdmResponse pushReport(@RequestBody @Validated PushReportReq req) { + return lyricInternalService.pushReport(req); } } diff --git a/project/src/main/java/com/sdm/project/dao/SimulationProjectSchedulerConfigMapper.java b/project/src/main/java/com/sdm/project/dao/SimulationProjectSchedulerConfigMapper.java new file mode 100644 index 00000000..961bd4f4 --- /dev/null +++ b/project/src/main/java/com/sdm/project/dao/SimulationProjectSchedulerConfigMapper.java @@ -0,0 +1,17 @@ +package com.sdm.project.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.sdm.project.model.entity.SimulationProjectSchedulerConfig; +import com.sdm.project.model.entity.SimulationTodoSchedulerConfig; + +/** + *

+ * Mapper 接口 + *

+ * + * @author author + * @since 2025-11-03 + */ +public interface SimulationProjectSchedulerConfigMapper extends BaseMapper { + +} diff --git a/project/src/main/java/com/sdm/project/dao/SimulationTodoSchedulerConfigMapper.java b/project/src/main/java/com/sdm/project/dao/SimulationTodoSchedulerConfigMapper.java new file mode 100644 index 00000000..fb6ae498 --- /dev/null +++ b/project/src/main/java/com/sdm/project/dao/SimulationTodoSchedulerConfigMapper.java @@ -0,0 +1,16 @@ +package com.sdm.project.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.sdm.project.model.entity.SimulationTodoSchedulerConfig; + +/** + *

+ * Mapper 接口 + *

+ * + * @author author + * @since 2025-11-03 + */ +public interface SimulationTodoSchedulerConfigMapper extends BaseMapper { + +} diff --git a/project/src/main/java/com/sdm/project/job/ProjectSyncJob.java b/project/src/main/java/com/sdm/project/job/ProjectSyncJob.java new file mode 100644 index 00000000..825a982a --- /dev/null +++ b/project/src/main/java/com/sdm/project/job/ProjectSyncJob.java @@ -0,0 +1,21 @@ +package com.sdm.project.job; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import java.time.LocalDateTime; + +/** + * 自定义定时任务执行逻辑 + */ +public class ProjectSyncJob implements Job { + /** + * 核心执行方法:这里写你需要定时执行的代码 + */ + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + String triggerTime = context.getTrigger().getDescription(); + System.out.println("【项目】定时任务执行成功!触发时间:" + triggerTime + ",当前系统时间:" + LocalDateTime.now()); + } +} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/job/TodoSyncJob.java b/project/src/main/java/com/sdm/project/job/TodoSyncJob.java new file mode 100644 index 00000000..9bb4f636 --- /dev/null +++ b/project/src/main/java/com/sdm/project/job/TodoSyncJob.java @@ -0,0 +1,23 @@ +package com.sdm.project.job; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import java.time.LocalDateTime; + +/** + * 自定义定时任务执行逻辑 + */ +public class TodoSyncJob implements Job { + /** + * 核心执行方法:这里写你需要定时执行的代码 + */ + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + String triggerTime = context.getTrigger().getDescription(); + System.out.println("【待办】定时任务执行成功!触发时间:" + triggerTime + ",当前系统时间:" + LocalDateTime.now()); + + + } +} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/manager/MultiJobManager.java b/project/src/main/java/com/sdm/project/manager/MultiJobManager.java new file mode 100644 index 00000000..7af9ef72 --- /dev/null +++ b/project/src/main/java/com/sdm/project/manager/MultiJobManager.java @@ -0,0 +1,100 @@ +package com.sdm.project.manager; + +import org.quartz.*; +import org.quartz.impl.matchers.GroupMatcher; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Component; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 通用定时任务管理类:支持管理多个不同的Job + */ +@Component +public class MultiJobManager { + + @Autowired + private Scheduler scheduler; + + + /** + * 创建指定Job的定时任务 + * @param jobClass 要执行的Job类(比如DataSyncJob.class、MessagePushJob.class) + * @param jobGroup Job分组(区分不同Job,比如"dataSyncGroup"、"messagePushGroup") + * @param timeList 执行时间数组(如["15:00:00","16:00:00"]) + */ + public void createJob(Class jobClass, String jobGroup, List timeList) throws SchedulerException, ParseException { + // 遍历时间数组,为当前Job创建多个定时触发器 + for (String time : timeList) { + // 1. 校验时间格式 + if (!time.matches("^\\d{2}:\\d{2}:\\d{2}$")) { + throw new IllegalArgumentException("时间格式错误:" + time + ",请使用HH:mm:ss格式"); + } + + // 2. 拆分时分秒,构建Cron表达式 + String[] timeParts = time.split(":"); + int second = Integer.parseInt(timeParts[2]); + int minute = Integer.parseInt(timeParts[1]); + int hour = Integer.parseInt(timeParts[0]); + String cronExpression = String.format("%d %d %d * * ?", second, minute, hour); + + // 3. 构建JobDetail(绑定指定的Job类,唯一标识:jobName=时间+分组,jobGroup=传入的分组) + String jobName = jobGroup + "_" + time; + JobDetail jobDetail = JobBuilder.newJob(jobClass) + .withIdentity(jobName, jobGroup) // 唯一标识:名称+分组,区分不同Job的任务 + .build(); + + // 4. 构建Trigger(触发器) + Trigger trigger = TriggerBuilder.newTrigger() + .withIdentity("trigger_" + jobName, jobGroup) + .withDescription(time) + .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) + .build(); + + // 5. 注册任务到调度器 + scheduler.scheduleJob(jobDetail, trigger); + System.out.println("成功创建任务:[" + jobGroup + "] 每日" + time + "执行,Cron:" + cronExpression); + } + } + + /** + * 停止指定分组的所有Job + * @param jobGroup Job分组(如"dataSyncGroup") + */ + public void pauseJobGroup(String jobGroup) throws SchedulerException { + scheduler.pauseJobs(GroupMatcher.jobGroupEquals(jobGroup)); + System.out.println("已暂停分组[" + jobGroup + "]的所有任务"); + } + + /** + * 启动指定分组的所有Job + * @param jobGroup Job分组 + */ + public void resumeJobGroup(String jobGroup) throws SchedulerException { + scheduler.resumeJobs(GroupMatcher.jobGroupEquals(jobGroup)); + System.out.println("已恢复分组[" + jobGroup + "]的所有任务"); + } + + /** + * 删除指定分组的所有Job + * @param jobGroup Job分组 + */ + public void deleteJobGroup(String jobGroup) throws SchedulerException { + // 1. 获取指定分组下的所有TriggerKey(返回Set) + Set triggerKeySet = scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(jobGroup)); + // 2. 将Set转换为List(使用Stream流,简洁高效) + List triggerKeyList = new ArrayList<>(triggerKeySet); + // 3. 取消触发器(此时需要List参数) + scheduler.unscheduleJobs(triggerKeyList); + // 4. 删除指定分组下的所有Job(getJobKeys返回Set,但deleteJobs支持Collection,List/Set都可以) + Set jobKeySet = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(jobGroup)); + scheduler.deleteJobs(new ArrayList<>(jobKeySet)); + System.out.println("已删除分组[" + jobGroup + "]的所有任务"); + } + +} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/manager/MultiJobStartupRunner.java b/project/src/main/java/com/sdm/project/manager/MultiJobStartupRunner.java new file mode 100644 index 00000000..62769e95 --- /dev/null +++ b/project/src/main/java/com/sdm/project/manager/MultiJobStartupRunner.java @@ -0,0 +1,48 @@ +package com.sdm.project.manager; + +import com.sdm.project.job.ProjectSyncJob; +import com.sdm.project.job.TodoSyncJob; +import com.sdm.project.model.entity.SimulationProjectSchedulerConfig; +import com.sdm.project.model.entity.SimulationTodoSchedulerConfig; +import com.sdm.project.service.ISimulationProjectSchedulerConfigService; +import com.sdm.project.service.ISimulationTodoSchedulerConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * 应用启动时自动初始化两个Job + */ +@Component +public class MultiJobStartupRunner implements CommandLineRunner { + + private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); + + @Autowired + private MultiJobManager multiJobManager; + + @Value("${scheduler.todo}") + private String schedulerTodoTime; + + @Value("${scheduler.project}") + private String schedulerProjectTime; + + @Override + public void run(String... args) throws Exception { + // ========== 初始化第一个Job:待办同步任务 ========== + schedulerTodoTime = schedulerTodoTime.replaceAll("\\.",":"); + schedulerProjectTime = schedulerProjectTime.replaceAll("\\.",":"); + multiJobManager.createJob(TodoSyncJob.class, "todoSyncJob", Collections.singletonList(schedulerTodoTime)); + + // ========== 初始化第二个Job:项目同步任务 ========== + multiJobManager.createJob(ProjectSyncJob.class, "projectSyncJob", Collections.singletonList(schedulerProjectTime)); + + System.out.println("应用启动成功!已初始化两个Job:待办同步任务、项目同步任务"); + } +} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/model/entity/SimulationProjectSchedulerConfig.java b/project/src/main/java/com/sdm/project/model/entity/SimulationProjectSchedulerConfig.java new file mode 100644 index 00000000..1cdefedf --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/entity/SimulationProjectSchedulerConfig.java @@ -0,0 +1,42 @@ +package com.sdm.project.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author author + * @since 2025-12-17 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("simulation_project_scheduler_config") +@ApiModel(value = "SimulationWork对象", description = "") +public class SimulationProjectSchedulerConfig implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "应完成任务") + @TableField("executeTime") + private String executeTime; + + + + +} diff --git a/project/src/main/java/com/sdm/project/model/entity/SimulationTodoSchedulerConfig.java b/project/src/main/java/com/sdm/project/model/entity/SimulationTodoSchedulerConfig.java new file mode 100644 index 00000000..85d1b69b --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/entity/SimulationTodoSchedulerConfig.java @@ -0,0 +1,42 @@ +package com.sdm.project.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author author + * @since 2025-12-17 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("simulation_todo_scheduler_config") +@ApiModel(value = "SimulationWork对象", description = "") +public class SimulationTodoSchedulerConfig implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "应完成任务") + @TableField("executeTime") + private String executeTime; + + + + +} diff --git a/project/src/main/java/com/sdm/project/model/req/ProcessDataDetailReq.java b/project/src/main/java/com/sdm/project/model/req/ProcessDataDetailReq.java new file mode 100644 index 00000000..bb6ac3c0 --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/req/ProcessDataDetailReq.java @@ -0,0 +1,14 @@ +package com.sdm.project.model.req; + +import lombok.Data; + +@Data +public class ProcessDataDetailReq { + + private String project_number; + + private String station_no; + + private String status; + +} diff --git a/project/src/main/java/com/sdm/project/model/req/ProcessDataReq.java b/project/src/main/java/com/sdm/project/model/req/ProcessDataReq.java new file mode 100644 index 00000000..365f125b --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/req/ProcessDataReq.java @@ -0,0 +1,17 @@ +package com.sdm.project.model.req; + +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +@Data +public class ProcessDataReq { + + private String jobNo; + + private String queryColumn; + + private ProcessDataDetailReq conditionColumn; + +} diff --git a/project/src/main/java/com/sdm/project/model/req/PushReportReq.java b/project/src/main/java/com/sdm/project/model/req/PushReportReq.java new file mode 100644 index 00000000..b2764774 --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/req/PushReportReq.java @@ -0,0 +1,23 @@ +package com.sdm.project.model.req; + +import com.sdm.common.entity.bo.UserInfo; +import com.sdm.common.entity.pojo.project.ProjectBase; +import com.sdm.common.entity.pojo.project.ProjectExpand; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +@Data +public class PushReportReq { + + @NotEmpty(message = "文件id不能为空") + private List fileIdList; + + private String projectCode; + + private String workspaceCode; + +} diff --git a/project/src/main/java/com/sdm/project/model/req/SchedulerReq.java b/project/src/main/java/com/sdm/project/model/req/SchedulerReq.java new file mode 100644 index 00000000..0b504272 --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/req/SchedulerReq.java @@ -0,0 +1,10 @@ +package com.sdm.project.model.req; + +import lombok.Data; + +import java.util.List; + +@Data +public class SchedulerReq { + List timeList; +} diff --git a/project/src/main/java/com/sdm/project/service/ILyricInternalService.java b/project/src/main/java/com/sdm/project/service/ILyricInternalService.java new file mode 100644 index 00000000..1f3d4ef8 --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/ILyricInternalService.java @@ -0,0 +1,18 @@ +package com.sdm.project.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.sdm.common.common.SdmResponse; +import com.sdm.outbridge.entity.ViewLyricconfig; +import com.sdm.project.model.req.ProcessDataReq; +import com.sdm.project.model.req.PushReportReq; + +public interface ILyricInternalService { + + SdmResponse getProcessData(ProcessDataReq req); + + SdmResponse pushReport(PushReportReq req); + + SdmResponse getTodoList(); + + SdmResponse getProjectList(); +} diff --git a/project/src/main/java/com/sdm/project/service/ISimulationProjectSchedulerConfigService.java b/project/src/main/java/com/sdm/project/service/ISimulationProjectSchedulerConfigService.java new file mode 100644 index 00000000..46c8b39f --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/ISimulationProjectSchedulerConfigService.java @@ -0,0 +1,18 @@ +package com.sdm.project.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.sdm.project.model.entity.SimulationProjectSchedulerConfig; +import com.sdm.project.model.entity.SimulationTodoSchedulerConfig; + +/** + *

+ * 服务类 + *

+ * + * @author author + * @since 2025-12-17 + */ +public interface ISimulationProjectSchedulerConfigService extends IService { + + +} diff --git a/project/src/main/java/com/sdm/project/service/ISimulationTodoSchedulerConfigService.java b/project/src/main/java/com/sdm/project/service/ISimulationTodoSchedulerConfigService.java new file mode 100644 index 00000000..49799b19 --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/ISimulationTodoSchedulerConfigService.java @@ -0,0 +1,20 @@ +package com.sdm.project.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.sdm.common.common.SdmResponse; +import com.sdm.project.model.entity.SimulationTodoSchedulerConfig; +import com.sdm.project.model.entity.SimulationWork; +import com.sdm.project.model.req.SpdmWorkReq; + +/** + *

+ * 服务类 + *

+ * + * @author author + * @since 2025-12-17 + */ +public interface ISimulationTodoSchedulerConfigService extends IService { + + +} diff --git a/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java new file mode 100644 index 00000000..83329fe2 --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java @@ -0,0 +1,186 @@ +package com.sdm.project.service.impl; + +import com.sdm.common.common.SdmResponse; +import com.sdm.common.common.ThreadLocalContext; +import com.sdm.common.feign.impl.data.DataClientFeignClientImpl; +import com.sdm.common.utils.FilesUtil; +import com.sdm.common.utils.RandomUtil; +import com.sdm.outbridge.mode.HkUploadFileReq; +import com.sdm.outbridge.service.lyric.LyricIntegrateService; +import com.sdm.project.common.generator.UniqueFileNameGenerator; +import com.sdm.project.model.req.ProcessDataReq; +import com.sdm.project.model.req.PushReportReq; +import com.sdm.project.service.ILyricInternalService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +@Service +@Slf4j +public class LyricInternalServiceImpl implements ILyricInternalService { + + private static final int BUFFER_SIZE = 1024 * 4; // 4KB缓冲区 + + private static final String TEMP_REPORT_PATH = "/opt/report/"; + + private static final String REPORT_ZIP_NAME = "report_"; + + private static final String ZIP_SUFFIX = ".zip"; + + @Autowired + private LyricIntegrateService lyricIntegrateService; + + @Autowired + private DataClientFeignClientImpl dataFeignClient; + + + @Override + public SdmResponse getProcessData(ProcessDataReq req) { +// return lyricIntegrateService.getProcessData(req); + return SdmResponse.success(); + } + + @Override + public SdmResponse getTodoList() { + return null; + } + + @Override + public SdmResponse getProjectList() { + return null; + } + + @Override + public SdmResponse pushReport(PushReportReq req) { + // 根据文件id下载文件到临时目录 + List fileIdList = req.getFileIdList(); + String randomId = RandomUtil.generateString(16); + String tempPath = TEMP_REPORT_PATH + randomId; + if (CollectionUtils.isNotEmpty(fileIdList)) { + for (Long fileId : fileIdList) { + dataFeignClient.downloadFileToLocal(fileId, tempPath); + } + } + Path folder = Paths.get(tempPath); + if (!Files.exists(folder) || !Files.isDirectory(folder)) { + if (!new File(tempPath).mkdir()) { + log.error("创建临时文件夹:{}失败", tempPath); + throw new RuntimeException("推送报告失败,原因为:创建临时文件夹失败"); + } + } + // 准备要打包的文件列表 + List filesToZip = FilesUtil.getAllFiles(tempPath); + // 指定生成的ZIP文件路径 + String zipFilePath = tempPath + File.separator + REPORT_ZIP_NAME + UniqueFileNameGenerator.generateUniqueFileName() + ZIP_SUFFIX; + log.info("zipFilePath为:{}", zipFilePath); + // 执行打包 + try { + zipFiles(filesToZip, zipFilePath); + } catch (IOException e) { + log.error("打包文件异常:{}", e.getMessage()); + try { + FilesUtil.deleteFolderNonRecursive(tempPath); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + throw new RuntimeException(e); + } + String jobNumber = ThreadLocalContext.getJobNumber(); + HkUploadFileReq uploadFileReq = new HkUploadFileReq(); + uploadFileReq.setFilePower("2456236750149124114"); + uploadFileReq.setWaterMarkFlag(false); + uploadFileReq.setWaterMarkContent("spdm"); + uploadFileReq.setSysId(1691399963692630016L); + uploadFileReq.setFormId(1847115435993071616L); + uploadFileReq.setComponentInstId(8000004142460000204L); + uploadFileReq.setTableName("oa_threee_d_review"); + uploadFileReq.setColumnName("simulation_table"); + uploadFileReq.setXmh(req.getProjectCode()); + uploadFileReq.setGwh(req.getWorkspaceCode()); + uploadFileReq.setFiles(Collections.singletonList(zipFilePath)); + try { + lyricIntegrateService.uploadHkFile(jobNumber, uploadFileReq); + } catch (Exception e) { + log.error("推送zip异常:{}", e.getMessage()); + throw new RuntimeException(e); + } finally { + // 删除临时路径 + log.info("删除临时路径:{},中。。。。。。", tempPath); + try { + FilesUtil.deleteFolderNonRecursive(tempPath); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return SdmResponse.success(); + } + + /** + * 将多个文件打包成ZIP文件 + * + * @param sourceFiles 要打包的文件列表 + * @param zipFilePath 生成的ZIP文件路径 + * @throws IOException IO异常 + */ + public static void zipFiles(List sourceFiles, String zipFilePath) throws IOException { + // 校验输入参数 + if (sourceFiles == null || sourceFiles.isEmpty()) { + throw new IllegalArgumentException("待压缩的文件列表不能为空"); + } + if (zipFilePath == null || zipFilePath.trim().isEmpty()) { + throw new IllegalArgumentException("ZIP文件路径不能为空"); + } + + // 声明流对象,使用try-with-resources自动关闭资源 + try (FileOutputStream fos = new FileOutputStream(zipFilePath); + BufferedOutputStream bos = new BufferedOutputStream(fos); + ZipOutputStream zos = new ZipOutputStream(bos)) { + zos.setLevel(9); // 设置压缩级别,0-9,9为最高压缩率 + // 遍历所有文件并添加到ZIP中 + for (File file : sourceFiles) { + if (file.exists() && file.isFile()) { // 只处理存在的文件(跳过目录) + addFileToZip(zos, file); + } else { + log.info("跳过无效文件:{}" , file.getAbsolutePath()); + } + } + log.info("ZIP文件创建成功:{}" , zipFilePath); + } catch (IOException e) { + log.error("创建ZIP文件失败:{}" , e.getMessage()); + throw e; // 抛出异常让调用方处理 + } + } + + /** + * 将单个文件添加到ZIP输出流中 + * + * @param zos ZIP输出流 + * @param file 要添加的文件 + * @throws IOException IO异常 + */ + private static void addFileToZip(ZipOutputStream zos, File file) throws IOException { + // 创建ZIP条目,使用文件名作为条目名 + ZipEntry zipEntry = new ZipEntry(file.getName()); + zos.putNextEntry(zipEntry); + // 读取文件内容并写入ZIP流 + try (FileInputStream fis = new FileInputStream(file); + BufferedInputStream bis = new BufferedInputStream(fis, BUFFER_SIZE)) { + byte[] buffer = new byte[BUFFER_SIZE]; + int bytesRead; + while ((bytesRead = bis.read(buffer)) != -1) { + zos.write(buffer, 0, bytesRead); + } + zos.closeEntry(); // 关闭当前ZIP条目 + } + } +} diff --git a/project/src/main/java/com/sdm/project/service/impl/ISimulationLyricNodeServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/SimulationLyricNodeServiceImpl.java similarity index 87% rename from project/src/main/java/com/sdm/project/service/impl/ISimulationLyricNodeServiceImpl.java rename to project/src/main/java/com/sdm/project/service/impl/SimulationLyricNodeServiceImpl.java index 822df49d..f6a5785b 100644 --- a/project/src/main/java/com/sdm/project/service/impl/ISimulationLyricNodeServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/SimulationLyricNodeServiceImpl.java @@ -15,11 +15,11 @@ import java.util.List; @Service @Slf4j -public class ISimulationLyricNodeServiceImpl extends ServiceImpl implements ISimulationLyricNodeService { +public class SimulationLyricNodeServiceImpl extends ServiceImpl implements ISimulationLyricNodeService { @Override public SdmResponse updateApprovalStatus(String projectName, String workspaceName, Integer approvalStatus) { - + log.info("仿真节点审批状态更新中,projectName为:{},workspaceName为:{},approvalStatus为:{}",projectName,workspaceName,approvalStatus); // 0:未通过,1:已通过 String approvalStatusValue = String.valueOf(approvalStatus == 0 ? ApprovalStatusEnum.REJECTED.getCode() : ApprovalStatusEnum.PASSED.getCode()); List projectNodeList = this.lambdaQuery().eq(SimulationNode::getNodeName, projectName) diff --git a/project/src/main/java/com/sdm/project/service/impl/SimulationProjectSchedulerConfigServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/SimulationProjectSchedulerConfigServiceImpl.java new file mode 100644 index 00000000..164fa77b --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/impl/SimulationProjectSchedulerConfigServiceImpl.java @@ -0,0 +1,24 @@ +package com.sdm.project.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.sdm.project.dao.SimulationProjectSchedulerConfigMapper; +import com.sdm.project.dao.SimulationTodoSchedulerConfigMapper; +import com.sdm.project.model.entity.SimulationProjectSchedulerConfig; +import com.sdm.project.model.entity.SimulationTodoSchedulerConfig; +import com.sdm.project.service.ISimulationProjectSchedulerConfigService; +import com.sdm.project.service.ISimulationTodoSchedulerConfigService; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author author + * @since 2025-11-03 + */ +@Service +public class SimulationProjectSchedulerConfigServiceImpl extends ServiceImpl implements ISimulationProjectSchedulerConfigService { + + +} diff --git a/project/src/main/java/com/sdm/project/service/impl/SimulationTodoSchedulerConfigServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/SimulationTodoSchedulerConfigServiceImpl.java new file mode 100644 index 00000000..bb8ef73c --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/impl/SimulationTodoSchedulerConfigServiceImpl.java @@ -0,0 +1,21 @@ +package com.sdm.project.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.sdm.project.dao.SimulationTodoSchedulerConfigMapper; +import com.sdm.project.model.entity.SimulationTodoSchedulerConfig; +import com.sdm.project.service.ISimulationTodoSchedulerConfigService; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author author + * @since 2025-11-03 + */ +@Service +public class SimulationTodoSchedulerConfigServiceImpl extends ServiceImpl implements ISimulationTodoSchedulerConfigService { + + +} diff --git a/project/src/main/resources/application-local.yml b/project/src/main/resources/application-local.yml index a068d942..76743aea 100644 --- a/project/src/main/resources/application-local.yml +++ b/project/src/main/resources/application-local.yml @@ -137,3 +137,7 @@ YA: #publicKeyUrl : http://s279983e.natappfree.cc/api-auth/clients/getPublicKey publicKeyUrl : http://pisxwh.8866.org:8015/gateway/api-auth/clients/getPublicKey frontendPrivateKey : MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjz2pItCtM2Itf3knLhA1ZWzTVtKKY692Eptk3ZUy4qjlv+2e6u78/cBYZsVa/1nOyHPtb2j9xZAsHYGKZGoh64UWSewUhRdUO15xBRr5DyGEdTWHjwc1GHf7c99rKCjKDO2Xdp7cpqYABOAxgkSA2vP5zqhSCq0FCqwleEPLG1aAa/kh/oUzCZLUoSjZIdqQOgHJTZojqNeQCOC6U8Q+kUcHdKbptewu1A6XK8DHV0WqiJJEG3kyaoAZ1kGtr6ETtGy++aRvJT9gZN4M4bIgucKtAu2dcqQHj9jZ1i2xwhY3nmLjqaz3y313/IEYpMTG8pnPb8eP5usHDaDmH8RqJAgMBAAECggEAAzz05WYGWxkGvEjpHYhJOUR3yWeuNSaodNhVf+ZVO2tGAmQuWz8d2zOshCqAw/8Jv3IaN+kbCvNG0okBufQP0ZoFZY1f/xXhzc7OTG4JEc7yuIEQl897btDl+lk97nOAJx7z9ws7MCwlFyEUAY6s29glkYTBrgmTmy1FXKIqImsLfVV3LgfL2Mkixn0YSSsbUh2b+dki1zxjct3hTGZVh29bKOpbflOaG0LqEO0UwSX92Y/ir+fKmC8zEFbi5HZANYODivm8DiwF7khpraayf78kG3liccOTMMLVxIHwNiS9wcLG8WPuVEphlXMT4Ev4lq5VFM3mVxtd9g21ESbuvwKBgQDmsgE8u66qKVBsndp2K9FV9VWYDA4fYfRswDAWnZDCzIdanT0NFPp8s3nZCVU4FfX4m958yOrJ/MVp6d58z6fgkYQh2qL2Wy6zRPaIxCc6JG3FheFSxfWyULU/mBBK02ntUZCXEs8XKjAfDvmxaVVeonv0nCSgVwxJ4ypB5BZ+owKBgQC1x0GDnWtMbNGUMx6tYtFGWQIgop4hVQe6ZNgkKaQX7gtMa5egEda6ga6wCTV3+ZvQ9tBa1DxUFb5N/TrtQdFm39gOSXyhWSrntUKqaSFo03GvXXvvze2D3+uXpk7S8yzWuuD3OYyYj9S3nFVZffymabfukuY7oY3AN0E0PALw4wKBgQDQiyGrMU6X7HkTdy9BnCLEvd7+cAdkPzyiAqp2B0IRlqrVM0c5SDmX+PaxSEqNROzyLJVX4Ji+t44OTKgf0+hCjckQgYDHi24QCMuEny2G1d+Vq40hMmsFIwh10JUJz0v2iMFYkFw86JpPuU3nHv1ZazD60xwZBhfJw10z62iaWQKBgH+EVgsUJS8pryO9cKnFBnXI/tsR+Mf9NDynfZBwvbIjxT1IxMb/fJi9XGQVMbMGIS5H1gXBmMiLsEJZgDrrzw/Ru2jaWFl/ib+dwjR1J4C3w6p3c/fXh+TY8hYiDm2hNTU1R5dmgaCMVXawbpcm8FN1Ghh8aJIwVJYgrNcNuiptAoGAO14DHGqUXZZ//erIYWVfL0CAMXqy38dqNmfbzSAXYyLDl6cn49CCHF0GXOfCOesQN9ToQbqpLrntFgcFe0hil5dIWYafk9fHjjR8N8g74ijErQmCEAQy22b06V0q7rLzEsU/HDVL+RZg2aY4hDN+ODHRdpdFkOxsCYV73gevVeo= + +scheduler: + todo: 10.10.00 + project: 10.11.00 \ No newline at end of file