diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployApprovalTaskDTO.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployApprovalTaskDTO.java index 610d24cb..78a24021 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployApprovalTaskDTO.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployApprovalTaskDTO.java @@ -8,7 +8,7 @@ import java.time.LocalDateTime; /** * 部署审批任务DTO * - *
扩展了审批任务的基本信息,增加部署相关的业务上下文 + *
结构化的审批任务信息,包含审批任务、部署记录、关联实体等信息 *
用于部署审批列表,让审批人员快速了解审批内容
*
* @author qqchen
@@ -18,92 +18,171 @@ import java.time.LocalDateTime;
@Schema(description = "部署审批任务信息")
public class DeployApprovalTaskDTO {
- // ============ 审批任务基本信息 ============
+ // ========== 审批任务信息 ==========
+ @Schema(description = "审批任务信息")
+ private ApprovalTaskInfo approvalTask;
- @Schema(description = "任务ID")
- private String taskId;
+ // ========== 部署记录信息 ==========
+ @Schema(description = "部署记录信息")
+ private DeployRecordInfo deployRecord;
- @Schema(description = "任务名称")
- private String taskName;
+ // ========== 关联实体信息 ==========
+ @Schema(description = "团队信息")
+ private TeamInfo team;
- @Schema(description = "任务描述")
- private String taskDescription;
+ @Schema(description = "应用信息")
+ private ApplicationInfo application;
- @Schema(description = "流程实例ID")
- private String processInstanceId;
+ @Schema(description = "环境信息")
+ private EnvironmentInfo environment;
- @Schema(description = "流程定义ID")
- private String processDefinitionId;
+ @Schema(description = "发起人信息")
+ private UserSimpleInfo deployUser;
- @Schema(description = "审批人")
- private String assignee;
+ // ========== 嵌套类定义 ==========
- @Schema(description = "创建时间")
- private LocalDateTime createTime;
+ /**
+ * 审批任务信息
+ */
+ @Data
+ @Schema(description = "审批任务信息")
+ public static class ApprovalTaskInfo {
+
+ @Schema(description = "任务ID")
+ private String taskId;
- @Schema(description = "到期时间")
- private LocalDateTime dueDate;
+ @Schema(description = "任务名称")
+ private String taskName;
- @Schema(description = "审批标题")
- private String approvalTitle;
+ @Schema(description = "任务描述")
+ private String taskDescription;
- @Schema(description = "审批内容")
- private String approvalContent;
+ @Schema(description = "流程实例ID")
+ private String processInstanceId;
- @Schema(description = "审批模式: SINGLE-单人审批, MULTI-多人会签, OR-多人或签")
- private String approvalMode;
+ @Schema(description = "流程定义ID")
+ private String processDefinitionId;
- @Schema(description = "是否允许转交")
- private Boolean allowDelegate;
+ @Schema(description = "审批人用户名")
+ private String assignee;
- @Schema(description = "是否允许加签")
- private Boolean allowAddSign;
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
- @Schema(description = "是否必须填写意见")
- private Boolean requireComment;
+ @Schema(description = "到期时间")
+ private LocalDateTime dueDate;
- // ============ 部署业务上下文信息 ============
+ @Schema(description = "待审批时长(毫秒)- 从任务创建到现在的时长")
+ private Long pendingDuration;
- @Schema(description = "部署记录ID")
- private Long deployRecordId;
+ @Schema(description = "审批标题")
+ private String approvalTitle;
- @Schema(description = "业务标识(UUID)")
- private String businessKey;
+ @Schema(description = "审批内容")
+ private String approvalContent;
- @Schema(description = "团队ID")
- private Long teamId;
+ @Schema(description = "审批模式: SINGLE-单人审批, MULTI-多人会签, OR-多人或签")
+ private String approvalMode;
- @Schema(description = "团队名称")
- private String teamName;
+ @Schema(description = "是否允许转交")
+ private Boolean allowDelegate;
- @Schema(description = "应用ID")
- private Long applicationId;
+ @Schema(description = "是否允许加签")
+ private Boolean allowAddSign;
- @Schema(description = "应用编码")
- private String applicationCode;
+ @Schema(description = "是否必须填写意见")
+ private Boolean requireComment;
+ }
- @Schema(description = "应用名称")
- private String applicationName;
+ /**
+ * 部署记录信息
+ */
+ @Data
+ @Schema(description = "部署记录信息")
+ public static class DeployRecordInfo {
+
+ @Schema(description = "部署记录ID")
+ private Long id;
- @Schema(description = "环境ID")
- private Long environmentId;
+ @Schema(description = "业务标识(UUID)")
+ private String businessKey;
- @Schema(description = "环境编码")
- private String environmentCode;
+ @Schema(description = "部署备注")
+ private String remark;
- @Schema(description = "环境名称")
- private String environmentName;
+ @Schema(description = "部署开始时间")
+ private LocalDateTime startTime;
+ }
- @Schema(description = "发起人")
- private String deployBy;
+ /**
+ * 团队信息
+ */
+ @Data
+ @Schema(description = "团队信息")
+ public static class TeamInfo {
+
+ @Schema(description = "团队ID")
+ private Long id;
- @Schema(description = "部署备注")
- private String deployRemark;
+ @Schema(description = "团队名称")
+ private String name;
+ }
- @Schema(description = "部署开始时间")
- private LocalDateTime deployStartTime;
+ /**
+ * 应用信息
+ */
+ @Data
+ @Schema(description = "应用信息")
+ public static class ApplicationInfo {
+
+ @Schema(description = "应用ID")
+ private Long id;
- @Schema(description = "待审批时长(毫秒)- 从任务创建到现在的时长")
- private Long pendingDuration;
+ @Schema(description = "应用编码")
+ private String code;
+
+ @Schema(description = "应用名称")
+ private String name;
+ }
+
+ /**
+ * 环境信息
+ */
+ @Data
+ @Schema(description = "环境信息")
+ public static class EnvironmentInfo {
+
+ @Schema(description = "环境ID")
+ private Long id;
+
+ @Schema(description = "环境编码")
+ private String code;
+
+ @Schema(description = "环境名称")
+ private String name;
+ }
+
+ /**
+ * 用户简要信息
+ */
+ @Data
+ @Schema(description = "用户简要信息")
+ public static class UserSimpleInfo {
+
+ @Schema(description = "用户名")
+ private String username;
+
+ @Schema(description = "昵称")
+ private String nickname;
+
+ @Schema(description = "邮箱")
+ private String email;
+
+ @Schema(description = "手机号")
+ private String phone;
+
+ @Schema(description = "部门名称")
+ private String departmentName;
+ }
}
diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployExecuteRequest.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployExecuteRequest.java
index f2b9cbe2..5513f4cc 100644
--- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployExecuteRequest.java
+++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/dto/DeployExecuteRequest.java
@@ -72,6 +72,8 @@ public class DeployExecuteRequest {
@Schema(description = "部署备注")
private String deployRemark;
+ private String deployUser;
+
/**
* Jenkins配置
*/
diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/DeployServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/DeployServiceImpl.java
index c67cb1e6..7efc7ea8 100644
--- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/DeployServiceImpl.java
+++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/DeployServiceImpl.java
@@ -755,9 +755,7 @@ public class DeployServiceImpl implements IDeployService {
* 创建部署记录
*/
private void createDeployRecord(DeployExecuteRequest request, WorkflowInstanceDTO workflowInstance, String businessKey) {
- String currentUsername = SecurityUtils.getCurrentUsername();
- deployRecordService.createDeployRecord(workflowInstance.getId(), businessKey, request.getTeamApplicationId(), request.getTeamId(), request.getApplicationId(), request.getEnvironmentId(), currentUsername, request.getDeployRemark());
-
+ deployRecordService.createDeployRecord(workflowInstance.getId(), businessKey, request.getTeamApplicationId(), request.getTeamId(), request.getApplicationId(), request.getEnvironmentId(), request.getDeployUser(), request.getDeployRemark());
log.info("部署记录已创建: businessKey={}, workflowInstanceId={}", businessKey, workflowInstance.getId());
}
@@ -820,20 +818,21 @@ public class DeployServiceImpl implements IDeployService {
}
}
- // 4. 批量查询团队信息(解决 N+1 查询问题)
+ // 4. 批量查询团队信息和用户信息(解决 N+1 查询问题)
enrichTeamInfo(result);
+ enrichDeployUserInfo(result);
// 5. 后置筛选:按团队和环境过滤
if (teamId != null) {
result = result.stream()
- .filter(task -> teamId.equals(task.getTeamId()))
+ .filter(task -> task.getTeam() != null && teamId.equals(task.getTeam().getId()))
.collect(Collectors.toList());
log.debug("按团队ID筛选后剩余 {} 个任务", result.size());
}
if (environmentId != null) {
result = result.stream()
- .filter(task -> environmentId.equals(task.getEnvironmentId()))
+ .filter(task -> task.getEnvironment() != null && environmentId.equals(task.getEnvironment().getId()))
.collect(Collectors.toList());
log.debug("按环境ID筛选后剩余 {} 个任务", result.size());
}
@@ -879,56 +878,79 @@ public class DeployServiceImpl implements IDeployService {
// 5. 构建 DTO
DeployApprovalTaskDTO dto = new DeployApprovalTaskDTO();
- // 5.1 审批任务基本信息
- dto.setTaskId(task.getId());
- dto.setTaskName(task.getName());
- dto.setTaskDescription(task.getDescription());
- dto.setProcessInstanceId(task.getProcessInstanceId());
- dto.setProcessDefinitionId(task.getProcessDefinitionId());
- dto.setAssignee(task.getAssignee());
+ // 5.1 构建审批任务信息
+ DeployApprovalTaskDTO.ApprovalTaskInfo approvalTask = new DeployApprovalTaskDTO.ApprovalTaskInfo();
+ approvalTask.setTaskId(task.getId());
+ approvalTask.setTaskName(task.getName());
+ approvalTask.setTaskDescription(task.getDescription());
+ approvalTask.setProcessInstanceId(task.getProcessInstanceId());
+ approvalTask.setProcessDefinitionId(task.getProcessDefinitionId());
+ approvalTask.setAssignee(task.getAssignee());
if (task.getCreateTime() != null) {
- dto.setCreateTime(LocalDateTime.ofInstant(
+ LocalDateTime createTime = LocalDateTime.ofInstant(
task.getCreateTime().toInstant(),
- ZoneId.systemDefault()));
+ ZoneId.systemDefault());
+ approvalTask.setCreateTime(createTime);
+
+ // 计算待审批时长
+ long pendingMillis = Duration.between(createTime, LocalDateTime.now()).toMillis();
+ approvalTask.setPendingDuration(pendingMillis);
}
if (task.getDueDate() != null) {
- dto.setDueDate(LocalDateTime.ofInstant(
+ approvalTask.setDueDate(LocalDateTime.ofInstant(
task.getDueDate().toInstant(),
ZoneId.systemDefault()));
}
- // 5.2 审批配置信息(从审批节点的 NodeContext 中获取 ApprovalInputMapping)
+ // 5.2 填充审批配置信息(从审批节点的 NodeContext 中获取 ApprovalInputMapping)
String nodeId = task.getTaskDefinitionKey();
ApprovalInputMapping approvalInputs = extractApprovalInputMapping(variables, nodeId);
if (approvalInputs != null) {
- dto.setApprovalTitle(approvalInputs.getApprovalTitle());
- dto.setApprovalContent(approvalInputs.getApprovalContent());
- dto.setApprovalMode(approvalInputs.getApprovalMode() != null
+ approvalTask.setApprovalTitle(approvalInputs.getApprovalTitle());
+ approvalTask.setApprovalContent(approvalInputs.getApprovalContent());
+ approvalTask.setApprovalMode(approvalInputs.getApprovalMode() != null
? approvalInputs.getApprovalMode().name()
: null);
- dto.setAllowDelegate(approvalInputs.getAllowDelegate());
- dto.setAllowAddSign(approvalInputs.getAllowAddSign());
- dto.setRequireComment(approvalInputs.getRequireComment());
+ approvalTask.setAllowDelegate(approvalInputs.getAllowDelegate());
+ approvalTask.setAllowAddSign(approvalInputs.getAllowAddSign());
+ approvalTask.setRequireComment(approvalInputs.getRequireComment());
}
+ dto.setApprovalTask(approvalTask);
- // 5.3 部署业务上下文信息(从 variables 还原 DeployExecuteRequest)
+ // 5.3 构建部署记录信息
+ DeployApprovalTaskDTO.DeployRecordInfo deployRecordInfo = new DeployApprovalTaskDTO.DeployRecordInfo();
+ deployRecordInfo.setId(deployRecord.getId());
+ deployRecordInfo.setBusinessKey(businessKey);
+ deployRecordInfo.setRemark(deployRecord.getDeployRemark());
+ deployRecordInfo.setStartTime(deployRecord.getStartTime());
+ dto.setDeployRecord(deployRecordInfo);
+
+ // 5.4 构建关联实体信息(从 variables 还原 DeployExecuteRequest)
DeployExecuteRequest deployRequest = JsonUtils.fromMap(variables, DeployExecuteRequest.class);
- dto.setDeployRecordId(deployRecord.getId());
- dto.setBusinessKey(businessKey);
- dto.setDeployStartTime(deployRecord.getStartTime());
+
+ // 团队信息
+ DeployApprovalTaskDTO.TeamInfo team = new DeployApprovalTaskDTO.TeamInfo();
+ team.setId(deployRequest.getTeamId());
+ // 团队名称通过批量查询填充(见 enrichTeamInfo 方法)
+ dto.setTeam(team);
+
+ // 应用信息
+ DeployApprovalTaskDTO.ApplicationInfo application = new DeployApprovalTaskDTO.ApplicationInfo();
+ application.setId(deployRequest.getApplicationId());
+ application.setCode(deployRequest.getApplicationCode());
+ application.setName(deployRequest.getApplicationName());
+ dto.setApplication(application);
+
+ // 环境信息
+ DeployApprovalTaskDTO.EnvironmentInfo environment = new DeployApprovalTaskDTO.EnvironmentInfo();
+ environment.setId(deployRequest.getEnvironmentId());
+ environment.setCode(deployRequest.getEnvironmentCode());
+ environment.setName(deployRequest.getEnvironmentName());
+ dto.setEnvironment(environment);
- // 使用 BeanUtils 批量复制同名字段
- BeanUtils.copyProperties(deployRequest, dto);
-
- // 5.4 计算待审批时长(团队名称通过批量查询填充)
- if (dto.getCreateTime() != null) {
- long pendingMillis = Duration.between(dto.getCreateTime(), LocalDateTime.now()).toMillis();
- dto.setPendingDuration(pendingMillis);
- }
-
- // 5.6 自动解析 EL 表达式(如 ${deploy.applicationName})
+ // 5.5 自动解析 EL 表达式(如 ${deploy.applicationName})
SpelExpressionResolver.resolveObject(dto, variables);
return dto;
@@ -1017,6 +1039,11 @@ public class DeployServiceImpl implements IDeployService {
*
* @param dtoList 待填充的 DTO 列表
*/
+ /**
+ * 批量查询并填充团队信息
+ *
+ * @param dtoList 待填充的 DTO 列表
+ */
private void enrichTeamInfo(List 从 NodeContext 的 inputs 字段中解析审批配置
diff --git a/backend/src/main/java/com/qqchen/deploy/backend/system/repository/IUserRepository.java b/backend/src/main/java/com/qqchen/deploy/backend/system/repository/IUserRepository.java
index 28911a95..7ee9c74e 100644
--- a/backend/src/main/java/com/qqchen/deploy/backend/system/repository/IUserRepository.java
+++ b/backend/src/main/java/com/qqchen/deploy/backend/system/repository/IUserRepository.java
@@ -4,6 +4,8 @@ import com.qqchen.deploy.backend.system.entity.User;
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import org.springframework.stereotype.Repository;
+import java.util.Collection;
+import java.util.List;
import java.util.Optional;
@Repository
@@ -14,6 +16,11 @@ public interface IUserRepository extends IBaseRepository