feat(taskflow): 添加意见填写标志并优化分支流程处理

master
zhaokai 2026-04-24 09:14:53 +08:00
parent fbe3c0b64d
commit 486cc0d0dc
11 changed files with 102 additions and 8 deletions

View File

@ -956,7 +956,6 @@ public class TaskLogUpdateExe {
*/ */
private void handleBranchStepsForReject(List<TaskLogE> allLogs, List<TaskLogDO> actionLogs) { private void handleBranchStepsForReject(List<TaskLogE> allLogs, List<TaskLogDO> actionLogs) {
log.info("开始处理打回时的分支步骤状态"); log.info("开始处理打回时的分支步骤状态");
// 收集所有分支开始节点 // 收集所有分支开始节点
List<TaskLogE> branchStartNodes = allLogs.stream() List<TaskLogE> branchStartNodes = allLogs.stream()
.filter(log -> BranchFlag.BRANCH_START.getCode().equals(log.getBranchFlag())) .filter(log -> BranchFlag.BRANCH_START.getCode().equals(log.getBranchFlag()))
@ -1003,11 +1002,16 @@ public class TaskLogUpdateExe {
private void handleRejectStep(TaskLogNextCmd cmd) { private void handleRejectStep(TaskLogNextCmd cmd) {
log.info("开始处理打回到某一步: workId={}, stepId={}", cmd.getWorkId(), cmd.getStepId()); log.info("开始处理打回到某一步: workId={}, stepId={}", cmd.getWorkId(), cmd.getStepId());
List<TaskLogE> allLogs = taskLogGateway.listAllByWorkId(cmd.getWorkId()); List<TaskLogE> allLogs = taskLogGateway.listAllByWorkId(cmd.getWorkId());
TaskLogE currentLog = findCurrentLog(allLogs, cmd.getId()); TaskLogE currentLog = findCurrentLog(allLogs, cmd.getId());
if (currentLog == null) { if (currentLog == null) {
throw new BizException("未找到对应的步骤记录"); throw new BizException("未找到对应的步骤记录");
} }
Integer rejectStepId = currentLog.getRejectStepId(); Integer rejectStepId = currentLog.getRejectStepId();
if(rejectStepId==null){ if(rejectStepId==null){
log.warn("未找到对应的步骤记录.workId={}, stepId={}", cmd.getWorkId(), cmd.getStepId()); log.warn("未找到对应的步骤记录.workId={}, stepId={}", cmd.getWorkId(), cmd.getStepId());
@ -1021,18 +1025,31 @@ public class TaskLogUpdateExe {
log.warn("未找到作业信息: workId={}", cmd.getWorkId()); log.warn("未找到作业信息: workId={}", cmd.getWorkId());
return; return;
} }
// 1. 归档当前的 task_log 记录(除了申请步骤) // 1. 归档当前的 task_log 记录(除了申请步骤)
archiveTaskLogs(allLogs); archiveTaskLogs(allLogs);
// 2. 删除的所有 task_log // 2. 删除的所有 task_log
deleteTaskLogsExceptFirst(cmd.getWorkId()); deleteTaskLogsExceptFirst(cmd.getWorkId());
List<TaskLogDO> taskLogs = taskLogCoConvertor.converEsToDOs(allLogs); List<TaskLogDO> taskLogs = taskLogCoConvertor.converEsToDOs(allLogs);
// 检查是否为持续步骤的特殊提交
// 持续步骤提交时不应改变状态为 APPROVED而应保持 IN_PROGRESS
boolean isOngoingStepSubmit = currentLog.getOngoingFlag() != null && currentLog.getOngoingFlag() == 1
&& StringUtils.isNotBlank(cmd.getSpecialStepCode());
// 1. 完成当前步骤(持续步骤的特殊提交跳过此步骤)
if (!isOngoingStepSubmit) {
completeCurrentStep(currentLog, cmd, taskLogs);
}
// 3. 设置所有步骤的id // 3. 设置所有步骤的id
for (TaskLogDO taskLog : taskLogs) { for (TaskLogDO taskLog : taskLogs) {
taskLog.setId(null); taskLog.setId(null);
taskLog.setTaskLogId(Tools.get32UUID()); taskLog.setTaskLogId(Tools.get32UUID());
taskLog.setUpdateTime(LocalDateTime.now());
taskLog.setUpdateId(null);
taskLog.setUpdateName( null);
} }
//4. 将指定步骤之后的步骤设置为未开始 //4. 将指定步骤之后的步骤设置为未开始
resetStepsAfterTargetStep(taskLogs, rejectStepId); resetStepsAfterTargetStep(taskLogs, rejectStepId);
@ -1040,8 +1057,8 @@ public class TaskLogUpdateExe {
// 5. 批量保存 // 5. 批量保存
taskLogRepository.saveBatch(taskLogs); taskLogRepository.saveBatch(taskLogs);
// 批量更新 eightworkInfo.info只更新本次变化的步骤
updateEightworkInfo(cmd.getWorkId(), taskLogs);
// 6. 发送待办完成事件 // 6. 发送待办完成事件
sendTodoCompleteEvent(currentLog.getId()); sendTodoCompleteEvent(currentLog.getId());
@ -1059,7 +1076,6 @@ public class TaskLogUpdateExe {
.findFirst() .findFirst()
.orElse(null); .orElse(null);
//发送待办和消息 //发送待办和消息
// 发送待办通知 // 发送待办通知
log.info("发送退回步骤待办通知"); log.info("发送退回步骤待办通知");
@ -1074,6 +1090,8 @@ public class TaskLogUpdateExe {
log.info("工作流已打回到指定步骤: workId={}, step={}", cmd.getWorkId(), rejectStepId); log.info("工作流已打回到指定步骤: workId={}, step={}", cmd.getWorkId(), rejectStepId);
} }
/** /**
* ID * ID
* - targetStepId 0 * - targetStepId 0
@ -1129,7 +1147,9 @@ public class TaskLogUpdateExe {
if (nextStep != null) { if (nextStep != null) {
// 只将通过状态1的步骤改为未开始-99 // 只将通过状态1的步骤改为未开始-99
if (TaskLogStatus.APPROVED.equalsCode(nextStep.getStatus())||TaskLogStatus.IN_PROGRESS.equalsCode(nextStep.getStatus())) { if (TaskLogStatus.APPROVED.equalsCode(nextStep.getStatus())
||TaskLogStatus.IN_PROGRESS.equalsCode(nextStep.getStatus())
|| REJECT_STEP_STATUS.equals(nextStep.getStatus())) {
Integer oldStatus = nextStep.getStatus(); Integer oldStatus = nextStep.getStatus();
nextStep.setStatus(TaskLogStatus.NOT_STARTED.getCode()); nextStep.setStatus(TaskLogStatus.NOT_STARTED.getCode());
resetCount++; resetCount++;
@ -1205,7 +1225,7 @@ public class TaskLogUpdateExe {
TaskLogDO branchStartNode = branchInfo.branchStartNode; TaskLogDO branchStartNode = branchInfo.branchStartNode;
Long branchStepId = branchInfo.branchStepId; Long branchStepId = branchInfo.branchStepId;
if (!TaskLogStatus.APPROVED.equalsCode(branchStartNode.getStatus())&&!TaskLogStatus.IN_PROGRESS.equalsCode(branchStartNode.getStatus())) { if (!TaskLogStatus.APPROVED.equalsCode(branchStartNode.getStatus())&&!TaskLogStatus.IN_PROGRESS.equalsCode(branchStartNode.getStatus())) {
log.warn("分支节点 {} (stepId={}) 状态不是通过或进行中,无法处理",branchStepId); log.warn("分支节点 (stepId={}) 状态不是通过或进行中,无法处理",branchStepId);
continue; continue;
} }
@ -1824,6 +1844,7 @@ public class TaskLogUpdateExe {
// 签字路径:只覆盖空值 // 签字路径:只覆盖空值
if (source.getSignPath() != null) { if (source.getSignPath() != null) {
target.setSignPath(source.getSignPath()); target.setSignPath(source.getSignPath());
target.setSignTime(LocalDateTime.now());
} }
// 填写次数:只覆盖空值 // 填写次数:只覆盖空值
if (source.getCurrentFillTimes() != null) { if (source.getCurrentFillTimes() != null) {
@ -2121,6 +2142,12 @@ public class TaskLogUpdateExe {
try { try {
JSONObject otherParams = JSONObject.parseObject(logDO.getOtherParams()); JSONObject otherParams = JSONObject.parseObject(logDO.getOtherParams());
stepInfo.put("otherParams", otherParams); stepInfo.put("otherParams", otherParams);
String hotTime = otherParams.getString("hotTime");
//工作结束时间
if (!StringUtils.isBlank(hotTime)) {
stepInfo.put("workEndTime", hotTime);
}
} catch (Exception e) { } catch (Exception e) {
// 如果不是JSON格式直接存储字符串 // 如果不是JSON格式直接存储字符串
stepInfo.put("otherParams", logDO.getOtherParams()); stepInfo.put("otherParams", logDO.getOtherParams());

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zcloud.eightwork.command.convertor.EightworkInfoCoConvertor; import com.zcloud.eightwork.command.convertor.EightworkInfoCoConvertor;
import com.zcloud.eightwork.command.convertor.TaskLogCoConvertor; import com.zcloud.eightwork.command.convertor.TaskLogCoConvertor;
import com.zcloud.eightwork.domain.model.TodoCountE; import com.zcloud.eightwork.domain.model.TodoCountE;
import com.zcloud.eightwork.domain.model.enums.StepType;
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus; import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
import com.zcloud.eightwork.dto.TaskLogPageQry; import com.zcloud.eightwork.dto.TaskLogPageQry;
import com.zcloud.eightwork.dto.clientobject.BlockingStepInfoCO; import com.zcloud.eightwork.dto.clientobject.BlockingStepInfoCO;
@ -63,7 +64,34 @@ public class TaskLogQueryExe {
examCenterCOS.forEach(item -> { examCenterCOS.forEach(item -> {
item.setWorkInfo(workInfos.stream().filter(workInfo -> workInfo.getWorkId().equals(item.getWorkId())).findFirst().orElse(null)); item.setWorkInfo(workInfos.stream().filter(workInfo -> workInfo.getWorkId().equals(item.getWorkId())).findFirst().orElse(null));
}); });
//如果不是分支项目直接返回
//如果是分支节点,需要展示对应主流程的状态信息 step_type =2是分支流程需要查询每一条数据对应workid中step_type=1 并且status=0的第一个stepName
//查询结果只能是单一流程,判断是否为分支流程
if(StepType.BRANCH.getCode().equals(examCenterCOS.get(0).getStepType())){
//获取这些workId对应的主流程步骤step_type=1 且 status=0
List<TaskLogDO> taskLogDOList = taskLogRepository.listAllByWorkIdList(workIds, TaskLogStatus.IN_PROGRESS.getCode(), StepType.NORMAL.getCode());
if(!CollectionUtils.isEmpty(taskLogDOList)){
// 按workId分组获取每个workId的第一个步骤已经是按stepOrder排序的
Map<String, TaskLogDO> workIdToMainStepMap = taskLogDOList.stream()
.collect(Collectors.toMap(
TaskLogDO::getWorkId,
taskLogDO -> taskLogDO,
(existing, replacement) -> existing // 如果有重复,保留第一个
));
// 为分支步骤设置主流程的步骤名称
examCenterCOS.forEach(item -> {
TaskLogDO mainStep = workIdToMainStepMap.get(item.getWorkId());
if(mainStep != null){
item.setStepName(mainStep.getStepName());
log.info("分支步骤显示主流程状态: workId={}, branchStepId={}, mainStepName={}",
item.getWorkId(), item.getStepId(), mainStep.getStepName());
} }
});
}
}
}
return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex()); return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
} }

View File

@ -83,7 +83,8 @@ public class TaskFlowAddCmd extends Command {
@ApiModelProperty(value = "是否可以打回1是2否", name = "rejectedStepFlag") @ApiModelProperty(value = "是否可以打回1是2否", name = "rejectedStepFlag")
private Integer rejectedStepFlag; private Integer rejectedStepFlag;
@ApiModelProperty(value = "是否填写意见1是2否")
private Integer opinionFlag;
@ApiModelProperty(value = "0无分支1有分支开始2有分支结束", name = "branchFlag", required = true) @ApiModelProperty(value = "0无分支1有分支开始2有分支结束", name = "branchFlag", required = true)
@NotNull(message = "0无分支1有分支开始2有分支结束不能为空") @NotNull(message = "0无分支1有分支开始2有分支结束不能为空")

View File

@ -62,6 +62,8 @@ public class TaskFlowCO extends ClientObject {
//是否可以打回1是2否 //是否可以打回1是2否
@ApiModelProperty(value = "是否可以打回1是2否") @ApiModelProperty(value = "是否可以打回1是2否")
private Integer rejectedStepFlag; private Integer rejectedStepFlag;
@ApiModelProperty(value = "是否填写意见1是2否")
private Integer opinionFlag;
//0无分支1有分支开始2有分支结束 //0无分支1有分支开始2有分支结束
@ApiModelProperty(value = "0无分支1有分支开始2有分支结束") @ApiModelProperty(value = "0无分支1有分支开始2有分支结束")
private Integer branchFlag; private Integer branchFlag;

View File

@ -103,6 +103,8 @@ public class TaskLogCO extends ClientObject {
//是否可以打回1是2否 //是否可以打回1是2否
@ApiModelProperty(value = "是否可以打回1是2否") @ApiModelProperty(value = "是否可以打回1是2否")
private Integer rejectedStepFlag; private Integer rejectedStepFlag;
@ApiModelProperty(value = "是否填写意见1是2否")
private Integer opinionFlag;
//0无分支1有分支开始2有分支结束 //0无分支1有分支开始2有分支结束
@ApiModelProperty(value = "0无分支1有分支开始2有分支结束") @ApiModelProperty(value = "0无分支1有分支开始2有分支结束")
private Integer branchFlag; private Integer branchFlag;

View File

@ -48,6 +48,8 @@ public class TaskFlowE extends BaseE {
private Integer measuresStepFlag; private Integer measuresStepFlag;
//是否可以打回1是2否 //是否可以打回1是2否
private Integer rejectedStepFlag; private Integer rejectedStepFlag;
@ApiModelProperty(value = "是否填写意见1是2否")
private Integer opinionFlag;
//0无分支1有分支开始2有分支结束 //0无分支1有分支开始2有分支结束
private Integer branchFlag; private Integer branchFlag;
//branch_flag == 1 分支节点ID //branch_flag == 1 分支节点ID

View File

@ -74,6 +74,8 @@ public class TaskLogE extends BaseE {
private Integer measuresStepFlag; private Integer measuresStepFlag;
//是否可以打回1是2否 //是否可以打回1是2否
private Integer rejectedStepFlag; private Integer rejectedStepFlag;
@ApiModelProperty(value = "是否填写意见1是2否")
private Integer opinionFlag;
//0无分支1有分支开始2有分支结束 //0无分支1有分支开始2有分支结束
private Integer branchFlag; private Integer branchFlag;
//branch_flag == 1 分支节点ID //branch_flag == 1 分支节点ID
@ -131,6 +133,7 @@ public class TaskLogE extends BaseE {
this.selectSignStep = log.getSelectSignStep(); this.selectSignStep = log.getSelectSignStep();
this.measuresStepFlag = log.getMeasuresStepFlag(); this.measuresStepFlag = log.getMeasuresStepFlag();
this.rejectedStepFlag = log.getRejectedStepFlag(); this.rejectedStepFlag = log.getRejectedStepFlag();
this.opinionFlag = log.getOpinionFlag();
this.branchFlag = log.getBranchFlag(); this.branchFlag = log.getBranchFlag();
this.branchStep = log.getBranchStep(); this.branchStep = log.getBranchStep();
this.branchMergeStep = log.getBranchMergeStep(); this.branchMergeStep = log.getBranchMergeStep();

View File

@ -65,6 +65,8 @@ public class TaskFlowDO extends BaseDO {
//是否可以打回1是2否 //是否可以打回1是2否
@ApiModelProperty(value = "是否可以打回1是2否") @ApiModelProperty(value = "是否可以打回1是2否")
private Integer rejectedStepFlag; private Integer rejectedStepFlag;
@ApiModelProperty(value = "是否填写意见1是2否")
private Integer opinionFlag;
//0无分支1有分支开始2有分支结束 //0无分支1有分支开始2有分支结束
@ApiModelProperty(value = "0无分支1有分支开始2有分支结束") @ApiModelProperty(value = "0无分支1有分支开始2有分支结束")
private Integer branchFlag; private Integer branchFlag;

View File

@ -103,6 +103,8 @@ public class TaskLogDO extends BaseDO {
//是否可以打回1是2否 //是否可以打回1是2否
@ApiModelProperty(value = "是否可以打回1是2否") @ApiModelProperty(value = "是否可以打回1是2否")
private Integer rejectedStepFlag; private Integer rejectedStepFlag;
@ApiModelProperty(value = "是否填写意见1是2否")
private Integer opinionFlag;
//0无分支1有分支开始2有分支结束 //0无分支1有分支开始2有分支结束
@ApiModelProperty(value = "0无分支1有分支开始2有分支结束") @ApiModelProperty(value = "0无分支1有分支开始2有分支结束")
private Integer branchFlag; private Integer branchFlag;

View File

@ -42,5 +42,13 @@ public interface TaskLogRepository extends BaseRepository<TaskLogDO> {
* @return * @return
*/ */
int physicalDeleteByIds(List<Long> ids); int physicalDeleteByIds(List<Long> ids);
/**
* /
* @param workIds
* @param status
* @return
*/
List<TaskLogDO> listAllByWorkIdList(List<String> workIds, Integer status, Integer stepType);
} }

View File

@ -18,6 +18,7 @@ import com.zcloud.gbscommon.utils.Query;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -74,5 +75,21 @@ public class TaskLogRepositoryImpl extends BaseRepositoryImpl<TaskLogMapper, Tas
// 使用 Mapper 中定义的物理删除 SQL // 使用 Mapper 中定义的物理删除 SQL
return taskLogMapper.physicalDeleteByIds(ids); return taskLogMapper.physicalDeleteByIds(ids);
} }
@Override
public List<TaskLogDO> listAllByWorkIdList(List<String> workIds, Integer status, Integer stepType) {
LambdaQueryWrapper<TaskLogDO> taskLogDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
taskLogDOLambdaQueryWrapper.in(TaskLogDO::getWorkId, workIds);
if(status!=null){
taskLogDOLambdaQueryWrapper.eq(TaskLogDO::getStatus, status);
}
if(stepType!=null){
taskLogDOLambdaQueryWrapper.eq(TaskLogDO::getStepType, stepType);
}
taskLogDOLambdaQueryWrapper.orderByAsc(TaskLogDO::getStepOrder)
.orderByAsc(TaskLogDO::getCreateTime);
return list(taskLogDOLambdaQueryWrapper);
}
} }