Skip to content

Commit 25168a4

Browse files
committed
feat: Approval record detail
1 parent abe02be commit 25168a4

11 files changed

Lines changed: 354 additions & 45 deletions
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package cn.cordys.crm.approval.domain;
2+
3+
import cn.cordys.common.domain.BaseModel;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import jakarta.persistence.Table;
6+
import lombok.Data;
7+
8+
/**
9+
* 加签任务
10+
*/
11+
@Data
12+
@Table(name = "approval_add_sign_task")
13+
public class ApprovalAddSignTask extends BaseModel {
14+
15+
@Schema(description = "审批实例ID")
16+
private String instanceId;
17+
18+
@Schema(description = "加签任务ID")
19+
private String taskId;
20+
21+
@Schema(description = "审批人")
22+
private String approverId;
23+
24+
@Schema(description = "加签方式")
25+
private String type;
26+
27+
@Schema(description = "加签位置")
28+
private Integer pos;
29+
30+
@Schema(description = "加签意见")
31+
private String comment;
32+
33+
@Schema(description = "状态")
34+
private String status;
35+
}

backend/crm/src/main/java/cn/cordys/crm/approval/domain/ApprovalInstance.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import jakarta.persistence.Table;
66
import lombok.Data;
77

8+
/**
9+
* 审批实例
10+
*/
811
@Data
912
@Table(name = "approval_instance")
1013
public class ApprovalInstance extends BaseModel {
@@ -31,7 +34,7 @@ public class ApprovalInstance extends BaseModel {
3134
private Long submitTime;
3235

3336
@Schema(description = "审批完成时间")
34-
private Long approveTime;
37+
private Long approvalTime;
3538

3639
@Schema(description = "审批结果")
3740
private String result;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package cn.cordys.crm.approval.domain;
2+
3+
import cn.cordys.common.domain.BaseModel;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import lombok.Data;
6+
import jakarta.persistence.Table;
7+
8+
/**
9+
* 审批记录
10+
*/
11+
@Data
12+
@Table(name = "approval_record")
13+
public class ApprovalRecord extends BaseModel {
14+
15+
@Schema(description = "审批实例ID")
16+
private String instanceId;
17+
18+
@Schema(description = "任务ID")
19+
private String taskId;
20+
21+
@Schema(description = "节点ID")
22+
private String nodeId;
23+
24+
@Schema(description = "审批结果")
25+
private String result;
26+
27+
@Schema(description = "审批意见")
28+
private String comment;
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package cn.cordys.crm.approval.domain;
2+
3+
import cn.cordys.common.domain.BaseModel;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import jakarta.persistence.Table;
6+
import lombok.Data;
7+
8+
/**
9+
* 审批退回记录
10+
*/
11+
@Data
12+
@Table(name = "approval_return_back_record")
13+
public class ApprovalReturnBackRecord extends BaseModel {
14+
15+
@Schema(description = "审批实例ID")
16+
private String instanceId;
17+
18+
@Schema(description = "当前任务ID")
19+
private String taskId;
20+
21+
@Schema(description = "退回至任务ID")
22+
private String returnToTaskId;
23+
24+
@Schema(description = "退回原因")
25+
private String returnReason;
26+
27+
@Schema(description = "退回操作人")
28+
private String returnUserId;
29+
}

backend/crm/src/main/java/cn/cordys/crm/approval/domain/ApprovalTask.java

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import jakarta.persistence.Table;
66
import lombok.Data;
77

8+
/**
9+
* 审批任务
10+
*/
811
@Data
912
@Table(name = "approval_task")
1013
public class ApprovalTask extends BaseModel {
@@ -21,33 +24,12 @@ public class ApprovalTask extends BaseModel {
2124
@Schema(description = "任务状态")
2225
private String taskStatus;
2326

24-
@Schema(description = "审批方式")
25-
private String approvalMethod;
26-
27-
@Schema(description = "是否加签")
27+
@Schema(description = "是否为加签任务")
2828
private Boolean isAddSign;
2929

30-
@Schema(description = "加签人")
31-
private String addSignBy;
32-
33-
@Schema(description = "加签时间")
34-
private Long addSignTime;
35-
36-
@Schema(description = "是否退回")
30+
@Schema(description = "是否为退回任务")
3731
private Boolean isReturn;
3832

39-
@Schema(description = "退回至节点")
40-
private String returnToNodeId;
41-
42-
@Schema(description = "退回原因")
43-
private String returnReason;
44-
45-
@Schema(description = "退回人")
46-
private String returnBy;
47-
48-
@Schema(description = "退回时间")
49-
private Long returnTime;
50-
5133
@Schema(description = "是否为抄送任务")
5234
private Boolean isCc;
5335
}

backend/crm/src/main/java/cn/cordys/crm/system/dto/request/ApprovalExecuteParam.java renamed to backend/crm/src/main/java/cn/cordys/crm/approval/dto/ApprovalExecuteParam.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package cn.cordys.crm.system.dto.request;
1+
package cn.cordys.crm.approval.dto;
22

33
import io.swagger.v3.oas.annotations.media.Schema;
44
import lombok.AllArgsConstructor;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package cn.cordys.crm.approval.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.Data;
5+
6+
import java.util.List;
7+
8+
@Data
9+
public class ApprovalInstanceDetail {
10+
11+
@Schema(description = "审批实例ID")
12+
private String id;
13+
14+
@Schema(description = "提交人ID")
15+
private String submitterId;
16+
17+
@Schema(description = "提交人")
18+
private String submitter;
19+
20+
@Schema(description = "提交时间")
21+
private Long submitTime;
22+
23+
@Schema(description = "审批结果")
24+
private String result;
25+
26+
@Schema(description = "审批状态")
27+
private String approvalStatus;
28+
29+
@Schema(description = "审批节点集合")
30+
private List<ApprovalRecordNode> nodes;
31+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package cn.cordys.crm.approval.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.util.List;
10+
11+
@Data
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public class ApprovalRecordNode {
16+
17+
@Schema(description = "审批任务ID")
18+
private String taskId;
19+
20+
@Schema(description = "审批记录ID")
21+
private String recordId;
22+
23+
@Schema(description = "节点ID")
24+
private String nodeId;
25+
26+
@Schema(description = "审批人ID")
27+
private String approverId;
28+
29+
@Schema(description = "审批人名称")
30+
private String approver;
31+
32+
@Schema(description = "审批状态")
33+
private String approvalStatus;
34+
35+
@Schema(description = "提交审批时间")
36+
private Long approvalTime;
37+
38+
@Schema(description = "是否加签节点")
39+
private boolean isAddSignNode;
40+
41+
@Schema(description = "抄送的节点列表")
42+
private List<ApprovalRecordNode> ccNodes;
43+
}

backend/crm/src/main/java/cn/cordys/crm/approval/service/ApprovalExecuteService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import cn.cordys.common.uid.IDGenerator;
55
import cn.cordys.crm.approval.domain.ApprovalInstance;
66
import cn.cordys.crm.approval.domain.ApprovalTask;
7-
import cn.cordys.crm.system.dto.request.ApprovalExecuteParam;
7+
import cn.cordys.crm.approval.dto.ApprovalExecuteParam;
88
import cn.cordys.mybatis.BaseMapper;
99
import jakarta.annotation.Resource;
1010
import org.apache.commons.lang3.StringUtils;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package cn.cordys.crm.approval.service;
2+
3+
import cn.cordys.common.util.BeanUtils;
4+
import cn.cordys.crm.approval.domain.ApprovalAddSignTask;
5+
import cn.cordys.crm.approval.domain.ApprovalInstance;
6+
import cn.cordys.crm.approval.domain.ApprovalRecord;
7+
import cn.cordys.crm.approval.domain.ApprovalTask;
8+
import cn.cordys.crm.approval.dto.ApprovalInstanceDetail;
9+
import cn.cordys.crm.approval.dto.ApprovalRecordNode;
10+
import cn.cordys.mybatis.BaseMapper;
11+
import cn.cordys.mybatis.lambda.LambdaQueryWrapper;
12+
import jakarta.annotation.Resource;
13+
import org.apache.commons.collections4.CollectionUtils;
14+
import org.apache.commons.collections4.ListUtils;
15+
import org.springframework.stereotype.Service;
16+
17+
import java.util.ArrayList;
18+
import java.util.List;
19+
import java.util.Map;
20+
import java.util.stream.Collectors;
21+
22+
@Service
23+
public class ApprovalInstanceService {
24+
25+
@Resource
26+
private BaseMapper<ApprovalInstance> approvalInstanceMapper;
27+
@Resource
28+
private BaseMapper<ApprovalTask> approvalTaskMapper;
29+
@Resource
30+
private BaseMapper<ApprovalAddSignTask> approvalAddSignTaskMapper;
31+
@Resource
32+
private BaseMapper<ApprovalRecord> approvalRecordMapper;
33+
34+
/**
35+
* 获取资源最新审批实例详情
36+
* @param resourceId 资源ID
37+
* @return 审批实例详情
38+
*/
39+
public ApprovalInstanceDetail getLatestApprovalInstanceDetail(String resourceId) {
40+
// 获取最新审批实例
41+
LambdaQueryWrapper<ApprovalInstance> instanceWrapper = new LambdaQueryWrapper<>();
42+
instanceWrapper.eq(ApprovalInstance::getResourceId, resourceId)
43+
.orderByDesc(ApprovalInstance::getSubmitTime);
44+
List<ApprovalInstance> approvalInstances = approvalInstanceMapper.selectListByLambda(instanceWrapper);
45+
if (CollectionUtils.isEmpty(approvalInstances)) {
46+
return null;
47+
}
48+
ApprovalInstance latestInstance = approvalInstances.getFirst();
49+
ApprovalInstanceDetail instanceDetail = BeanUtils.copyBean(new ApprovalInstanceDetail(), latestInstance);
50+
51+
// 获取所有审批任务 TODO: (只保留实例下节点最新的任务, 退回及撤回后会生成新的节点任务)
52+
LambdaQueryWrapper<ApprovalTask> taskWrapper = new LambdaQueryWrapper<>();
53+
taskWrapper.eq(ApprovalTask::getInstanceId, latestInstance.getId())
54+
.orderByAsc(ApprovalTask::getCreateTime);
55+
List<ApprovalTask> approvalTasks = approvalTaskMapper.selectListByLambda(taskWrapper);
56+
if (CollectionUtils.isNotEmpty(approvalTasks)) {
57+
instanceDetail.setNodes(null);
58+
return instanceDetail;
59+
}
60+
61+
List<String> signTaskIds = approvalTasks.stream().filter(ApprovalTask::getIsAddSign).map(ApprovalTask::getId).toList();
62+
LambdaQueryWrapper<ApprovalAddSignTask> signTaskWrapper = new LambdaQueryWrapper<>();
63+
signTaskWrapper.in(ApprovalAddSignTask::getTaskId, signTaskIds);
64+
List<ApprovalAddSignTask> signTasks = approvalAddSignTaskMapper.selectListByLambda(signTaskWrapper);
65+
Map<String, List<ApprovalAddSignTask>> signTaskGroupMap = signTasks.stream().collect(Collectors.groupingBy(ApprovalAddSignTask::getTaskId));
66+
67+
List<String> taskIds = approvalTasks.stream().map(ApprovalTask::getId).toList();
68+
List<String> signIds = signTasks.stream().map(ApprovalAddSignTask::getTaskId).toList();
69+
List<ApprovalRecord> approvalRecords = approvalRecordMapper.selectByIds(ListUtils.union(taskIds, signIds));
70+
Map<String, ApprovalRecord> taskRecordMap = approvalRecords.stream().collect(Collectors.toMap(ApprovalRecord::getTaskId, record -> record));
71+
72+
/*
73+
* 处理不同类型的任务:
74+
* 1. 加签任务: 需单独查询加签任务表, 并按位次配置追加。
75+
* 2. 退回任务: 如果为审批中, 需带上退回记录信息。
76+
* 3. 抄送任务: 查询该任务节点下所有的抄送任务, 并一起返回。
77+
*/
78+
List<ApprovalRecordNode> nodes = new ArrayList<>();
79+
for (ApprovalTask task : approvalTasks) {
80+
if (task.getIsAddSign()) {
81+
// TODO: 处理加签任务节点
82+
83+
}
84+
85+
if (task.getIsReturn()) {
86+
// TODO: 处理退回任务节点
87+
88+
}
89+
90+
if (task.getIsCc()) {
91+
// TODO: 处理抄送任务节点
92+
93+
}
94+
}
95+
96+
instanceDetail.setNodes(nodes);
97+
return instanceDetail;
98+
}
99+
}

0 commit comments

Comments
 (0)