diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/ExternalSystemApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/ExternalSystemApiController.java index dfdc380c..47dec01a 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/ExternalSystemApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/ExternalSystemApiController.java @@ -54,6 +54,22 @@ public class ExternalSystemApiController extends BaseController getJenkinsInstance( + @Parameter(description = "外部系统ID", required = true) @PathVariable Long id + ) { + return Response.success(externalSystemService.getJenkinsInstance(id)); + } + + @Operation(summary = "获取Git实例信息") + @GetMapping("/{id}/git-instance") + public Response getGitInstance( + @Parameter(description = "外部系统ID", required = true) @PathVariable Long id + ) { + return Response.success(externalSystemService.getGitInstance(id)); + } + @Override protected void exportData(HttpServletResponse response, List data) { // TODO: 实现导出功能 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsBuildApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsBuildApiController.java index 3238969b..57446664 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsBuildApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsBuildApiController.java @@ -1,13 +1,17 @@ package com.qqchen.deploy.backend.deploy.api; +import com.qqchen.deploy.backend.framework.api.Response; import com.qqchen.deploy.backend.framework.controller.BaseController; import com.qqchen.deploy.backend.deploy.entity.JenkinsBuild; import com.qqchen.deploy.backend.deploy.dto.JenkinsBuildDTO; import com.qqchen.deploy.backend.deploy.query.JenkinsBuildQuery; +import com.qqchen.deploy.backend.deploy.service.IJenkinsBuildService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -20,6 +24,29 @@ import java.util.List; @Tag(name = "Jenkins构建信息管理", description = "Jenkins构建信息管理相关接口") public class JenkinsBuildApiController extends BaseController { + @Resource + private IJenkinsBuildService jenkinsBuildService; + + @Operation(summary = "同步Jenkins构建", description = "异步同步,支持三种模式:1)只传externalSystemId-全量同步 2)传externalSystemId+viewId-同步视图 3)传externalSystemId+viewId+jobId-同步单个任务") + @PostMapping("/sync") + public Response sync( + @Parameter(description = "外部系统ID", required = true) @RequestParam Long externalSystemId, + @Parameter(description = "视图ID(可选)", required = false) @RequestParam(required = false) Long viewId, + @Parameter(description = "任务ID(可选,传此参数时viewId必传)", required = false) @RequestParam(required = false) Long jobId + ) { + if (jobId != null) { + // 同步单个任务 + jenkinsBuildService.syncBuilds(externalSystemId, viewId, jobId); + } else if (viewId != null) { + // 同步视图 + jenkinsBuildService.syncBuilds(externalSystemId, viewId); + } else { + // 全量同步 + jenkinsBuildService.syncBuilds(externalSystemId); + } + return Response.success(); + } + @Override protected void exportData(HttpServletResponse response, List data) { // TODO: 实现导出逻辑 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsJobApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsJobApiController.java index 13f4e622..57a678ba 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsJobApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsJobApiController.java @@ -1,13 +1,17 @@ package com.qqchen.deploy.backend.deploy.api; +import com.qqchen.deploy.backend.framework.api.Response; import com.qqchen.deploy.backend.framework.controller.BaseController; import com.qqchen.deploy.backend.deploy.entity.JenkinsJob; import com.qqchen.deploy.backend.deploy.dto.JenkinsJobDTO; import com.qqchen.deploy.backend.deploy.query.JenkinsJobQuery; +import com.qqchen.deploy.backend.deploy.service.IJenkinsJobService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -20,6 +24,25 @@ import java.util.List; @Tag(name = "Jenkins工作管理", description = "Jenkins工作管理相关接口") public class JenkinsJobApiController extends BaseController { + @Resource + private IJenkinsJobService jenkinsJobService; + + @Operation(summary = "同步Jenkins任务", description = "异步同步,支持两种模式:1)只传externalSystemId-全量同步 2)传externalSystemId+viewId-同步指定视图") + @PostMapping("/sync") + public Response sync( + @Parameter(description = "外部系统ID", required = true) @RequestParam Long externalSystemId, + @Parameter(description = "视图ID(可选)", required = false) @RequestParam(required = false) Long viewId + ) { + if (viewId != null) { + // 同步指定视图 + jenkinsJobService.syncJobs(externalSystemId, viewId); + } else { + // 全量同步 + jenkinsJobService.syncJobs(externalSystemId); + } + return Response.success(); + } + @Override protected void exportData(HttpServletResponse response, List data) { // TODO: 实现导出逻辑 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsManagerApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsManagerApiController.java deleted file mode 100644 index dbdda5ae..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsManagerApiController.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.qqchen.deploy.backend.deploy.api; - -import com.qqchen.deploy.backend.deploy.dto.JenkinsInstanceDTO; -import com.qqchen.deploy.backend.deploy.service.IJenkinsManagerService; -import com.qqchen.deploy.backend.framework.api.Response; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.*; - -/** - * Jenkins管理API控制器 - */ -@Slf4j -@RestController -@RequestMapping("/api/v1/jenkins-manager") -@Tag(name = "Jenkins管理", description = "Jenkins管理相关接口") -public class JenkinsManagerApiController { - - @Resource - private IJenkinsManagerService jenkinsManagerService; - - @Operation(summary = "同步所有Jenkins数据") - @PostMapping("/{externalSystemId}/sync-all") - public Response syncAll( - @Parameter(description = "外部系统ID", required = true) @PathVariable Long externalSystemId - ) { - jenkinsManagerService.syncAll(externalSystemId); - return Response.success(); - } - - @Operation(summary = "同步Jenkins视图") - @PostMapping("/{externalSystemId}/sync-views") - public Response syncViews( - @Parameter(description = "外部系统ID", required = true) @PathVariable Long externalSystemId - ) { - jenkinsManagerService.syncViews(externalSystemId); - return Response.success(); - } - - @Operation(summary = "同步Jenkins任务") - @PostMapping("/{externalSystemId}/sync-jobs") - public Response syncJobs( - @Parameter(description = "外部系统ID", required = true) @PathVariable Long externalSystemId - ) { - jenkinsManagerService.syncJobs(externalSystemId); - return Response.success(); - } - - @Operation(summary = "同步Jenkins构建信息") - @PostMapping("/{externalSystemId}/sync-builds") - public Response syncBuilds( - @Parameter(description = "外部系统ID", required = true) @PathVariable Long externalSystemId - ) { - jenkinsManagerService.syncBuilds(externalSystemId); - return Response.success(); - } - - @Operation(summary = "获取Jenkins实例信息") - @GetMapping("/{externalSystemId}/instance") - public Response instance(@Parameter(description = "外部系统ID", required = true) @PathVariable Long externalSystemId) { - return Response.success(jenkinsManagerService.instance(externalSystemId)); - } -} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsViewApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsViewApiController.java index 988bdf7c..3b7a2d04 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsViewApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/JenkinsViewApiController.java @@ -1,13 +1,17 @@ package com.qqchen.deploy.backend.deploy.api; +import com.qqchen.deploy.backend.framework.api.Response; import com.qqchen.deploy.backend.framework.controller.BaseController; import com.qqchen.deploy.backend.deploy.entity.JenkinsView; import com.qqchen.deploy.backend.deploy.dto.JenkinsViewDTO; import com.qqchen.deploy.backend.deploy.query.JenkinsViewQuery; +import com.qqchen.deploy.backend.deploy.service.IJenkinsViewService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -20,6 +24,18 @@ import java.util.List; @Tag(name = "Jenkins视图管理", description = "Jenkins视图管理相关接口") public class JenkinsViewApiController extends BaseController { + @Resource + private IJenkinsViewService jenkinsViewService; + + @Operation(summary = "同步Jenkins视图", description = "异步同步指定外部系统的所有Jenkins视图,立即返回") + @PostMapping("/sync") + public Response sync( + @Parameter(description = "外部系统ID", required = true) @RequestParam Long externalSystemId + ) { + jenkinsViewService.syncViews(externalSystemId); + return Response.success(); + } + @Override protected void exportData(HttpServletResponse response, List data) { // TODO: 实现导出逻辑 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsJobDTO.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsJobDTO.java index f6c5d37a..03772c34 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsJobDTO.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsJobDTO.java @@ -34,4 +34,9 @@ public class JenkinsJobDTO extends BaseDTO { private Long viewId; + /** + * 关联的构建数量(仅在列表和分页查询时填充) + */ + private Long buildCount; + } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsViewDTO.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsViewDTO.java index 101c6f7f..7cdd1221 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsViewDTO.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/JenkinsViewDTO.java @@ -20,4 +20,9 @@ public class JenkinsViewDTO extends BaseDTO { private String viewUrl; + /** + * 关联的任务数量(仅在列表和分页查询时填充) + */ + private Long jobCount; + } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsBuildRepository.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsBuildRepository.java index 9b4ead38..55e69462 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsBuildRepository.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsBuildRepository.java @@ -42,4 +42,12 @@ public interface IJenkinsBuildRepository extends IBaseRepository findTopByExternalSystemIdAndJobIdOrderByBuildNumberDesc( Long externalSystemId, Long jobId); + + /** + * 统计任务下的构建数量 + * + * @param jobId 任务ID + * @return 构建数量 + */ + Long countByJobIdAndDeletedFalse(Long jobId); } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsJobRepository.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsJobRepository.java index 885aa963..88fb6b9f 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsJobRepository.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IJenkinsJobRepository.java @@ -31,4 +31,12 @@ public interface IJenkinsJobRepository extends IBaseRepository * @return 任务列表 */ List findByExternalSystemIdAndViewId(Long externalSystemId, Long viewId); + + /** + * 统计视图下的任务数量 + * + * @param viewId 视图ID + * @return 任务数量 + */ + Long countByViewIdAndDeletedFalse(Long viewId); } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IExternalSystemService.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IExternalSystemService.java index 11a419ba..5991db71 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IExternalSystemService.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IExternalSystemService.java @@ -1,5 +1,6 @@ package com.qqchen.deploy.backend.deploy.service; +import com.qqchen.deploy.backend.deploy.dto.JenkinsInstanceDTO; import com.qqchen.deploy.backend.deploy.entity.ExternalSystem; import com.qqchen.deploy.backend.framework.service.IBaseService; import com.qqchen.deploy.backend.system.model.ExternalSystemDTO; @@ -23,4 +24,20 @@ public interface IExternalSystemService extends IBaseService { /** - * 同步外部系统下所有构建信息 + * 同步外部系统下所有构建信息(异步执行) * * @param externalSystemId 外部系统ID - * @return 同步的构建总数 */ - Integer syncAllBuilds(Long externalSystemId); + void syncBuilds(Long externalSystemId); + + /** + * 同步指定视图下的构建信息(异步执行) + * + * @param externalSystemId 外部系统ID + * @param viewId 视图ID + */ + void syncBuilds(Long externalSystemId, Long viewId); + + /** + * 同步指定任务的构建信息(异步执行) + * + * @param externalSystemId 外部系统ID + * @param viewId 视图ID + * @param jobId 任务ID + */ + void syncBuilds(Long externalSystemId, Long viewId, Long jobId); /** * 根据外部系统ID统计构建总数 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IJenkinsJobService.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IJenkinsJobService.java index 86eae16f..5374c981 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IJenkinsJobService.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IJenkinsJobService.java @@ -23,12 +23,19 @@ public interface IJenkinsJobService extends IBaseService { /** - * 同步Jenkins视图 + * 同步Jenkins视图(异步执行) * * @param externalSystemId 外部系统ID - * @return 同步的视图数量 */ - Integer syncViews(Long externalSystemId); + void syncViews(Long externalSystemId); /** * 根据外部系统ID查询所有视图 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ExternalSystemServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ExternalSystemServiceImpl.java index c398e294..e1f7b3bd 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ExternalSystemServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ExternalSystemServiceImpl.java @@ -1,6 +1,18 @@ package com.qqchen.deploy.backend.deploy.service.impl; +import com.qqchen.deploy.backend.deploy.dto.*; import com.qqchen.deploy.backend.deploy.entity.ExternalSystem; +import com.qqchen.deploy.backend.deploy.entity.JenkinsSyncHistory; +import com.qqchen.deploy.backend.deploy.entity.RepositorySyncHistory; +import com.qqchen.deploy.backend.deploy.enums.ExternalSystemSyncStatus; +import com.qqchen.deploy.backend.deploy.enums.JenkinsSyncType; +import com.qqchen.deploy.backend.deploy.enums.RepositorySyncType; +import com.qqchen.deploy.backend.deploy.repository.IJenkinsSyncHistoryRepository; +import com.qqchen.deploy.backend.deploy.repository.IRepositorySyncHistoryRepository; +import com.qqchen.deploy.backend.deploy.service.*; +import com.qqchen.deploy.backend.deploy.service.IJenkinsBuildService; +import com.qqchen.deploy.backend.deploy.service.IJenkinsJobService; +import com.qqchen.deploy.backend.deploy.service.IJenkinsViewService; import com.qqchen.deploy.backend.system.enums.ExternalSystemAuthTypeEnum; import com.qqchen.deploy.backend.system.enums.ExternalSystemSyncStatusEnum; import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum; @@ -51,6 +63,30 @@ public class ExternalSystemServiceImpl extends BaseServiceImpl systemIntegrations; private Map integrationMap; + + @Resource + private IJenkinsViewService jenkinsViewService; + + @Resource + private IJenkinsJobService jenkinsJobService; + + @Resource + private IJenkinsBuildService jenkinsBuildService; + + @Resource + private IJenkinsSyncHistoryRepository jenkinsSyncHistoryRepository; + + @Resource + private IRepositoryGroupService repositoryGroupService; + + @Resource + private IRepositoryProjectService repositoryProjectService; + + @Resource + private IRepositoryBranchService repositoryBranchService; + + @Resource + private IRepositorySyncHistoryRepository repositorySyncHistoryRepository; @PostConstruct public void init() { @@ -129,4 +165,89 @@ public class ExternalSystemServiceImpl extends BaseServiceImpl views = jenkinsViewService.findByExternalSystemId(externalSystemId); + instanceDTO.setJenkinsViewList(views); + instanceDTO.setTotalViews(views.size()); + + // 3. 获取任务列表 + List jobs = jenkinsJobService.findByExternalSystemId(externalSystemId); + instanceDTO.setJenkinsJobList(jobs); + instanceDTO.setTotalJobs(jobs.size()); + + // 4. 获取构建总数 + Long totalBuilds = jenkinsBuildService.countByExternalSystemId(externalSystemId); + instanceDTO.setTotalBuilds(totalBuilds.intValue()); + + // 5. 获取最后同步时间 + JenkinsSyncHistory lastViewSync = jenkinsSyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( + externalSystemId, JenkinsSyncType.VIEW, ExternalSystemSyncStatus.SUCCESS); + if (lastViewSync != null) { + instanceDTO.setLastSyncViewsTime(lastViewSync.getEndTime()); + } + + JenkinsSyncHistory lastJobSync = jenkinsSyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( + externalSystemId, JenkinsSyncType.JOB, ExternalSystemSyncStatus.SUCCESS); + if (lastJobSync != null) { + instanceDTO.setLastSyncJobsTime(lastJobSync.getEndTime()); + } + + JenkinsSyncHistory lastBuildSync = jenkinsSyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( + externalSystemId, JenkinsSyncType.BUILD, ExternalSystemSyncStatus.SUCCESS); + if (lastBuildSync != null) { + instanceDTO.setLastSyncBuildsTime(lastBuildSync.getEndTime()); + } + + return instanceDTO; + } + + @Override + public GitInstanceDTO getGitInstance(Long externalSystemId) { + // 1. 创建返回对象 + GitInstanceDTO instanceDTO = new GitInstanceDTO(); + + // 2. 获取仓库组列表 + List groups = repositoryGroupService.findByExternalSystemId(externalSystemId); + instanceDTO.setRepositoryGroupList(groups); + instanceDTO.setTotalGroups(groups.size()); + + // 3. 获取项目列表 + List projects = repositoryProjectService.findByExternalSystemId(externalSystemId); + instanceDTO.setRepositoryProjectList(projects); + instanceDTO.setTotalProjects(projects.size()); + + // 4. 获取分支总数 + Long totalBranches = repositoryBranchService.countByExternalSystemId(externalSystemId); + instanceDTO.setTotalBranches(totalBranches.intValue()); + + // 5. 获取最后同步时间 + RepositorySyncHistory lastGroupSync = repositorySyncHistoryRepository + .findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( + externalSystemId, RepositorySyncType.GROUP, ExternalSystemSyncStatus.SUCCESS); + if (lastGroupSync != null) { + instanceDTO.setLastSyncGroupsTime(lastGroupSync.getEndTime()); + } + + RepositorySyncHistory lastProjectSync = repositorySyncHistoryRepository + .findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( + externalSystemId, RepositorySyncType.PROJECT, ExternalSystemSyncStatus.SUCCESS); + if (lastProjectSync != null) { + instanceDTO.setLastSyncProjectsTime(lastProjectSync.getEndTime()); + } + + RepositorySyncHistory lastBranchSync = repositorySyncHistoryRepository + .findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( + externalSystemId, RepositorySyncType.BRANCH, ExternalSystemSyncStatus.SUCCESS); + if (lastBranchSync != null) { + instanceDTO.setLastSyncBranchesTime(lastBranchSync.getEndTime()); + } + + return instanceDTO; + } + } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsBuildServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsBuildServiceImpl.java index 27e27a7f..5de75341 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsBuildServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsBuildServiceImpl.java @@ -19,6 +19,7 @@ import com.qqchen.deploy.backend.framework.exception.BusinessException; import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -61,19 +62,10 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl new BusinessException(ResponseCode.DATA_NOT_FOUND)); + JenkinsView view = jenkinsViewRepository.findById(job.getViewId()) + .orElseThrow(() -> new BusinessException(ResponseCode.DATA_NOT_FOUND)); + // 获取该任务的最新状态 + List jobResponses = jenkinsServiceIntegration.listJobs(context.getExternalSystem(), view.getViewName()); + JenkinsJobResponse jobResponse = jobResponses.stream() + .filter(r -> r.getName().equals(job.getJobName())) + .findFirst() + .orElse(null); + int syncedCount = syncJob(context.getExternalSystem(), job, jobResponse); + log.info("Synchronized {} builds for job: {}", syncedCount, job.getJobName()); + } else if (viewId != null) { + // 同步指定视图下的所有构建 + JenkinsView view = jenkinsViewRepository.findById(viewId) + .orElseThrow(() -> new BusinessException(ResponseCode.DATA_NOT_FOUND)); + int syncedCount = syncView(context.getExternalSystem(), view); + log.info("Synchronized {} builds for view: {}", syncedCount, view.getViewName()); + } else { + // 全量同步 + doSync(context); + } + + // 3. 更新同步历史为成功 + updateSyncHistorySuccess(context.getSyncHistory()); + log.info("Successfully synchronized builds for external system: {}", externalSystemId); + } catch (Exception e) { + handleSyncException(context, e); + throw e; + } + } + @Override public Long countByExternalSystemId(Long externalSystemId) { QJenkinsBuild qJenkinsBuild = QJenkinsBuild.jenkinsBuild; diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsJobServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsJobServiceImpl.java index 14fe7201..b6bd5aba 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsJobServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsJobServiceImpl.java @@ -22,6 +22,7 @@ import com.qqchen.deploy.backend.framework.exception.BusinessException; import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -61,15 +62,41 @@ public class JenkinsJobServiceImpl extends BaseServiceImpl new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); + ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId) + .orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); - // 3. 查询该外部系统下的所有视图 - List views = jenkinsViewRepository.findByExternalSystemId(externalSystemId); - if (views.isEmpty()) { - log.info("No views found for external system: {}", externalSystemId); - // 更新同步历史为成功 - syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS); - jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory); - return 0; + // 3. 确定要同步的视图列表 + List views; + if (viewId != null) { + // 同步指定视图 + JenkinsView view = jenkinsViewRepository.findById(viewId) + .orElseThrow(() -> new BusinessException(ResponseCode.DATA_NOT_FOUND)); + views = List.of(view); + } else { + // 同步所有视图 + views = jenkinsViewRepository.findByExternalSystemId(externalSystemId); } - // 4. 遍历所有视图,同步每个视图下的任务 + if (views.isEmpty()) { + log.info("No views found for external system: {}", externalSystemId); + syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS); + jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory); + return; + } + + // 4. 遍历视图,同步每个视图下的任务 int totalSyncedJobs = 0; StringBuilder errorMessages = new StringBuilder(); for (JenkinsView view : views) { @@ -117,10 +154,8 @@ public class JenkinsJobServiceImpl extends BaseServiceImpl page(JenkinsJobQuery query) { + org.springframework.data.domain.Page page = super.page(query); + // 填充每个任务的构建数量 + page.getContent().forEach(dto -> { + Long buildCount = jenkinsBuildRepository.countByJobIdAndDeletedFalse(dto.getId()); + dto.setBuildCount(buildCount); + }); + return page; + } + + /** + * 重写列表方法,增加关联构建数统计 + */ + @Override + public List findAll(JenkinsJobQuery query) { + List list = super.findAll(query); + // 填充每个任务的构建数量 + list.forEach(dto -> { + Long buildCount = jenkinsBuildRepository.countByJobIdAndDeletedFalse(dto.getId()); + dto.setBuildCount(buildCount); + }); + return list; + } } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsManagerServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsManagerServiceImpl.java deleted file mode 100644 index b2a5d505..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsManagerServiceImpl.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.qqchen.deploy.backend.deploy.service.impl; - -import com.qqchen.deploy.backend.deploy.dto.JenkinsInstanceDTO; -import com.qqchen.deploy.backend.deploy.dto.JenkinsJobDTO; -import com.qqchen.deploy.backend.deploy.dto.JenkinsViewDTO; -import com.qqchen.deploy.backend.deploy.entity.JenkinsJob; -import com.qqchen.deploy.backend.deploy.entity.JenkinsView; -import com.qqchen.deploy.backend.deploy.service.IJenkinsManagerService; -import com.qqchen.deploy.backend.deploy.service.IJenkinsViewService; -import com.qqchen.deploy.backend.deploy.service.IJenkinsJobService; -import com.qqchen.deploy.backend.deploy.service.IJenkinsBuildService; -import com.qqchen.deploy.backend.deploy.service.IJenkinsSyncHistoryService; -import com.qqchen.deploy.backend.deploy.entity.JenkinsSyncHistory; -import com.qqchen.deploy.backend.deploy.enums.ExternalSystemSyncStatus; -import com.qqchen.deploy.backend.deploy.enums.JenkinsSyncType; -import com.qqchen.deploy.backend.deploy.repository.IJenkinsSyncHistoryRepository; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.util.List; - -/** - * Jenkins管理服务实现 - */ -@Slf4j -@Service -public class JenkinsManagerServiceImpl implements IJenkinsManagerService { - - @Resource - private IJenkinsViewService jenkinsViewService; - - @Resource - private IJenkinsJobService jenkinsJobService; - - @Resource - private IJenkinsBuildService jenkinsBuildService; - - @Resource - private IJenkinsSyncHistoryRepository jenkinsSyncHistoryRepository; - - @Override - @Transactional(rollbackFor = Exception.class) - public void syncAll(Long externalSystemId) { - // 同步视图 - syncViews(externalSystemId); - // 同步任务 - syncJobs(externalSystemId); - // 同步构建信息 - syncBuilds(externalSystemId); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void syncViews(Long externalSystemId) { - // 同步视图 - Integer viewCount = jenkinsViewService.syncViews(externalSystemId); - log.info("Successfully synchronized {} views", viewCount); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void syncJobs(Long externalSystemId) { - // 同步任务 - Integer jobCount = jenkinsJobService.syncJobs(externalSystemId); - log.info("Successfully synchronized {} jobs", jobCount); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void syncBuilds(Long externalSystemId) { - // 同步构建信息 - Integer buildCount = jenkinsBuildService.syncAllBuilds(externalSystemId); - log.info("Successfully synchronized {} builds", buildCount); - } - - @Override - public JenkinsInstanceDTO instance(Long externalSystemId) { - // 1. 创建返回对象 - JenkinsInstanceDTO instanceDTO = new JenkinsInstanceDTO(); - - // 2. 获取视图列表 - List views = jenkinsViewService.findByExternalSystemId(externalSystemId); - instanceDTO.setJenkinsViewList(views); - instanceDTO.setTotalViews(views.size()); - - // 3. 获取任务列表 - List jobs = jenkinsJobService.findByExternalSystemId(externalSystemId); - instanceDTO.setJenkinsJobList(jobs); - instanceDTO.setTotalJobs(jobs.size()); - - // 4. 获取构建总数 - Long totalBuilds = jenkinsBuildService.countByExternalSystemId(externalSystemId); - instanceDTO.setTotalBuilds(totalBuilds.intValue()); - - // 5. 获取最后同步时间 - JenkinsSyncHistory lastViewSync = jenkinsSyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( - externalSystemId, JenkinsSyncType.VIEW, ExternalSystemSyncStatus.SUCCESS); - if (lastViewSync != null) { - instanceDTO.setLastSyncViewsTime(lastViewSync.getEndTime()); - } - - JenkinsSyncHistory lastJobSync = jenkinsSyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( - externalSystemId, JenkinsSyncType.JOB, ExternalSystemSyncStatus.SUCCESS); - if (lastJobSync != null) { - instanceDTO.setLastSyncJobsTime(lastJobSync.getEndTime()); - } - - JenkinsSyncHistory lastBuildSync = jenkinsSyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc( - externalSystemId, JenkinsSyncType.BUILD, ExternalSystemSyncStatus.SUCCESS); - if (lastBuildSync != null) { - instanceDTO.setLastSyncBuildsTime(lastBuildSync.getEndTime()); - } - - return instanceDTO; - } -} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsViewServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsViewServiceImpl.java index 239f6d79..3b77d499 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsViewServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/JenkinsViewServiceImpl.java @@ -20,6 +20,7 @@ import com.qqchen.deploy.backend.framework.exception.BusinessException; import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,6 +45,9 @@ public class JenkinsViewServiceImpl extends BaseServiceImpl page(JenkinsViewQuery query) { + org.springframework.data.domain.Page page = super.page(query); + // 填充每个视图的任务数量 + page.getContent().forEach(dto -> { + Long jobCount = jenkinsJobRepository.countByViewIdAndDeletedFalse(dto.getId()); + dto.setJobCount(jobCount); + }); + return page; + } + + /** + * 重写列表方法,增加关联任务数统计 + */ + @Override + public List findAll(JenkinsViewQuery query) { + List list = super.findAll(query); + // 填充每个视图的任务数量 + list.forEach(dto -> { + Long jobCount = jenkinsJobRepository.countByViewIdAndDeletedFalse(dto.getId()); + dto.setJobCount(jobCount); + }); + return list; + } } \ No newline at end of file