修改:流程转办过程大改

This commit is contained in:
zjh 2025-12-17 11:17:59 +08:00
parent 5f7e8493e3
commit 5c87d67ac1
4 changed files with 49 additions and 152 deletions

View File

@ -60,9 +60,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
@Value("${apaas.token.clientSecred}") @Value("${apaas.token.clientSecred}")
private String clientSecret; private String clientSecret;
private static final String TODO_PREFIX = "report:todo:";
private static final String NODE_PROCESSED_PREFIX = "report:node:processed:";
private static final String FLOW_LOCK_PREFIX = "report:lock:"; private static final String FLOW_LOCK_PREFIX = "report:lock:";
private static final int FLOW_LOCK_EXPIRE_SECONDS = 15; private static final int FLOW_LOCK_EXPIRE_SECONDS = 15;
@ -113,11 +110,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
list.add(todoTask); list.add(todoTask);
} }
bd.getBusinessDatabase().doBatchInsert(list); bd.getBusinessDatabase().doBatchInsert(list);
// 3. 初始化Redis待办信息(校对节点)
form.getProofreadUsers().forEach(userId -> {
redisTemplate.opsForSet().add(TODO_PREFIX + userId, flow.getId());
});
} }
private String getNodeName(String node) { private String getNodeName(String node) {
@ -158,10 +150,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
flow.setExplanation(form.getExplanation()); flow.setExplanation(form.getExplanation());
bd.getBusinessDatabase().doInsert(flow); bd.getBusinessDatabase().doInsert(flow);
form.getProofreadUsers().forEach(userId -> {
redisTemplate.opsForSet().add(TODO_PREFIX + userId, flow.getId());
});
List<TodoTaskPojo> list = new ArrayList<>(); List<TodoTaskPojo> list = new ArrayList<>();
for (String person : form.getProofreadUsers()) { for (String person : form.getProofreadUsers()) {
TodoTaskPojo todoTask = new TodoTaskPojo(); TodoTaskPojo todoTask = new TodoTaskPojo();
@ -292,9 +280,11 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
throw new CommonException("当前节点正在处理,请稍后重试"); throw new CommonException("当前节点正在处理,请稍后重试");
} }
try { try {
String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode; int processedCount = bd.getBusinessDatabase()
long processedCount = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey)) .eq("document_no", flow.getId())
.orElse(0L); .eq("is_delete", 1)
.eq("current_node", getNodeName(flow.getCurrentNode()))
.doQuery(TodoTaskPojo.class).size();
if (processedCount > 0) { if (processedCount > 0) {
throw new CommonException("此节点已被他人处理"); throw new CommonException("此节点已被他人处理");
} }
@ -373,20 +363,20 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
record.setApprovalTime(Timestamp.valueOf(LocalDateTime.now())); record.setApprovalTime(Timestamp.valueOf(LocalDateTime.now()));
bd.getBusinessDatabase().doInsert(record); bd.getBusinessDatabase().doInsert(record);
redisTemplate.opsForSet().add(NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode,
request.getUserId());
bd.getBusinessDatabase() bd.getBusinessDatabase()
.eq("document_no", flow.getId()) .eq("document_no", flow.getId())
.eq("owner_id", request.getUserId()) .eq("owner_id", request.getUserId())
.eq("current_node", getNodeName(flow.getCurrentNode()))
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now())) .update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
.update("is_delete", 1) .update("is_delete", 1)
.doUpdate(TodoTaskPojo.class); .doUpdate(TodoTaskPojo.class);
bd.getBusinessDatabase() bd.getBusinessDatabase()
.eq("document_no", flow.getId()) .eq("document_no", flow.getId())
.ne("owner_id", request.getUserId()) .ne("owner_id", request.getUserId())
.eq("current_node", getNodeName(flow.getCurrentNode()))
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now())) .update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
.update("is_delete", 2) .update("is_delete", 2)
.doDelete(TodoTaskPojo.class); .doUpdate(TodoTaskPojo.class);
// 处理驳回逻辑 // 处理驳回逻辑
if ("REJECT".equals(request.getResult())) { if ("REJECT".equals(request.getResult())) {
@ -398,10 +388,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
} }
private void processNextNode(ApprovalFlow flow, String currentNode, String userId) { private void processNextNode(ApprovalFlow flow, String currentNode, String userId) {
// 检查当前节点是否满足流转条件
if (!checkNodeComplete(flow, currentNode)) {
return; // 未满足条件不流转
}
// 更新报告状态 // 更新报告状态
BenchmarkingReport report = bd.getBusinessDatabase() BenchmarkingReport report = bd.getBusinessDatabase()
@ -418,7 +404,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.rowid("id", report.getRowId()) .rowid("id", report.getRowId())
.update("status", report.getStatus()) .update("status", report.getStatus())
.doUpdate(BenchmarkingReport.class); .doUpdate(BenchmarkingReport.class);
clearProcessed(flow);
} else { } else {
flow.setCurrentNode(nextNode); flow.setCurrentNode(nextNode);
addNodeTodo(flow, nextNode, report, userId); addNodeTodo(flow, nextNode, report, userId);
@ -429,27 +414,10 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.update("flow_status", flow.getFlowStatus()) .update("flow_status", flow.getFlowStatus())
.update("current_node", flow.getCurrentNode()) .update("current_node", flow.getCurrentNode())
.doUpdate(ApprovalFlow.class); .doUpdate(ApprovalFlow.class);
// 清除当前节点待办
clearNodeTodoSmart(flow, currentNode, nextNode);
}
private void clearNodeTodoSmart(ApprovalFlow flow, String currentNode, String nextNode) {
List<String> currentNodeUsers = getNodeUsers(flow, currentNode);
List<String> nextNodeUsers = nextNode != null ? getNodeUsers(flow, nextNode) : Collections.emptyList();
// 只清除那些不在下一节点的用户的待办
for (String userId : currentNodeUsers) {
if (!nextNodeUsers.contains(userId)) {
redisTemplate.opsForSet().remove(TODO_PREFIX + userId, flow.getId());
}
}
} }
private void addNodeTodo(ApprovalFlow flow, String node, BenchmarkingReport report, String createBy) { private void addNodeTodo(ApprovalFlow flow, String node, BenchmarkingReport report, String createBy) {
List<String> users = getNodeUsers(flow, node); List<String> users = getNodeUsers(flow, node);
users.forEach(userId -> {
redisTemplate.opsForSet().add(TODO_PREFIX+ userId, flow.getId());
});
// 新增待办 // 新增待办
List<TodoTaskPojo> list = new ArrayList<>(); List<TodoTaskPojo> list = new ArrayList<>();
for (String person : users) { for (String person : users) {
@ -472,14 +440,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
bd.getBusinessDatabase().doBatchInsert(list); bd.getBusinessDatabase().doBatchInsert(list);
} }
private boolean checkNodeComplete(ApprovalFlow flow, String node) {
String key = NODE_PROCESSED_PREFIX + flow.getId() + ":" + node;
Long processedCount = redisTemplate.opsForSet().size(key);
if (processedCount == null) processedCount = 0L;
return processedCount >= 1;
}
private String getNextNode(String currentNode, ApprovalFlow flow) { private String getNextNode(String currentNode, ApprovalFlow flow) {
switch (currentNode) { switch (currentNode) {
case "PROOFREAD": case "PROOFREAD":
@ -510,32 +470,16 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.doUpdate(BenchmarkingReport.class); .doUpdate(BenchmarkingReport.class);
// 清除所有待办 // 清除所有待办
clearAllTodo(flow, userId); clearAllTodo(flow, userId);
clearProcessed(flow);
} }
private void clearAllTodo(ApprovalFlow flow, String userId) { private void clearAllTodo(ApprovalFlow flow, String userId) {
clearNodeTodo(flow, "PROOFREAD");
clearNodeTodo(flow, "REVIEW");
clearNodeTodo(flow, "APPROVE");
// 清除已有待办 // 清除已有待办
bd.getBusinessDatabase() bd.getBusinessDatabase()
.eq("document_no", flow.getId()) .eq("document_no", flow.getId())
.ne("owner_id", userId) .eq("is_delete", 0)
.update("is_delete", 2) .update("is_delete", 2)
.doDelete(TodoTaskPojo.class); .update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
} .doUpdate(TodoTaskPojo.class);
private void clearProcessed(ApprovalFlow flow) {
redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "PROOFREAD");
redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "REVIEW");
redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "APPROVE");
}
private void clearNodeTodo(ApprovalFlow flow, String node) {
List<String> users = getNodeUsers(flow, node);
users.forEach(userId -> {
redisTemplate.opsForSet().remove(TODO_PREFIX+ userId, flow.getId());
});
} }
private List<String> getNodeUsers(ApprovalFlow flow, String node) { private List<String> getNodeUsers(ApprovalFlow flow, String node) {

View File

@ -294,7 +294,10 @@ public class ParameterServiceImpl implements ParameterService {
.doQueryFirst(Parameter.class); .doQueryFirst(Parameter.class);
int maxNum = newParameters.stream() int maxNum = newParameters.stream()
.mapToInt(Parameter::getParameterNumber) .filter(Objects::nonNull)
.map(Parameter::getParameterNumber)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.max() .max()
.orElse(0); .orElse(0);

View File

@ -48,10 +48,6 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
@Resource @Resource
private XdapDeptUsersService xdapDeptUsersService; private XdapDeptUsersService xdapDeptUsersService;
// 待办标志: userId -> flowId集合
private static final String TODO_PREFIX = "approval:todo:";
// 节点已处理用户标志: flowId:node -> userId集合
private static final String NODE_PROCESSED_PREFIX = "approval:node:processed:";
// 分布式锁标志 // 分布式锁标志
private static final String FLOW_LOCK_PREFIX = "approval:lock:"; private static final String FLOW_LOCK_PREFIX = "approval:lock:";
// 分布式锁有效时间 // 分布式锁有效时间
@ -130,12 +126,6 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
.rowid("id", template.getRowId()) .rowid("id", template.getRowId())
.update("status", template.getStatus()) .update("status", template.getStatus())
.doUpdate(Template.class); .doUpdate(Template.class);
// 4. 初始化Redis待办信息(校对节点)
request.getProofreadUsers().forEach(userId -> {
redisTemplate.opsForSet().add(TODO_PREFIX + userId, flow.getId());
});
return flow.getId(); return flow.getId();
} }
@ -206,17 +196,16 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
String lockValue = UUID.randomUUID().toString(); String lockValue = UUID.randomUUID().toString();
boolean lockAcquired = redisLockUtil boolean lockAcquired = redisLockUtil
.tryLock(lockKey, lockValue, FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS); .tryLock(lockKey, lockValue, FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS);
// 其他人正在处理 // 其他人正在处理
if (!lockAcquired) { if (!lockAcquired) {
throw new CommonException("当前节点正在处理,请稍后重试"); throw new CommonException("当前节点正在处理,请稍后重试");
} }
try { try {
String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode; int processedCount = bd.getBusinessDatabase()
long processedCount = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey)) .eq("document_no", flow.getId())
.orElse(0L); .eq("current_node", getNodeName(flow.getCurrentNode()))
.eq("is_delete", 1)
.doQuery(TodoTaskPojo.class).size();
// 已被其他人处理 // 已被其他人处理
if (processedCount > 0) { if (processedCount > 0) {
throw new CommonException("此节点已被他人处理"); throw new CommonException("此节点已被他人处理");
@ -244,23 +233,20 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
record.setApprovalTime(Timestamp.valueOf(LocalDateTime.now())); record.setApprovalTime(Timestamp.valueOf(LocalDateTime.now()));
bd.getBusinessDatabase().doInsert(record); bd.getBusinessDatabase().doInsert(record);
redisTemplate.opsForSet().add(NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode,
request.getUserId());
// 删除当前节点的已处理待办 // 删除当前节点的已处理待办
if ("COUNTERSIGN".equals(flow.getCurrentNode())) { if (!"COUNTERSIGN".equals(flow.getCurrentNode())) {
redisTemplate.opsForSet().remove(TODO_PREFIX + request.getUserId(), flow.getId());
} else {
bd.getBusinessDatabase() bd.getBusinessDatabase()
.eq("document_no", flow.getId()) .eq("document_no", flow.getId())
.ne("owner_id", request.getUserId()) .ne("owner_id", request.getUserId())
.eq("current_node", getNodeName(flow.getCurrentNode()))
.update("is_delete", 2) .update("is_delete", 2)
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now())) .update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
.doDelete(TodoTaskPojo.class); .doUpdate(TodoTaskPojo.class);
} }
bd.getBusinessDatabase() bd.getBusinessDatabase()
.eq("document_no", flow.getId()) .eq("document_no", flow.getId())
.eq("owner_id", request.getUserId()) .eq("owner_id", request.getUserId())
.eq("current_node", getNodeName(flow.getCurrentNode()))
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now())) .update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
.update("is_delete", 1) .update("is_delete", 1)
.doUpdate(TodoTaskPojo.class); .doUpdate(TodoTaskPojo.class);
@ -403,7 +389,6 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
.doUpdate(Template.class); .doUpdate(Template.class);
// 更新机型版本 // 更新机型版本
// dataEntryEngineModelService.updateModelForNewVersion(); // dataEntryEngineModelService.updateModelForNewVersion();
clearProcessed(flow, userId);
} else { } else {
flow.setCurrentNode(nextNode); flow.setCurrentNode(nextNode);
addNodeTodo(flow, nextNode, template, userId); addNodeTodo(flow, nextNode, template, userId);
@ -414,8 +399,6 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
.update("flow_status", flow.getFlowStatus()) .update("flow_status", flow.getFlowStatus())
.update("current_node", flow.getCurrentNode()) .update("current_node", flow.getCurrentNode())
.doUpdate(ApprovalFlow.class); .doUpdate(ApprovalFlow.class);
// 清除当前节点待办
clearNodeTodoSmart(flow, currentNode, nextNode);
} }
// 获取下一节点 // 获取下一节点
@ -437,13 +420,14 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
// 检查节点是否完成 // 检查节点是否完成
private boolean checkNodeComplete(ApprovalFlow flow, String node) { private boolean checkNodeComplete(ApprovalFlow flow, String node) {
String key = NODE_PROCESSED_PREFIX + flow.getId() + ":" + node; Integer processedCount = bd.getBusinessDatabase()
Long processedCount = redisTemplate.opsForSet().size(key); .eq("document_no", flow.getId())
if (processedCount == null) processedCount = 0L; .eq("is_delete", 1)
.eq("current_node", getNodeName(flow.getCurrentNode()))
.doQuery(TodoTaskPojo.class).size();
// 会签节点需要所有人处理其他节点只需1人 // 会签节点需要所有人处理其他节点只需1人
if ("COUNTERSIGN".equals(node)) { if ("COUNTERSIGN".equals(node)) {
return processedCount.equals((long) JSON.parseArray(flow.getCountersignUsers()).size()); return processedCount.equals(JSON.parseArray(flow.getCountersignUsers()).size());
} else { } else {
return processedCount >= 1; return processedCount >= 1;
} }
@ -467,7 +451,6 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
.doUpdate(Template.class); .doUpdate(Template.class);
// 清除所有待办 // 清除所有待办
clearAllTodo(flow, userId); clearAllTodo(flow, userId);
clearProcessed(flow, userId);
} }
private boolean hasPermission(ApprovalFlow flow, String node, String userId) { private boolean hasPermission(ApprovalFlow flow, String node, String userId) {
@ -487,9 +470,6 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
private void addNodeTodo(ApprovalFlow flow, String node, Template template, String createBy) { private void addNodeTodo(ApprovalFlow flow, String node, Template template, String createBy) {
List<String> users = getNodeUsers(flow, node); List<String> users = getNodeUsers(flow, node);
users.forEach(userId -> {
redisTemplate.opsForSet().add(TODO_PREFIX+ userId, flow.getId());
});
// 新增待办 // 新增待办
List<TodoTaskPojo> list = new ArrayList<>(); List<TodoTaskPojo> list = new ArrayList<>();
for (String person : users) { for (String person : users) {
@ -512,47 +492,14 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
bd.getBusinessDatabase().doBatchInsert(list); bd.getBusinessDatabase().doBatchInsert(list);
} }
private void clearNodeTodo(ApprovalFlow flow, String node) {
List<String> users = getNodeUsers(flow, node);
users.forEach(userId -> {
redisTemplate.opsForSet().remove(TODO_PREFIX+ userId, flow.getId());
});
}
private void clearProcessed(ApprovalFlow flow, String userId) {
redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "PROOFREAD");
redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "REVIEW");
if (flow.getCountersignUsers() != null) {
redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "COUNTERSIGN");
}
redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "APPROVE");
}
private void clearAllTodo(ApprovalFlow flow, String userId) { private void clearAllTodo(ApprovalFlow flow, String userId) {
clearNodeTodo(flow, "PROOFREAD");
clearNodeTodo(flow, "REVIEW");
if (flow.getCountersignUsers() != null) {
clearNodeTodo(flow, "COUNTERSIGN");
}
clearNodeTodo(flow, "APPROVE");
// 清除已有待办 // 清除已有待办
bd.getBusinessDatabase() bd.getBusinessDatabase()
.eq("document_no", flow.getId()) .eq("document_no", flow.getId())
.ne("owner_id", userId) .eq("is_delete", 0)
.update("is_delete", 2) .update("is_delete", 2)
.doDelete(TodoTaskPojo.class); .update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
} .doUpdate(TodoTaskPojo.class);
private void clearNodeTodoSmart(ApprovalFlow flow, String currentNode, String nextNode) {
List<String> currentNodeUsers = getNodeUsers(flow, currentNode);
List<String> nextNodeUsers = nextNode != null ? getNodeUsers(flow, nextNode) : Collections.emptyList();
// 只清除那些不在下一节点的用户的待办
for (String userId : currentNodeUsers) {
if (!nextNodeUsers.contains(userId)) {
redisTemplate.opsForSet().remove(TODO_PREFIX + userId, flow.getId());
}
}
} }
private List<String> getNodeUsers(ApprovalFlow flow, String node) { private List<String> getNodeUsers(ApprovalFlow flow, String node) {

View File

@ -11,6 +11,7 @@ import com.xdap.self_development.enums.DistributeStatusEnum;
import com.xdap.self_development.pojo.*; import com.xdap.self_development.pojo.*;
import com.xdap.self_development.pojo.dto.EngineParamDetailDTO; import com.xdap.self_development.pojo.dto.EngineParamDetailDTO;
import com.xdap.self_development.pojo.dto.PageResultDTO; import com.xdap.self_development.pojo.dto.PageResultDTO;
import com.xdap.self_development.pojo.dto.YcTodoTaskResultDTO;
import com.xdap.self_development.service.DataEntryEngineModelService; import com.xdap.self_development.service.DataEntryEngineModelService;
import com.xdap.self_development.service.EngineParamDetailService; import com.xdap.self_development.service.EngineParamDetailService;
import com.xdap.self_development.service.TodoTaskService; import com.xdap.self_development.service.TodoTaskService;
@ -20,10 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -236,6 +234,11 @@ public class TodoTaskServiceImpl implements TodoTaskService {
} }
@Override
public List<YcTodoTaskResultDTO> returnTodoTask(String userName) {
return Collections.emptyList();
}
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚 @Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
public void batchInsertTodoTask(List<TodoTaskPojo> todoTaskPojos) { public void batchInsertTodoTask(List<TodoTaskPojo> todoTaskPojos) {
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(todoTaskPojos); sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(todoTaskPojos);