团队app配置增加绑定工作流
This commit is contained in:
parent
287e820af8
commit
62dec088fd
@ -0,0 +1,40 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.api;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.deploy.dto.UserDeployableDTO;
|
||||||
|
import com.qqchen.deploy.backend.deploy.service.IDeployService;
|
||||||
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部署管理API控制器
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/deploy")
|
||||||
|
@Tag(name = "部署管理", description = "部署相关接口")
|
||||||
|
public class DeployApiController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IDeployService deployService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前用户可部署的环境和应用
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取可部署的环境", description = "获取当前登录用户在各团队中可部署的环境和应用列表")
|
||||||
|
@GetMapping("/environments")
|
||||||
|
@PreAuthorize("isAuthenticated()")
|
||||||
|
public Response<UserDeployableDTO> getDeployableEnvironments() {
|
||||||
|
return Response.success(deployService.getDeployableEnvironments());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -11,6 +11,9 @@ import jakarta.annotation.Resource;
|
|||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@ -30,23 +33,23 @@ public class TeamMemberApiController extends BaseController<TeamMember, TeamMemb
|
|||||||
private ITeamMemberService teamMemberService;
|
private ITeamMemberService teamMemberService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<TeamMemberDTO> create(TeamMemberDTO dto) {
|
public Response<TeamMemberDTO> create(@Validated @RequestBody TeamMemberDTO dto) {
|
||||||
return super.create(dto);
|
return super.create(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<TeamMemberDTO> update(Long aLong, TeamMemberDTO dto) {
|
public Response<TeamMemberDTO> update(@PathVariable Long id, @Validated @RequestBody TeamMemberDTO dto) {
|
||||||
return super.update(aLong, dto);
|
return super.update(id, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<Void> delete(Long aLong) {
|
public Response<Void> delete(@PathVariable Long id) {
|
||||||
return super.delete(aLong);
|
return super.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<TeamMemberDTO> findById(Long aLong) {
|
public Response<TeamMemberDTO> findById(@PathVariable Long id) {
|
||||||
return super.findById(aLong);
|
return super.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批人DTO
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "审批人信息")
|
||||||
|
public class ApproverDTO {
|
||||||
|
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "真实姓名")
|
||||||
|
private String realName;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可部署应用DTO
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "可部署应用信息")
|
||||||
|
public class DeployableApplicationDTO {
|
||||||
|
|
||||||
|
@Schema(description = "团队应用关联ID")
|
||||||
|
private Long teamApplicationId;
|
||||||
|
|
||||||
|
@Schema(description = "应用ID")
|
||||||
|
private Long applicationId;
|
||||||
|
|
||||||
|
@Schema(description = "应用编码")
|
||||||
|
private String applicationCode;
|
||||||
|
|
||||||
|
@Schema(description = "应用名称")
|
||||||
|
private String applicationName;
|
||||||
|
|
||||||
|
@Schema(description = "应用描述")
|
||||||
|
private String applicationDesc;
|
||||||
|
|
||||||
|
@Schema(description = "分支名称")
|
||||||
|
private String branch;
|
||||||
|
|
||||||
|
@Schema(description = "部署系统ID(Jenkins系统)")
|
||||||
|
private Long deploySystemId;
|
||||||
|
|
||||||
|
@Schema(description = "部署系统名称")
|
||||||
|
private String deploySystemName;
|
||||||
|
|
||||||
|
@Schema(description = "部署任务ID(Jenkins Job)")
|
||||||
|
private String deployJob;
|
||||||
|
|
||||||
|
@Schema(description = "工作流定义ID")
|
||||||
|
private Long workflowDefinitionId;
|
||||||
|
|
||||||
|
@Schema(description = "工作流定义名称")
|
||||||
|
private String workflowDefinitionName;
|
||||||
|
|
||||||
|
@Schema(description = "工作流流程标识(processKey)")
|
||||||
|
private String workflowDefinitionKey;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可部署环境DTO
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "可部署环境信息")
|
||||||
|
public class DeployableEnvironmentDTO {
|
||||||
|
|
||||||
|
@Schema(description = "环境ID")
|
||||||
|
private Long environmentId;
|
||||||
|
|
||||||
|
@Schema(description = "环境编码")
|
||||||
|
private String environmentCode;
|
||||||
|
|
||||||
|
@Schema(description = "环境名称")
|
||||||
|
private String environmentName;
|
||||||
|
|
||||||
|
@Schema(description = "环境描述")
|
||||||
|
private String environmentDesc;
|
||||||
|
|
||||||
|
@Schema(description = "是否启用")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "排序号")
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "是否需要审批")
|
||||||
|
private Boolean requiresApproval;
|
||||||
|
|
||||||
|
@Schema(description = "审批人列表")
|
||||||
|
private List<ApproverDTO> approvers;
|
||||||
|
|
||||||
|
@Schema(description = "可部署应用列表")
|
||||||
|
private List<DeployableApplicationDTO> applications;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队可部署环境DTO
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "团队可部署环境信息")
|
||||||
|
public class TeamDeployableDTO {
|
||||||
|
|
||||||
|
@Schema(description = "团队ID")
|
||||||
|
private Long teamId;
|
||||||
|
|
||||||
|
@Schema(description = "团队编码")
|
||||||
|
private String teamCode;
|
||||||
|
|
||||||
|
@Schema(description = "团队名称")
|
||||||
|
private String teamName;
|
||||||
|
|
||||||
|
@Schema(description = "用户在团队中的角色")
|
||||||
|
private String teamRole;
|
||||||
|
|
||||||
|
@Schema(description = "团队描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "可部署环境列表")
|
||||||
|
private List<DeployableEnvironmentDTO> environments;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户可部署环境DTO
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "用户可部署环境信息")
|
||||||
|
public class UserDeployableDTO {
|
||||||
|
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "真实姓名")
|
||||||
|
private String realName;
|
||||||
|
|
||||||
|
@Schema(description = "用户所属团队列表")
|
||||||
|
private List<TeamDeployableDTO> teams;
|
||||||
|
}
|
||||||
|
|
||||||
@ -81,5 +81,13 @@ public interface ITeamApplicationRepository extends IBaseRepository<TeamApplicat
|
|||||||
"WHERE ta.applicationId IN :applicationIds " +
|
"WHERE ta.applicationId IN :applicationIds " +
|
||||||
"GROUP BY ta.applicationId")
|
"GROUP BY ta.applicationId")
|
||||||
List<Object[]> countDistinctTeamIdByApplicationIds(@Param("applicationIds") Collection<Long> applicationIds);
|
List<Object[]> countDistinctTeamIdByApplicationIds(@Param("applicationIds") Collection<Long> applicationIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量根据团队ID查询应用配置
|
||||||
|
*
|
||||||
|
* @param teamIds 团队ID集合
|
||||||
|
* @return 团队应用配置列表
|
||||||
|
*/
|
||||||
|
List<TeamApplication> findByTeamIdIn(Collection<Long> teamIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import com.qqchen.deploy.backend.deploy.entity.TeamConfig;
|
|||||||
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,5 +32,13 @@ public interface ITeamConfigRepository extends IBaseRepository<TeamConfig, Long>
|
|||||||
* @return 是否存在
|
* @return 是否存在
|
||||||
*/
|
*/
|
||||||
boolean existsByTeamIdAndDeletedFalse(Long teamId);
|
boolean existsByTeamIdAndDeletedFalse(Long teamId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量根据团队ID查询配置
|
||||||
|
*
|
||||||
|
* @param teamIds 团队ID集合
|
||||||
|
* @return 团队配置列表
|
||||||
|
*/
|
||||||
|
List<TeamConfig> findByTeamIdIn(Collection<Long> teamIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import com.qqchen.deploy.backend.deploy.entity.TeamMember;
|
|||||||
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@ -23,5 +24,10 @@ public interface ITeamMemberRepository extends IBaseRepository<TeamMember, Long>
|
|||||||
* 根据团队ID和用户ID查询
|
* 根据团队ID和用户ID查询
|
||||||
*/
|
*/
|
||||||
Optional<TeamMember> findByTeamIdAndUserIdAndDeletedFalse(Long teamId, Long userId);
|
Optional<TeamMember> findByTeamIdAndUserIdAndDeletedFalse(Long teamId, Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID查询所有团队成员记录
|
||||||
|
*/
|
||||||
|
List<TeamMember> findByUserIdAndDeletedFalse(Long userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.service;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.deploy.dto.UserDeployableDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部署服务接口
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
public interface IDeployService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前用户可部署的环境和应用
|
||||||
|
*
|
||||||
|
* @return 用户可部署环境信息
|
||||||
|
*/
|
||||||
|
UserDeployableDTO getDeployableEnvironments();
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,392 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.service.impl;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.deploy.dto.*;
|
||||||
|
import com.qqchen.deploy.backend.deploy.entity.*;
|
||||||
|
import com.qqchen.deploy.backend.deploy.repository.*;
|
||||||
|
import com.qqchen.deploy.backend.deploy.service.IDeployService;
|
||||||
|
import com.qqchen.deploy.backend.framework.security.SecurityUtils;
|
||||||
|
import com.qqchen.deploy.backend.system.entity.User;
|
||||||
|
import com.qqchen.deploy.backend.system.repository.IUserRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部署服务实现
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class DeployServiceImpl implements IDeployService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IUserRepository userRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ITeamMemberRepository teamMemberRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ITeamRepository teamRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ITeamConfigRepository teamConfigRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IEnvironmentRepository environmentRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ITeamApplicationRepository teamApplicationRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IApplicationRepository applicationRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IExternalSystemRepository externalSystemRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IWorkflowDefinitionRepository workflowDefinitionRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public UserDeployableDTO getDeployableEnvironments() {
|
||||||
|
// 1. 获取当前登录用户
|
||||||
|
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
User user = userRepository.findById(currentUserId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("用户不存在"));
|
||||||
|
|
||||||
|
// 2. 查询用户所属的团队
|
||||||
|
List<TeamMember> teamMembers = teamMemberRepository.findByUserIdAndDeletedFalse(currentUserId);
|
||||||
|
if (teamMembers.isEmpty()) {
|
||||||
|
log.info("用户 {} 未加入任何团队", user.getUsername());
|
||||||
|
return buildEmptyResult(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> teamIds = teamMembers.stream()
|
||||||
|
.map(TeamMember::getTeamId)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
// 3. 批量查询团队信息
|
||||||
|
Map<Long, Team> teamMap = teamRepository.findAllById(teamIds)
|
||||||
|
.stream().collect(toMap(Team::getId, t -> t));
|
||||||
|
|
||||||
|
// 4. 批量查询团队配置
|
||||||
|
Map<Long, TeamConfig> configMap = teamConfigRepository.findByTeamIdIn(teamIds)
|
||||||
|
.stream().collect(toMap(TeamConfig::getTeamId, c -> c));
|
||||||
|
|
||||||
|
// 5. 收集所有环境ID
|
||||||
|
Set<Long> allEnvIds = configMap.values().stream()
|
||||||
|
.filter(c -> c.getAllowedEnvironmentIds() != null)
|
||||||
|
.flatMap(c -> c.getAllowedEnvironmentIds().stream())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (allEnvIds.isEmpty()) {
|
||||||
|
log.info("用户 {} 所属团队未配置任何环境", user.getUsername());
|
||||||
|
return buildEmptyResult(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 批量查询环境信息
|
||||||
|
Map<Long, Environment> envMap = environmentRepository.findAllById(allEnvIds)
|
||||||
|
.stream().collect(toMap(Environment::getId, e -> e));
|
||||||
|
|
||||||
|
// 7. 批量查询所有团队的应用配置
|
||||||
|
List<TeamApplication> allTeamApps = teamApplicationRepository.findByTeamIdIn(teamIds);
|
||||||
|
Map<Long, List<TeamApplication>> teamAppsMap = allTeamApps.stream()
|
||||||
|
.collect(groupingBy(TeamApplication::getTeamId));
|
||||||
|
|
||||||
|
// 8. 批量查询应用信息
|
||||||
|
Set<Long> appIds = allTeamApps.stream()
|
||||||
|
.map(TeamApplication::getApplicationId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
final Map<Long, Application> appMap;
|
||||||
|
if (!appIds.isEmpty()) {
|
||||||
|
appMap = applicationRepository.findAllById(appIds)
|
||||||
|
.stream().collect(toMap(Application::getId, a -> a));
|
||||||
|
} else {
|
||||||
|
appMap = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. 批量查询部署系统
|
||||||
|
Set<Long> systemIds = allTeamApps.stream()
|
||||||
|
.map(TeamApplication::getDeploySystemId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
final Map<Long, ExternalSystem> systemMap;
|
||||||
|
if (!systemIds.isEmpty()) {
|
||||||
|
systemMap = externalSystemRepository.findAllById(systemIds)
|
||||||
|
.stream().collect(toMap(ExternalSystem::getId, s -> s));
|
||||||
|
} else {
|
||||||
|
systemMap = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. 批量查询工作流定义
|
||||||
|
Set<Long> workflowIds = allTeamApps.stream()
|
||||||
|
.map(TeamApplication::getWorkflowDefinitionId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
final Map<Long, WorkflowDefinition> workflowMap;
|
||||||
|
if (!workflowIds.isEmpty()) {
|
||||||
|
workflowMap = workflowDefinitionRepository.findAllById(workflowIds)
|
||||||
|
.stream().collect(toMap(WorkflowDefinition::getId, w -> w));
|
||||||
|
} else {
|
||||||
|
workflowMap = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. 批量查询审批人信息
|
||||||
|
Set<Long> approverUserIds = configMap.values().stream()
|
||||||
|
.filter(c -> c.getApproverUserIds() != null)
|
||||||
|
.flatMap(c -> c.getApproverUserIds().stream())
|
||||||
|
.filter(obj -> obj instanceof List)
|
||||||
|
.flatMap(obj -> ((List<?>) obj).stream())
|
||||||
|
.filter(id -> id instanceof Number)
|
||||||
|
.map(id -> ((Number) id).longValue())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
final Map<Long, User> approverMap;
|
||||||
|
if (!approverUserIds.isEmpty()) {
|
||||||
|
approverMap = userRepository.findAllById(approverUserIds)
|
||||||
|
.stream().collect(toMap(User::getId, u -> u));
|
||||||
|
} else {
|
||||||
|
approverMap = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12. 组装团队数据
|
||||||
|
Map<Long, TeamMember> teamMemberMap = teamMembers.stream()
|
||||||
|
.collect(toMap(TeamMember::getTeamId, tm -> tm));
|
||||||
|
|
||||||
|
List<TeamDeployableDTO> teamDTOs = teamIds.stream()
|
||||||
|
.map(teamId -> buildTeamDTO(
|
||||||
|
teamId,
|
||||||
|
teamMap,
|
||||||
|
teamMemberMap,
|
||||||
|
configMap,
|
||||||
|
envMap,
|
||||||
|
teamAppsMap,
|
||||||
|
appMap,
|
||||||
|
systemMap,
|
||||||
|
workflowMap,
|
||||||
|
approverMap
|
||||||
|
))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
// 13. 组装最终结果
|
||||||
|
UserDeployableDTO result = new UserDeployableDTO();
|
||||||
|
result.setUserId(user.getId());
|
||||||
|
result.setUsername(user.getUsername());
|
||||||
|
result.setRealName(user.getNickname());
|
||||||
|
result.setTeams(teamDTOs);
|
||||||
|
|
||||||
|
log.info("用户 {} 可部署环境数据查询完成,包含 {} 个团队", user.getUsername(), teamDTOs.size());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建空结果
|
||||||
|
*/
|
||||||
|
private UserDeployableDTO buildEmptyResult(User user) {
|
||||||
|
UserDeployableDTO result = new UserDeployableDTO();
|
||||||
|
result.setUserId(user.getId());
|
||||||
|
result.setUsername(user.getUsername());
|
||||||
|
result.setRealName(user.getNickname());
|
||||||
|
result.setTeams(Collections.emptyList());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建团队DTO
|
||||||
|
*/
|
||||||
|
private TeamDeployableDTO buildTeamDTO(
|
||||||
|
Long teamId,
|
||||||
|
Map<Long, Team> teamMap,
|
||||||
|
Map<Long, TeamMember> teamMemberMap,
|
||||||
|
Map<Long, TeamConfig> configMap,
|
||||||
|
Map<Long, Environment> envMap,
|
||||||
|
Map<Long, List<TeamApplication>> teamAppsMap,
|
||||||
|
Map<Long, Application> appMap,
|
||||||
|
Map<Long, ExternalSystem> systemMap,
|
||||||
|
Map<Long, WorkflowDefinition> workflowMap,
|
||||||
|
Map<Long, User> approverMap
|
||||||
|
) {
|
||||||
|
Team team = teamMap.get(teamId);
|
||||||
|
if (team == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamMember member = teamMemberMap.get(teamId);
|
||||||
|
TeamConfig config = configMap.get(teamId);
|
||||||
|
|
||||||
|
TeamDeployableDTO teamDTO = new TeamDeployableDTO();
|
||||||
|
teamDTO.setTeamId(team.getId());
|
||||||
|
teamDTO.setTeamCode(team.getTeamCode());
|
||||||
|
teamDTO.setTeamName(team.getTeamName());
|
||||||
|
teamDTO.setDescription(team.getDescription());
|
||||||
|
teamDTO.setTeamRole(member != null ? member.getRoleInTeam() : null);
|
||||||
|
|
||||||
|
// 组装环境数据
|
||||||
|
if (config != null && config.getAllowedEnvironmentIds() != null && !config.getAllowedEnvironmentIds().isEmpty()) {
|
||||||
|
List<Long> allowedEnvIds = config.getAllowedEnvironmentIds();
|
||||||
|
List<TeamApplication> teamApps = teamAppsMap.getOrDefault(teamId, Collections.emptyList());
|
||||||
|
|
||||||
|
// 按环境分组应用
|
||||||
|
Map<Long, List<TeamApplication>> appsByEnv = teamApps.stream()
|
||||||
|
.collect(groupingBy(TeamApplication::getEnvironmentId));
|
||||||
|
|
||||||
|
List<DeployableEnvironmentDTO> envDTOs = new ArrayList<>();
|
||||||
|
for (int i = 0; i < allowedEnvIds.size(); i++) {
|
||||||
|
Long envId = allowedEnvIds.get(i);
|
||||||
|
Environment env = envMap.get(envId);
|
||||||
|
if (env == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeployableEnvironmentDTO envDTO = buildEnvironmentDTO(
|
||||||
|
env,
|
||||||
|
config,
|
||||||
|
i,
|
||||||
|
appsByEnv.getOrDefault(envId, Collections.emptyList()),
|
||||||
|
appMap,
|
||||||
|
systemMap,
|
||||||
|
workflowMap,
|
||||||
|
approverMap
|
||||||
|
);
|
||||||
|
|
||||||
|
envDTOs.add(envDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
envDTOs.sort(Comparator.comparing(DeployableEnvironmentDTO::getSort));
|
||||||
|
teamDTO.setEnvironments(envDTOs);
|
||||||
|
} else {
|
||||||
|
teamDTO.setEnvironments(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return teamDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建环境DTO
|
||||||
|
*/
|
||||||
|
private DeployableEnvironmentDTO buildEnvironmentDTO(
|
||||||
|
Environment env,
|
||||||
|
TeamConfig config,
|
||||||
|
int envIndex,
|
||||||
|
List<TeamApplication> teamApps,
|
||||||
|
Map<Long, Application> appMap,
|
||||||
|
Map<Long, ExternalSystem> systemMap,
|
||||||
|
Map<Long, WorkflowDefinition> workflowMap,
|
||||||
|
Map<Long, User> approverMap
|
||||||
|
) {
|
||||||
|
DeployableEnvironmentDTO envDTO = new DeployableEnvironmentDTO();
|
||||||
|
envDTO.setEnvironmentId(env.getId());
|
||||||
|
envDTO.setEnvironmentCode(env.getEnvCode());
|
||||||
|
envDTO.setEnvironmentName(env.getEnvName());
|
||||||
|
envDTO.setEnvironmentDesc(env.getEnvDesc());
|
||||||
|
envDTO.setEnabled(env.getEnabled());
|
||||||
|
envDTO.setSort(env.getSort());
|
||||||
|
|
||||||
|
// 审批配置
|
||||||
|
if (config.getEnvironmentApprovalRequired() != null && envIndex < config.getEnvironmentApprovalRequired().size()) {
|
||||||
|
envDTO.setRequiresApproval(config.getEnvironmentApprovalRequired().get(envIndex));
|
||||||
|
} else {
|
||||||
|
envDTO.setRequiresApproval(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审批人
|
||||||
|
if (config.getApproverUserIds() != null && envIndex < config.getApproverUserIds().size()) {
|
||||||
|
Object approverObj = config.getApproverUserIds().get(envIndex);
|
||||||
|
if (approverObj instanceof List) {
|
||||||
|
List<?> approverList = (List<?>) approverObj;
|
||||||
|
List<ApproverDTO> approverDTOs = approverList.stream()
|
||||||
|
.filter(id -> id instanceof Number)
|
||||||
|
.map(id -> buildApproverDTO(((Number) id).longValue(), approverMap))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(toList());
|
||||||
|
envDTO.setApprovers(approverDTOs);
|
||||||
|
} else {
|
||||||
|
envDTO.setApprovers(Collections.emptyList());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
envDTO.setApprovers(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用列表
|
||||||
|
List<DeployableApplicationDTO> appDTOs = teamApps.stream()
|
||||||
|
.map(ta -> buildApplicationDTO(ta, appMap, systemMap, workflowMap))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
envDTO.setApplications(appDTOs);
|
||||||
|
|
||||||
|
return envDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建审批人DTO
|
||||||
|
*/
|
||||||
|
private ApproverDTO buildApproverDTO(Long userId, Map<Long, User> approverMap) {
|
||||||
|
User user = approverMap.get(userId);
|
||||||
|
if (user == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApproverDTO dto = new ApproverDTO();
|
||||||
|
dto.setUserId(user.getId());
|
||||||
|
dto.setUsername(user.getUsername());
|
||||||
|
dto.setRealName(user.getNickname());
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建应用DTO
|
||||||
|
*/
|
||||||
|
private DeployableApplicationDTO buildApplicationDTO(
|
||||||
|
TeamApplication ta,
|
||||||
|
Map<Long, Application> appMap,
|
||||||
|
Map<Long, ExternalSystem> systemMap,
|
||||||
|
Map<Long, WorkflowDefinition> workflowMap
|
||||||
|
) {
|
||||||
|
Application app = appMap.get(ta.getApplicationId());
|
||||||
|
if (app == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeployableApplicationDTO dto = new DeployableApplicationDTO();
|
||||||
|
dto.setTeamApplicationId(ta.getId());
|
||||||
|
dto.setApplicationId(app.getId());
|
||||||
|
dto.setApplicationCode(app.getAppCode());
|
||||||
|
dto.setApplicationName(app.getAppName());
|
||||||
|
dto.setApplicationDesc(app.getAppDesc());
|
||||||
|
dto.setBranch(ta.getBranch());
|
||||||
|
|
||||||
|
// 部署系统
|
||||||
|
dto.setDeploySystemId(ta.getDeploySystemId());
|
||||||
|
if (ta.getDeploySystemId() != null) {
|
||||||
|
ExternalSystem system = systemMap.get(ta.getDeploySystemId());
|
||||||
|
dto.setDeploySystemName(system != null ? system.getName() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 部署任务
|
||||||
|
dto.setDeployJob(ta.getDeployJob());
|
||||||
|
|
||||||
|
// 工作流定义
|
||||||
|
dto.setWorkflowDefinitionId(ta.getWorkflowDefinitionId());
|
||||||
|
if (ta.getWorkflowDefinitionId() != null) {
|
||||||
|
WorkflowDefinition workflow = workflowMap.get(ta.getWorkflowDefinitionId());
|
||||||
|
if (workflow != null) {
|
||||||
|
dto.setWorkflowDefinitionName(workflow.getName());
|
||||||
|
dto.setWorkflowDefinitionKey(workflow.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user