From 2dab8f45b04eca6c0566fcb9e549f11bd2ad5bca Mon Sep 17 00:00:00 2001 From: dhb52 Date: Tue, 28 May 2024 00:30:02 +0800 Subject: [PATCH] =?UTF-8?q?wip(sj=5F1.0.0):=20=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E5=AF=BC=E5=85=A5=E3=80=81=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/web/controller/JobController.java | 75 +++++++++++++++++++ .../server/web/service/JobService.java | 7 ++ .../web/service/convert/JobConverter.java | 4 + .../web/service/impl/JobServiceImpl.java | 31 +++++++- 4 files changed, 113 insertions(+), 4 deletions(-) diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/JobController.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/JobController.java index a8c4d424..b9ec9790 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/JobController.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/JobController.java @@ -1,17 +1,37 @@ package com.aizuda.snailjob.server.web.controller; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.lang.Assert; +import com.aizuda.snailjob.common.core.annotation.OriginalControllerReturnValue; +import com.aizuda.snailjob.common.core.exception.SnailJobCommonException; +import com.aizuda.snailjob.common.core.util.JsonUtil; +import com.aizuda.snailjob.server.common.exception.SnailJobServerException; +import com.aizuda.snailjob.server.common.util.DateUtils; import com.aizuda.snailjob.server.web.annotation.LoginRequired; +import com.aizuda.snailjob.server.web.annotation.RoleEnum; import com.aizuda.snailjob.server.web.model.base.PageResult; import com.aizuda.snailjob.server.web.model.request.JobQueryVO; import com.aizuda.snailjob.server.web.model.request.JobRequestVO; import com.aizuda.snailjob.server.web.model.request.JobUpdateJobStatusRequestVO; import com.aizuda.snailjob.server.web.model.response.JobResponseVO; import com.aizuda.snailjob.server.web.service.JobService; +import com.fasterxml.jackson.databind.JsonNode; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Set; /** * @author opensnail @@ -22,6 +42,8 @@ import java.util.List; @RequestMapping("/job") public class JobController { + private static final List FILE_EXTENSIONS = List.of("json"); + @Autowired private JobService jobService; @@ -88,4 +110,57 @@ public class JobController { public Boolean trigger(@PathVariable("jobId") Long jobId) { return jobService.trigger(jobId); } + + @PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @LoginRequired(role = RoleEnum.ADMIN) + public void importScene(@RequestPart("file") MultipartFile file) throws IOException { + if (file.isEmpty()) { + throw new SnailJobCommonException("请选择一个文件上传"); + } + + // 保存文件到服务器 + String suffix = FileUtil.getSuffix(file.getOriginalFilename()); + if (!FILE_EXTENSIONS.contains(suffix)) { + throw new SnailJobCommonException("文件类型错误"); + } + + JsonNode node = JsonUtil.toJson(file.getBytes()); + + List requestList = JsonUtil.parseList(JsonUtil.toJsonString(node), + JobRequestVO.class); + requestList.forEach(vo -> vo.setId(null)); + + Assert.notEmpty(requestList, () -> new SnailJobServerException("导入数据不能为空")); + + // 校验参数是否合法 + requestList.forEach(vo ->{ + ValidatorFactory vf = Validation.buildDefaultValidatorFactory(); + Validator validator = vf.getValidator(); + Set> set = validator.validate(vo); + for (final ConstraintViolation violation : set) { + throw new SnailJobCommonException(violation.getMessage()); + } + }); + + jobService.importJobs(requestList); + } + + @PostMapping("/export") + @LoginRequired(role = RoleEnum.ADMIN) + @OriginalControllerReturnValue + public ResponseEntity exportGroup(@RequestBody Set jobIds) { + String jobsJson = jobService.exportJobs(jobIds); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + // 设置下载时的文件名称 + String fileName = String.format("job-%s.json", DateUtils.toNowFormat(DateUtils.PURE_DATETIME_MS_PATTERN)); + String disposition = "attachment; filename=" + + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); + headers.add(HttpHeaders.CONTENT_DISPOSITION, disposition); + return ResponseEntity.ok() + .headers(headers) + .body(jobsJson); + } + } diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/JobService.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/JobService.java index b5a0e422..97376842 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/JobService.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/JobService.java @@ -6,8 +6,10 @@ import com.aizuda.snailjob.server.web.model.request.JobRequestVO; import com.aizuda.snailjob.server.web.model.request.JobUpdateJobStatusRequestVO; import com.aizuda.snailjob.server.web.model.response.JobResponseVO; import com.aizuda.snailjob.template.datasource.persistence.po.Job; +import jakarta.validation.Valid; import java.util.List; +import java.util.Set; /** * @author opensnail @@ -36,4 +38,9 @@ public interface JobService { boolean trigger(Long jobId); List getJobList(String groupName); + + void importJobs(List requestList); + + String exportJobs(Set jobIds); + } diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/convert/JobConverter.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/convert/JobConverter.java index 833d18a2..bb6e05f0 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/convert/JobConverter.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/convert/JobConverter.java @@ -5,6 +5,8 @@ import com.aizuda.snailjob.template.datasource.persistence.po.Job; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; +import java.util.List; + /** * @author: opensnail * @date : 2023-10-12 09:40 @@ -17,4 +19,6 @@ public interface JobConverter { Job convert(JobRequestVO jobRequestVO); + List convertList(List jobs); + } diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/JobServiceImpl.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/JobServiceImpl.java index 6b701120..567a3a5d 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/JobServiceImpl.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/JobServiceImpl.java @@ -1,10 +1,14 @@ package com.aizuda.snailjob.server.web.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.HashUtil; import cn.hutool.core.util.StrUtil; import com.aizuda.snailjob.common.core.constant.SystemConstants; +import com.aizuda.snailjob.common.core.context.SpringContext; import com.aizuda.snailjob.common.core.enums.StatusEnum; +import com.aizuda.snailjob.common.core.util.JsonUtil; +import com.aizuda.snailjob.common.core.util.StreamUtils; import com.aizuda.snailjob.server.common.WaitStrategy; import com.aizuda.snailjob.server.common.config.SystemProperties; import com.aizuda.snailjob.server.common.enums.JobTaskExecutorSceneEnum; @@ -17,16 +21,14 @@ import com.aizuda.snailjob.server.job.task.support.JobPrepareHandler; import com.aizuda.snailjob.server.job.task.support.JobTaskConverter; import com.aizuda.snailjob.server.job.task.support.cache.ResidentTaskCache; import com.aizuda.snailjob.server.web.model.base.PageResult; -import com.aizuda.snailjob.server.web.model.request.JobQueryVO; -import com.aizuda.snailjob.server.web.model.request.JobRequestVO; -import com.aizuda.snailjob.server.web.model.request.JobUpdateJobStatusRequestVO; -import com.aizuda.snailjob.server.web.model.request.UserSessionVO; +import com.aizuda.snailjob.server.web.model.request.*; import com.aizuda.snailjob.server.web.model.response.JobResponseVO; import com.aizuda.snailjob.server.web.service.JobService; import com.aizuda.snailjob.server.web.service.convert.JobConverter; import com.aizuda.snailjob.server.web.service.convert.JobResponseVOConverter; import com.aizuda.snailjob.server.web.util.UserSessionUtils; import com.aizuda.snailjob.template.datasource.access.AccessTemplate; +import com.aizuda.snailjob.template.datasource.access.ConfigAccess; import com.aizuda.snailjob.template.datasource.persistence.mapper.JobMapper; import com.aizuda.snailjob.template.datasource.persistence.po.GroupConfig; import com.aizuda.snailjob.template.datasource.persistence.po.Job; @@ -34,12 +36,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.framework.AopContext; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; /** * @author opensnail @@ -242,4 +247,22 @@ public class JobServiceImpl implements JobService { List jobResponseList = JobResponseVOConverter.INSTANCE.convertList(jobs); return jobResponseList; } + + @Transactional(rollbackFor = Exception.class) + @Override + public void importJobs(List requestList) { + requestList.forEach(vo -> saveJob(vo)); + } + + @Override + public String exportJobs(Set jobIds) { + if (CollUtil.isEmpty(jobIds)) { + return StrUtil.EMPTY; + } + + List jobList = jobMapper.selectBatchIds(jobIds); + jobList.forEach(job -> job.setId(null)); + return JsonUtil.toJsonString(JobConverter.INSTANCE.convertList(jobList)); + } + }