feat(task): 重构任务日志处理功能并添加转换工具类

- 新增 TaskLogConvertUtil 工具类实现 TaskLogE 与 TaskLogDO 之间的转换
- 重构 TaskLogAddExe 优化作业流程创建逻辑,使用 Redis 原子递增生成票号
- 重构 TaskLogUpdateExe 重写步骤流转核心逻辑,支持多步骤类型和分支流程处理
- 添加常量定义统一管理流程标识符,提升代码可维护性
- 实现特殊步骤处理机制,支持延时监火、安全措施、气体检测等场景
- 优化待办事项推送逻辑,完善流程状态管理
- 添加日志记录便于问题排查和流程监控
master
fangjiakai 2026-03-13 08:29:06 +08:00
parent 34c34f4b29
commit 597eb47554
18 changed files with 1040 additions and 228 deletions

View File

@ -5,6 +5,7 @@ import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.eightwork.domain.gateway.TaskFlowGateway;
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
import com.zcloud.eightwork.domain.model.TaskFlowE;
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
import com.zcloud.eightwork.domain.model.enums.WorkCodeEnum;
import com.zcloud.eightwork.dto.TaskLogAddCmd;
import com.zcloud.eightwork.dto.TaskSignStepInfoCmd;
@ -15,88 +16,198 @@ import com.zcloud.eightwork.persistence.repository.TaskLogRepository;
import com.zcloud.gbscommon.utils.DateUtil;
import com.zcloud.gbscommon.utils.Tools;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* web-app
*
*
*
* @Author fangjiakai
* @Date 2025-11-05 09:53:53
*/
@Slf4j
@Component
@AllArgsConstructor
public class TaskLogAddExe {
/** 第一步申请步骤的步骤ID */
private static final Long FIRST_STEP_ID = 1L;
/** 可跳过标识 */
private static final Integer CAN_SKIP_FLAG = 1;
/** 持续步骤标识 */
private static final Integer ONGOING_FLAG = 1;
/** 票号 Redis Key 前缀 */
private static final String TICKET_NO_KEY_PREFIX = "eightwork:ticket:no:";
/** Redis Key 过期时间48小时确保跨天仍可用 */
private static final long KEY_EXPIRE_HOURS = 48;
private final TaskLogGateway taskLogGateway;
private final TaskLogRepository taskLogRepository;
private final TaskFlowGateway taskFlowGateway;
private final EightworkInfoRepository eightworkInfoRepository;
private final StringRedisTemplate stringRedisTemplate;
@Transactional(rollbackFor = Exception.class)
public synchronized List<TaskLogDO> execute(TaskLogAddCmd cmd) {
public List<TaskLogDO> execute(TaskLogAddCmd cmd) {
log.info("开始创建作业流程: workType={}, workLevel={}", cmd.getWorkType(), cmd.getWorkLevel());
try {
// 1. 创建作业信息
String workId = saveWork(cmd);
log.info("作业信息已创建: workId={}", workId);
// 2. 获取流程配置
List<TaskFlowE> flows = taskFlowGateway.listAllByWorkType(cmd.getWorkType(), cmd.getWorkLevel());
List<TaskLogDO> taskLogs = flows.stream().map(flow -> {
log.info("获取到 {} 个流程步骤", flows.size());
// 3. 生成任务日志
List<TaskLogDO> taskLogs = flows.stream().map(flow -> createTaskLog(flow, workId, cmd)).collect(Collectors.toList());
// 4. 批量保存
taskLogRepository.saveBatch(taskLogs);
log.info("作业流程创建成功: workId={}, stepCount={}", workId, taskLogs.size());
return taskLogs;
} catch (Exception e) {
log.error("创建作业流程失败: workType={}", cmd.getWorkType(), e);
throw new BizException("保存失败: " + e.getMessage());
}
}
/**
*
*/
private TaskLogDO createTaskLog(TaskFlowE flow, String workId, TaskLogAddCmd cmd) {
TaskLogDO taskLogDO = new TaskLogDO(Tools.get32UUID());
BeanUtils.copyProperties(flow, taskLogDO, "id");
taskLogDO.setWorkId(workId);
taskLogDO.setStatus(-99);
if (flow.getStepId() == 1) {
taskLogDO.setSign(flow.getActorField(),
// 持续步骤(如气体检测):申请后就开始,且状态始终为进行中
if (flow.getOngoingFlag() != null && flow.getOngoingFlag() == 1) {
taskLogDO.setStatus(TaskLogStatus.IN_PROGRESS.getCode());
taskLogDO.setCurrentFillTimes(0);
log.info("持续步骤已初始化: stepName={}", flow.getStepName());
} else {
// 默认状态为未开始
taskLogDO.setStatus(TaskLogStatus.NOT_STARTED.getCode());
}
// 第一步自动设置为当前申请人
if (FIRST_STEP_ID.equals(flow.getStepId())) {
taskLogDO.setSign(
flow.getActorField(),
AuthContext.getOrgId(),
AuthContext.getCurrentUser().getOrgName(),
AuthContext.getUserId(),
AuthContext.getName());
}
TaskSignStepInfoCmd taskSignStepInfoCmd = cmd.getSignLogs().stream().filter(info -> info.getStepId().equals(flow.getStepId())).findFirst().orElse(null);
if (taskSignStepInfoCmd != null) {
if (flow.getCanSkip() == 1 && taskSignStepInfoCmd.getActUser() == null) {
taskLogDO.setStatus(-1); // 设置跳过
} else {
taskLogDO.setSign(taskSignStepInfoCmd.getActorField(),
taskSignStepInfoCmd.getActUserDepartment(),
taskSignStepInfoCmd.getActUserDepartmentName(),
taskSignStepInfoCmd.getActUser(),
taskSignStepInfoCmd.getActUserName());
taskLogDO.setWorkType(cmd.getWorkType());
AuthContext.getName()
);
log.info("第一步已设置申请人: stepName={}", flow.getStepName());
}
// 处理用户预设的签字人
TaskSignStepInfoCmd signInfo = findSignInfo(cmd, flow.getStepId());
if (signInfo != null) {
handlePredefinedSigner(taskLogDO, flow, signInfo, cmd);
}
return taskLogDO;
}).collect(Collectors.toList());
taskLogRepository.saveBatch(taskLogs);
return taskLogs;
} catch (Exception e) {
e.printStackTrace();
throw new BizException("保存失败");
}
/**
*
*/
private TaskSignStepInfoCmd findSignInfo(TaskLogAddCmd cmd, Long stepId) {
if (cmd.getSignLogs() == null) {
return null;
}
return cmd.getSignLogs().stream()
.filter(info -> info.getStepId().equals(stepId))
.findFirst()
.orElse(null);
}
/**
*
*/
private void handlePredefinedSigner(TaskLogDO taskLogDO, TaskFlowE flow, TaskSignStepInfoCmd signInfo, TaskLogAddCmd cmd) {
// 可跳过步骤且未设置签字人,则设置为跳过状态
if (CAN_SKIP_FLAG.equals(flow.getCanSkip()) && signInfo.getActUser() == null) {
taskLogDO.setStatus(TaskLogStatus.SKIPPED.getCode());
log.info("步骤设置为跳过: stepName={}", flow.getStepName());
} else {
// 设置预设签字人
taskLogDO.setSign(
signInfo.getActorField(),
signInfo.getActUserDepartment(),
signInfo.getActUserDepartmentName(),
signInfo.getActUser(),
signInfo.getActUserName()
);
taskLogDO.setWorkType(cmd.getWorkType());
log.info("已设置预设签字人: stepName={}, userName={}", flow.getStepName(), signInfo.getActUserName());
}
}
/**
*
* 使 Redis
*/
private String saveWork(TaskLogAddCmd cmd) {
Long workCountBytype = eightworkInfoRepository.countByWorkType(cmd.getWorkType());
String nosb = "QG" +
WorkCodeEnum.getCodeByWorkType(cmd.getWorkType()) +
DateUtil.getDays() +
workCountBytype;
EightworkInfoDO eightworkInfo = new EightworkInfoDO(Tools.get32UUID()
, cmd.getWorkType()
, cmd.getWorkLevel()
, cmd.getCorpinfoId()
, cmd.getXgfFlag()
, cmd.getInternalOperationFlag()
, cmd.getProjectId()
, cmd.getXgfId()
, nosb
, 1
, cmd.getInfo()
, cmd.getDepartmentId());
String workType = cmd.getWorkType();
String workTypeCode = WorkCodeEnum.getCodeByWorkType(workType);
String date = DateUtil.getDays();
// 构建 Redis Key: eightwork:ticket:no:DH:20250312
String redisKey = buildTicketNoKey(workTypeCode, date);
// Redis 原子递增获取序号从1开始
Long seq = stringRedisTemplate.opsForValue().increment(redisKey);
if (seq == 1) {
stringRedisTemplate.expire(redisKey, KEY_EXPIRE_HOURS, TimeUnit.HOURS);
}
log.info("生成票号: workType={}, date={}, seq={}", workType, date, seq);
// 生成票号: QG + 作业类型代码 + 日期 + 4位序号
String checkNo = "QG" + workTypeCode + date + String.format("%04d", seq);
EightworkInfoDO eightworkInfo = new EightworkInfoDO(
Tools.get32UUID(),
cmd.getWorkType(),
cmd.getWorkLevel(),
cmd.getCorpinfoId(),
cmd.getXgfFlag(),
cmd.getInternalOperationFlag(),
cmd.getProjectId(),
cmd.getXgfId(),
checkNo,
TaskLogStatus.IN_PROGRESS.getCode(), // 初始状态为进行中
cmd.getInfo(),
cmd.getDepartmentId()
);
eightworkInfoRepository.save(eightworkInfo);
return eightworkInfo.getWorkId();
}
}
/**
* Redis Key
* : eightwork:ticket:no:{}:{}
*
* @param workTypeCode DHMBCD
* @param date yyyyMMdd
* @return Redis Key
*/
private String buildTicketNoKey(String workTypeCode, String date) {
return TICKET_NO_KEY_PREFIX + workTypeCode + ":" + date;
}
}

View File

@ -6,10 +6,15 @@ import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zcloud.eightwork.command.convertor.TaskLogConvertUtil;
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
import com.zcloud.eightwork.domain.gateway.EightworkSupplementaryInfoGateway;
import com.zcloud.eightwork.domain.model.MeasuresLogsE;
import com.zcloud.eightwork.domain.model.EightworkSupplementaryInfoE;
import com.zcloud.eightwork.domain.model.TaskLogE;
import com.zcloud.eightwork.domain.model.enums.MenuEnum;
import com.zcloud.eightwork.domain.model.enums.BranchFlag;
import com.zcloud.eightwork.domain.model.enums.StepType;
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
import com.zcloud.eightwork.domain.model.enums.WorkCodeEnum;
import com.zcloud.eightwork.dto.TaskLogNextCmd;
import com.zcloud.eightwork.dto.TaskLogUpdateCmd;
@ -24,6 +29,7 @@ import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil;
import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent;
import com.zcloud.gbscommon.todolistmq.event.TodoListCompleteEvent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
@ -35,19 +41,37 @@ import java.util.stream.Collectors;
/**
* web-app
*
*
*
* @Author fangjiakai
* @Date 2025-11-05 09:53:54
*/
@Slf4j
@Component
@AllArgsConstructor
public class TaskLogUpdateExe {
/** 签字步骤标识 */
private static final Integer SIGN_STEP_FLAG = 1;
/** 多人签字标识 */
private static final Integer MULTIPLE_FLAG = 1;
/** 主要措施类型 */
private static final Integer MAIN_MEASURE_TYPE = 1;
/** 可添加其他安全措施标识 */
private static final Integer MEASURES_STEP_FLAG = 1;
/** 可跳过标识 */
private static final Integer CAN_SKIP_FLAG = 1;
/** PC端待办标识 */
private static final Integer PC_FLAG = 1;
/** APP端待办标识 */
private static final Integer APP_FLAG = 1;
private final TaskLogGateway taskLogGateway;
private final TaskLogRepository taskLogRepository;
private final MeasuresLogsRepository measuresLogsRepository;
private final EightworkInfoRepository eightworkInfoRepository;
private final TodoListEventPusherUtil todoListEventPusherUtil;
private final EightworkSupplementaryInfoGateway eightworkSupplementaryInfoGateway;
@Transactional(rollbackFor = Exception.class)
public void execute(TaskLogUpdateCmd taskLogUpdateCmd) {
@ -59,148 +83,172 @@ public class TaskLogUpdateExe {
}
}
/**
*
*
* 1.
* 2.
* 3.
* 4.
* 5.
* 6.
*
* @param cmd
*/
@Transactional(rollbackFor = Exception.class)
public void nextStep(TaskLogNextCmd cmd) {
log.info("开始处理步骤流转: workId={}, stepId={}, status={}",
cmd.getWorkId(), cmd.getStepId(), cmd.getStatus());
List<TaskLogE> logs = taskLogGateway.listAllByWorkId(cmd.getWorkId());
// 待操作logs
List<TaskLogDO> actionLogs = new ArrayList<>();
logs.forEach(log -> {
// 修改当前步骤状态
if (log.getId().equals(cmd.getId())) {
log.setStatus(cmd.getStatus());
if (log.getSignStepFlag() == 1) {
log.setSignPath(cmd.getSignPath());
// 查找当前处理的步骤日志
TaskLogE currentLog = findCurrentLog(logs, cmd.getId());
if (currentLog == null) {
throw new BizException("未找到对应的步骤记录");
}
TodoListCompleteEvent todoCompletedTaskEvent = new TodoListCompleteEvent();
todoCompletedTaskEvent.setForeignSubsidiaryKey(log.getId());
todoListEventPusherUtil.sendMessageCompleteEvent(todoCompletedTaskEvent);
// 1. 完成当前步骤
completeCurrentStep(currentLog, cmd, actionLogs);
TaskLogDO logDO = new TaskLogDO();
BeanUtils.copyProperties(log, logDO);
actionLogs.add(logDO);
// 同意时
if (cmd.getStatus() == 1) {
// 多人签字步骤时
boolean canNext = true;
if (log.getMultipleFlag() == 1) {
// 获取多人签字步骤未签字的其他人人数
long multipleSigns = logs.stream().filter(info -> info.getStepId().equals(log.getStepId()) && log.getStatus() != 1 && !log.getId().equals(cmd.getId())).collect(Collectors.toList()).size();
canNext = multipleSigns == 0;
// 2. 判断是否通过,通过才流转
if (TaskLogStatus.APPROVED.equalsCode(cmd.getStatus())) {
// 3. 判断是否可以流转到下一步
if (canProceedToNext(currentLog, logs, cmd)) {
// 4. 处理特殊步骤逻辑
boolean shouldProceed = handleSpecialStepIfNeeded(currentLog, cmd, actionLogs);
// 5. 处理其他安全措施
handleOtherMeasuresIfNeeded(currentLog, cmd);
// 6. 流转到下一步
if (shouldProceed) {
proceedToNextStep(currentLog, actionLogs, logs);
}
// 特殊步骤
if (StringUtils.isNotBlank(log.getSpecialStepCode())) {
canNext = handleSpecialStep(log, cmd, actionLogs);
}
// 其他安全措施步骤
if (log.getMeasuresStepFlag() != null && 1 == log.getMeasuresStepFlag()) {
MeasuresLogsDO measuresLogsDO = new MeasuresLogsDO(
cmd.getOthers().getString("otherMeasures"),
log.getWorkId(),
log.getWorkType()
);
measuresLogsRepository.save(measuresLogsDO);
}
if (canNext) {
// 递归 直到找到不跳过的下一步
handleNextStep(log, actionLogs, logs);
}
// 如果当前步骤为分支开始步骤
if (log.getStepType() == 1 && log.getBranchFlag() == 1) {
TaskLogE branchStep = logs.stream().filter(info -> info.getStepId().equals(log.getBranchStep())).findFirst().orElse(null);
if (branchStep != null) {
branchStep.setStatus(0);
TaskLogDO branchLogDO = new TaskLogDO();
BeanUtils.copyProperties(branchStep, branchLogDO);
actionLogs.add(branchLogDO);
// 7. 处理分支流程
handleBranchIfNeeded(currentLog, actionLogs, logs);
// 8. 设置后续签字人
handleSignStepsIfNeeded(currentLog, cmd, actionLogs, logs);
}
}
// 判断是否有当前步骤设置的签字人
if (cmd.getSignLogs() != null && cmd.getSignLogs().size() > 0) {
cmd.getSignLogs().stream().forEach(info -> {
TaskLogE signStepLog = logs.stream().filter(tempLog -> tempLog.getStepId().equals(info.getStepId())).findFirst().orElse(null);
if (signStepLog != null) {
if (log.getCanSkip() == 1 && signStepLog.getActUser() == null) {
log.setStatus(-1); // 设置跳过
TaskLogDO skipLogDO = new TaskLogDO();
BeanUtils.copyProperties(log, skipLogDO);
actionLogs.add(skipLogDO);
} else {
signStepLog.setSign(info.getActorField(),
info.getActUserDepartment(),
info.getActUserDepartmentName(),
info.getActUser(),
info.getActUserName());
TaskLogDO signLogDO = new TaskLogDO();
BeanUtils.copyProperties(signStepLog, signLogDO);
actionLogs.add(signLogDO);
}
}
});
}
}
}
});
// 批量更新
taskLogRepository.updateBatchById(actionLogs);
log.info("步骤流转完成: workId={}, currentStep={}", cmd.getWorkId(), currentLog.getStepName());
}
/**
*
*
* @param log
* @param actionLogs
* @param logs
* @return
*
*/
private void handleNextStep(TaskLogE log, List<TaskLogDO> actionLogs, List<TaskLogE> logs) {
List<TaskLogE> nextStep = logs.stream().filter(info -> info.getStepId().equals(log.getNextStep())).collect(Collectors.toList());
if (!CollectionUtil.isEmpty(nextStep)) {
// 下一步跳过时, 多人签字不存在跳过情况
TaskLogE nextStepTemp = nextStep.get(0);
if (nextStepTemp.getStatus() == -1) { // 步骤可跳过 并且未设置签字人 则判断为跳过步骤
handleNextStep(nextStepTemp, actionLogs, logs);
} else { // 非跳过时
Long workId = eightworkInfoRepository.getOne(new LambdaQueryWrapper<EightworkInfoDO>().select(EightworkInfoDO::getId).eq(EightworkInfoDO::getWorkId, log.getWorkId())).getId();
// 可能涉及多人签字
nextStep.forEach(next -> {
next.setStatus(0);
TaskLogDO nextLogDO = new TaskLogDO();
BeanUtils.copyProperties(next, nextLogDO);
actionLogs.add(nextLogDO);
// 添加待办
TodoListAddEvent event = new TodoListAddEvent();
event.setTitle("您有一条"+ WorkCodeEnum.getNameByWorkType(log.getWorkType()) +"流程待处理");
event.setContent(next.getNextStepName());
event.setForeignKey(workId); // 业务表ID
event.setForeignSubsidiaryKey(next.getId()); // 业务附表ID 没有附表时为foreignKey的值
event.setReceiveUser(next.getActUser());// user表ID
event.setPcFlag(1); // 是否PC端待办 1是 0否
event.setAppFlag(1); // 是否APP端待办 1是 0否
event.setOtherParams(new JSONObject());
todoListEventPusherUtil.sendMessageAddEvent(event);
});
eightworkInfoRepository.updateWorkStatus(log.getWorkId(),nextStep.get(0).getStepName() , null);
private TaskLogE findCurrentLog(List<TaskLogE> logs, Long id) {
return logs.stream()
.filter(log -> log.getId().equals(id))
.findFirst()
.orElse(null);
}
}else{
// 没有下一步 则设置作业状态为999 验收
eightworkInfoRepository.updateWorkStatus(log.getWorkId(), "已归档", 999);
/**
*
* -
* -
* -
*/
private void completeCurrentStep(TaskLogE currentLog, TaskLogNextCmd cmd, List<TaskLogDO> actionLogs) {
log.info("完成当前步骤: stepName={}, status={}", currentLog.getStepName(), cmd.getStatus());
currentLog.setStatus(cmd.getStatus());
// 签字步骤,保存签字图片
if (SIGN_STEP_FLAG.equals(currentLog.getSignStepFlag())) {
currentLog.setSignPath(cmd.getSignPath());
}
// 发送待办完成事件
sendTodoCompleteEvent(currentLog.getId());
actionLogs.add(TaskLogConvertUtil.toDO(currentLog));
}
/**
*
* -
* -
*/
private boolean canProceedToNext(TaskLogE currentLog, List<TaskLogE> logs, TaskLogNextCmd cmd) {
// 1. 多人签字步骤:需要所有人都签字
if (MULTIPLE_FLAG.equals(currentLog.getMultipleFlag())) {
long pendingSigns = logs.stream()
.filter(log -> log.getStepId().equals(currentLog.getStepId())
&& !TaskLogStatus.APPROVED.equalsCode(log.getStatus())
&& !log.getId().equals(currentLog.getId()))
.count();
if (pendingSigns > 0) {
log.info("多人签字步骤,还有 {} 人未签字,暂不流转", pendingSigns);
return false;
}
}
// 2. 检查是否为特殊步骤
if (StringUtils.isNotBlank(currentLog.getSpecialStepCode())) {
// 特殊步骤的流转判断在 handleSpecialStepIfNeeded 中处理
}
return true;
}
/**
*
* - delay:
* - measures:
* - gas:
*
* @return
*/
private boolean handleSpecialStepIfNeeded(TaskLogE currentLog, TaskLogNextCmd cmd, List<TaskLogDO> actionLogs) {
String specialStepCode = cmd.getSpecialStepCode();
if (StringUtils.isBlank(specialStepCode)) {
return true;
}
log.info("处理特殊步骤: stepCode={}", specialStepCode);
switch (specialStepCode) {
case "delay":
return handleDelayStep(currentLog, cmd, actionLogs);
case "measures":
return handleMeasuresStep(currentLog, cmd, actionLogs);
case "gas":
return handleGasDetectionStep(currentLog, cmd, actionLogs);
default:
log.warn("未知的特殊步骤类型: {}", specialStepCode);
return true;
}
}
/**
*
*
* @param log
* @param cmd
* @param actionLogs
* @return
*
*
*/
private boolean handleSpecialStep(TaskLogE log, TaskLogNextCmd cmd, List<TaskLogDO> actionLogs) {
if ("delay".equals(cmd.getSpecialStepCode())) { // 延时监火转交时, 完成时SpecialStepCode为null走正常下一步
private boolean handleDelayStep(TaskLogE currentLog, TaskLogNextCmd cmd, List<TaskLogDO> actionLogs) {
log.info("处理延时监火转交");
// 保存延时监火信息到 eightwork_supplementary_info 表
EightworkSupplementaryInfoE supplementaryInfo = new EightworkSupplementaryInfoE();
supplementaryInfo.setTaskLogId(currentLog.getTaskLogId());
supplementaryInfo.setWorkId(currentLog.getWorkId());
supplementaryInfo.setType("delay");
supplementaryInfo.setDetails(cmd.getOthers());
eightworkSupplementaryInfoGateway.add(supplementaryInfo);
// 保存下一步转交人记录
TaskLogE newDelayStep = new TaskLogE(log);
TaskLogE newDelayStep = new TaskLogE(currentLog);
TaskLogDO nextLogDO = new TaskLogDO();
BeanUtils.copyProperties(newDelayStep, nextLogDO);
nextLogDO.setActUserDepartment(cmd.getOthers().getLong("actUserDepartment"));
@ -208,29 +256,374 @@ public class TaskLogUpdateExe {
taskLogRepository.save(nextLogDO);
// 修改当前步骤状态为已完成
log.setStatus(1);
TaskLogDO currentLog = new TaskLogDO();
BeanUtils.copyProperties(log, currentLog);
actionLogs.add(currentLog);
currentLog.setStatus(TaskLogStatus.APPROVED.getCode());
actionLogs.add(TaskLogConvertUtil.toDO(currentLog));
// 延时转交步骤不自动流转下一步
return false;
}else if("measures".equals(cmd.getSpecialStepCode())){
List<MeasuresLogsE> list = new ArrayList<>();
}
/**
*
*
*/
private boolean handleMeasuresStep(TaskLogE currentLog, TaskLogNextCmd cmd, List<TaskLogDO> actionLogs) {
log.info("处理安全措施确认");
List<MeasuresLogsE> measuresList = new ArrayList<>();
JSONArray array = cmd.getOthers().getJSONArray("measures");
if (array != null) {
for (int i = 0; i < array.size(); i++) {
MeasuresLogsE cmdItem = JSONUtil.toBean(array.getJSONObject(i).toJSONString(), MeasuresLogsE.class);
list.add(cmdItem);
MeasuresLogsE item = JSONUtil.toBean(array.getJSONObject(i).toJSONString(), MeasuresLogsE.class);
measuresList.add(item);
}
}
measuresLogsRepository.saveBatch(list.stream().map(item -> {
measuresLogsRepository.saveBatch(measuresList.stream().map(item -> {
MeasuresLogsDO d = new MeasuresLogsDO();
BeanUtils.copyProperties(item, d, "id");
d.setType(1);
d.setType(MAIN_MEASURE_TYPE);
return d;
}).collect(Collectors.toList()));
return true;
}
return true;
/**
*
*
*/
private boolean handleGasDetectionStep(TaskLogE currentLog, TaskLogNextCmd cmd, List<TaskLogDO> actionLogs) {
log.info("处理气体检测记录");
// 保存气体检测信息到 eightwork_supplementary_info 表
EightworkSupplementaryInfoE supplementaryInfo = new EightworkSupplementaryInfoE();
supplementaryInfo.setTaskLogId(currentLog.getTaskLogId());
supplementaryInfo.setWorkId(currentLog.getWorkId());
supplementaryInfo.setType("gas");
supplementaryInfo.setDetails(cmd.getOthers());
eightworkSupplementaryInfoGateway.add(supplementaryInfo);
// 更新持续步骤的填写次数
Integer currentTimes = currentLog.getCurrentFillTimes();
if (currentTimes == null) {
currentTimes = 0;
}
currentLog.setCurrentFillTimes(currentTimes + 1);
actionLogs.add(TaskLogConvertUtil.toDO(currentLog));
log.info("气体检测记录已保存,当前填写次数: {}", currentTimes + 1);
// 气体检测步骤不流转,保持活跃状态
return false;
}
/**
*
* steps.measuresStepFlag == 1
*/
private void handleOtherMeasuresIfNeeded(TaskLogE currentLog, TaskLogNextCmd cmd) {
if (MEASURES_STEP_FLAG.equals(currentLog.getMeasuresStepFlag())) {
String otherMeasures = cmd.getOthers() != null ? cmd.getOthers().getString("otherMeasures") : null;
if (StringUtils.isNotBlank(otherMeasures)) {
MeasuresLogsDO measuresLogsDO = new MeasuresLogsDO(
otherMeasures,
currentLog.getWorkId(),
currentLog.getWorkType()
);
measuresLogsRepository.save(measuresLogsDO);
log.info("已添加其他安全措施");
}
}
}
/**
*
*
*/
private void proceedToNextStep(TaskLogE currentLog, List<TaskLogDO> actionLogs, List<TaskLogE> allLogs) {
List<TaskLogE> nextSteps = findNextSteps(currentLog, allLogs);
if (CollectionUtil.isEmpty(nextSteps)) {
// 没有下一步,流程结束
completeWorkflow(currentLog);
return;
}
TaskLogE nextStep = nextSteps.get(0);
// 判断下一步是否为跳过状态
if (TaskLogStatus.SKIPPED.equalsCode(nextStep.getStatus())) {
log.info("下一步为跳过步骤,继续递归: {}", nextStep.getStepName());
proceedToNextStep(nextStep, actionLogs, allLogs);
return;
}
// 判断下一步是否为合并节点(需要等待所有前置步骤都完成)
if (isMergeNode(nextStep)) {
if (!areAllBranchesCompleted(nextStep, allLogs)) {
List<TaskLogE> pendingSteps = getPendingBranches(nextStep, allLogs);
log.info("合并节点等待其他前置步骤完成: mergeNode={}, waitingSteps={}",
nextStep.getStepName(),
pendingSteps.stream()
.map(TaskLogE::getStepName)
.collect(java.util.stream.Collectors.joining(", ")));
// 不激活合并节点,等待其他前置步骤完成
return;
}
log.info("所有前置步骤已完成,激活合并节点: {}", nextStep.getStepName());
}
// 判断下一步是否被持续步骤阻塞(如气体检测必须填写指定次数)
if (isBlockedByOngoingStep(nextStep, allLogs)) {
TaskLogE blockingStep = findBlockingStep(nextStep, allLogs);
log.info("步骤被持续步骤阻塞: step={}, blockingStep={}, currentTimes={}, requiredTimes={}",
nextStep.getStepName(),
blockingStep != null ? blockingStep.getStepName() : "未知",
blockingStep != null ? blockingStep.getCurrentFillTimes() : 0,
blockingStep != null ? blockingStep.getMinFillTimes() : 0);
// 不激活步骤,等待持续步骤填写足够次数
return;
}
// 激活下一步
activateNextSteps(nextSteps, actionLogs, currentLog);
}
/**
*
*/
private boolean isMergeNode(TaskLogE step) {
BranchFlag branchFlag = BranchFlag.getByCode(step.getBranchFlag());
return branchFlag.isBranchEnd();
}
/**
*
*
*
* @param mergeNode
* @param allLogs
* @return true-false-
*/
private boolean areAllBranchesCompleted(TaskLogE mergeNode, List<TaskLogE> allLogs) {
List<TaskLogE> pendingSteps = getPendingBranches(mergeNode, allLogs);
return pendingSteps.isEmpty();
}
/**
*
*
*
* @param mergeNode
* @param allLogs
* @return
*/
private List<TaskLogE> getPendingBranches(TaskLogE mergeNode, List<TaskLogE> allLogs) {
List<TaskLogE> pendingSteps = new ArrayList<>();
for (TaskLogE log : allLogs) {
// 找出所有指向该合并节点的步骤(通过 nextStep 判断)
// 这样可以同时检查主流程和分支步骤
if (mergeNode.getStepId().equals(log.getNextStep())) {
// 检查是否已完成
if (!TaskLogStatus.APPROVED.equalsCode(log.getStatus())) {
pendingSteps.add(log);
}
}
}
return pendingSteps;
}
/**
*
*
*/
private boolean isBlockedByOngoingStep(TaskLogE step, List<TaskLogE> allLogs) {
// 找出阻塞当前步骤的持续步骤
TaskLogE blockingStep = findBlockingStep(step, allLogs);
if (blockingStep == null) {
return false;
}
// 检查填写次数是否满足要求
Integer currentTimes = blockingStep.getCurrentFillTimes();
Integer requiredTimes = blockingStep.getMinFillTimes();
return currentTimes == null || currentTimes < requiredTimes;
}
/**
*
*/
private TaskLogE findBlockingStep(TaskLogE step, List<TaskLogE> allLogs) {
for (TaskLogE log : allLogs) {
// 找出持续步骤且其阻塞的步骤ID等于当前步骤ID
if (Integer.valueOf(1).equals(log.getOngoingFlag())
&& step.getStepId().equals(log.getBlockingStepId())) {
return log;
}
}
return null;
}
/**
*
*/
private List<TaskLogE> findNextSteps(TaskLogE currentLog, List<TaskLogE> allLogs) {
return allLogs.stream()
.filter(log -> log.getStepId().equals(currentLog.getNextStep()))
.collect(Collectors.toList());
}
/**
*
* -
* -
* -
*/
private void activateNextSteps(List<TaskLogE> nextSteps, List<TaskLogDO> actionLogs, TaskLogE currentLog) {
Long workId = getWorkId(currentLog.getWorkId());
for (TaskLogE next : nextSteps) {
next.setStatus(TaskLogStatus.IN_PROGRESS.getCode());
actionLogs.add(TaskLogConvertUtil.toDO(next));
// 发送待办通知
sendTodoAddEvent(workId, next, currentLog.getWorkType());
log.info("已激活下一步: {}", next.getStepName());
}
// 更新作业当前步骤
eightworkInfoRepository.updateWorkStatus(
currentLog.getWorkId(),
nextSteps.get(0).getStepName(),
null
);
}
/**
*
*
*/
private void completeWorkflow(TaskLogE currentLog) {
log.info("工作流已完成,开始归档: workId={}", currentLog.getWorkId());
eightworkInfoRepository.updateWorkStatus(
currentLog.getWorkId(),
"已归档",
TaskLogStatus.ARCHIVED.getCode()
);
}
/**
*
*
*/
private void handleBranchIfNeeded(TaskLogE currentLog, List<TaskLogDO> actionLogs, List<TaskLogE> allLogs) {
StepType stepType = StepType.getByCode(currentLog.getStepType());
BranchFlag branchFlag = BranchFlag.getByCode(currentLog.getBranchFlag());
// 只处理:主流程步骤完成,且为分支开始节点 → 激活分支步骤
if (stepType != null && stepType.isNormalStep() && branchFlag.isBranchStart()) {
TaskLogE branchStep = allLogs.stream()
.filter(log -> log.getStepId().equals(currentLog.getBranchStep()))
.findFirst()
.orElse(null);
if (branchStep != null) {
branchStep.setStatus(TaskLogStatus.IN_PROGRESS.getCode());
actionLogs.add(TaskLogConvertUtil.toDO(branchStep));
sendTodoAddEvent(getWorkId(currentLog.getWorkId()), branchStep, currentLog.getWorkType());
log.info("已激活分支步骤: stepName={}, mergeTo={}", branchStep.getStepName(), branchStep.getBranchMergeStep());
}
}
}
/**
*
*
*/
private void handleSignStepsIfNeeded(TaskLogE currentLog, TaskLogNextCmd cmd,
List<TaskLogDO> actionLogs, List<TaskLogE> allLogs) {
List<TaskSignStepInfoCmd> signLogs = cmd.getSignLogs();
if (CollectionUtil.isEmpty(signLogs)) {
return;
}
for (TaskSignStepInfoCmd signInfo : signLogs) {
TaskLogE signStepLog = allLogs.stream()
.filter(log -> log.getStepId().equals(signInfo.getStepId()))
.findFirst()
.orElse(null);
if (signStepLog == null) {
continue;
}
// 检查是否需要跳过
if (CAN_SKIP_FLAG.equals(currentLog.getCanSkip()) && signInfo.getActUser() == null) {
// 设置为跳过状态
signStepLog.setStatus(TaskLogStatus.SKIPPED.getCode());
actionLogs.add(TaskLogConvertUtil.toDO(signStepLog));
log.info("步骤设置为跳过: {}", signStepLog.getStepName());
} else {
// 设置签字人
signStepLog.setSign(
signInfo.getActorField(),
signInfo.getActUserDepartment(),
signInfo.getActUserDepartmentName(),
signInfo.getActUser(),
signInfo.getActUserName()
);
actionLogs.add(TaskLogConvertUtil.toDO(signStepLog));
log.info("已设置签字人: step={}, user={}", signStepLog.getStepName(), signInfo.getActUserName());
}
}
}
/**
*
*/
private void sendTodoCompleteEvent(Long taskLogId) {
try {
TodoListCompleteEvent event = new TodoListCompleteEvent();
event.setForeignSubsidiaryKey(taskLogId);
todoListEventPusherUtil.sendMessageCompleteEvent(event);
} catch (Exception e) {
log.error("发送待办完成事件失败: taskLogId={}", taskLogId, e);
}
}
/**
*
*/
private void sendTodoAddEvent(Long workId, TaskLogE nextStep, String workType) {
try {
TodoListAddEvent event = new TodoListAddEvent();
event.setTitle("您有一条" + WorkCodeEnum.getNameByWorkType(workType) + "流程待处理");
event.setContent(nextStep.getNextStepName());
event.setForeignKey(workId);
event.setForeignSubsidiaryKey(nextStep.getId());
event.setReceiveUser(nextStep.getActUser());
event.setPcFlag(PC_FLAG);
event.setAppFlag(APP_FLAG);
event.setOtherParams(new JSONObject());
todoListEventPusherUtil.sendMessageAddEvent(event);
} catch (Exception e) {
log.error("发送待办新增事件失败: stepId={}", nextStep.getId(), e);
}
}
/**
* ID
*/
private Long getWorkId(String workId) {
return eightworkInfoRepository.getOne(
new LambdaQueryWrapper<EightworkInfoDO>()
.select(EightworkInfoDO::getId)
.eq(EightworkInfoDO::getWorkId, workId)
).getId();
}
}

View File

@ -0,0 +1,38 @@
package com.zcloud.eightwork.command.convertor;
import com.zcloud.eightwork.domain.model.TaskLogE;
import com.zcloud.eightwork.persistence.dataobject.TaskLogDO;
import org.springframework.beans.BeanUtils;
/**
* TaskLog
*
* @author fangjiakai
* @date 2026-03-12
*/
public class TaskLogConvertUtil {
/**
* TaskLogE TaskLogDO
*/
public static TaskLogDO toDO(TaskLogE log) {
if (log == null) {
return null;
}
TaskLogDO logDO = new TaskLogDO();
BeanUtils.copyProperties(log, logDO);
return logDO;
}
/**
* TaskLogE TaskLogDO
*/
public static java.util.List<TaskLogDO> toDOList(java.util.List<TaskLogE> logs) {
if (logs == null) {
return new java.util.ArrayList<>();
}
return logs.stream()
.map(TaskLogConvertUtil::toDO)
.collect(java.util.stream.Collectors.toList());
}
}

View File

@ -34,6 +34,11 @@ import java.util.stream.Collectors;
@Component
@AllArgsConstructor
public class TaskFlowQueryExe {
/** 第一步申请步骤的步骤ID */
private static final Long FIRST_STEP_ID = 1L;
/** 需要选择签字人的步骤标识 */
private static final Integer NEED_SELECT_SIGN = 1;
private final TaskFlowRepository taskFlowRepository;
private final TaskFlowCoConvertor taskFlowCoConvertor;
private final EightworkTaskRepository eightworkTaskRepository;
@ -69,7 +74,7 @@ public class TaskFlowQueryExe {
TaskFlowInitCO taskFlowInitCO = new TaskFlowInitCO();
taskFlowInitCO.setSettingSignSteps(taskFlowCoConvertor.converDOsToCOs(
flows.stream()
.filter(flow -> flow.getSelectSignStep() != null && 1 == flow.getSelectSignStep())
.filter(flow -> flow.getSelectSignStep() != null && NEED_SELECT_SIGN.equals(flow.getSelectSignStep()))
.collect(Collectors.toList())
));
@ -81,10 +86,10 @@ public class TaskFlowQueryExe {
List<Long> taskIds = taskDOs.stream().map(EightworkTaskDO::getId).collect(Collectors.toList());
List<TaskFlowDO> flows = taskFlowRepository.list(new QueryWrapper<TaskFlowDO>()
.select("DISTINCT step_id")
.select("DISTINCT step_id as step_id")
.select("step_name")
.in("task_id", taskIds)
.ne("step_id", 1)
.ne("step_id", FIRST_STEP_ID)
.orderByAsc("step_order"));
return taskFlowCoConvertor.converDOsToCOs(flows);

View File

@ -5,6 +5,7 @@ import com.zcloud.eightwork.command.TaskLogAddExe;
import com.zcloud.eightwork.command.TaskLogRemoveExe;
import com.zcloud.eightwork.command.TaskLogUpdateExe;
import com.zcloud.eightwork.command.query.TaskLogQueryExe;
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
import com.zcloud.eightwork.dto.TaskLogAddCmd;
import com.zcloud.eightwork.dto.TaskLogNextCmd;
import com.zcloud.eightwork.dto.TaskLogPageQry;
@ -54,7 +55,7 @@ public class TaskLogServiceImpl implements TaskLogServiceI {
TaskLogNextCmd taskLogNextCmd = new TaskLogNextCmd(commitTaskLogDO.getId(),
commitTaskLogDO.getWorkId(),
commitTaskLogDO.getStepId(),
1,null,null,null,null);
TaskLogStatus.APPROVED.getCode(),null,null,null,null);
taskLogUpdateExe.nextStep(taskLogNextCmd);
return SingleResponse.buildSuccess();

View File

@ -74,4 +74,13 @@ public class TaskFlowCO extends ClientObject {
//can_skip == 1 跳过条件 示例 age == 20
@ApiModelProperty(value = "can_skip == 1 跳过条件 示例 age == 20")
private String skipCondition;
//是否持续步骤1是如气体检测在整个流程期间都活跃
@ApiModelProperty(value = "是否持续步骤1是如气体检测在整个流程期间都活跃")
private Integer ongoingFlag;
//持续步骤最少填写次数
@ApiModelProperty(value = "持续步骤最少填写次数")
private Integer minFillTimes;
//持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤
@ApiModelProperty(value = "持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤")
private Long blockingStepId;
}

View File

@ -118,6 +118,18 @@ public class TaskLogCO extends ClientObject {
//can_skip == 1 跳过条件 示例 age == 20
@ApiModelProperty(value = "can_skip == 1 跳过条件 示例 age == 20")
private String skipCondition;
//是否持续步骤1是如气体检测在整个流程期间都活跃
@ApiModelProperty(value = "是否持续步骤1是如气体检测在整个流程期间都活跃")
private Integer ongoingFlag;
//持续步骤最少填写次数
@ApiModelProperty(value = "持续步骤最少填写次数")
private Integer minFillTimes;
//持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤
@ApiModelProperty(value = "持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤")
private Long blockingStepId;
//持续步骤当前填写次数
@ApiModelProperty(value = "持续步骤当前填写次数")
private Integer currentFillTimes;
@ApiModelProperty(value = "当前步骤需设置的签字人")
List<TaskLogCO> settingSignSteps;

View File

@ -46,15 +46,21 @@ public class TaskFlowE extends BaseE {
private Integer measuresStepFlag;
//0无分支1有分支开始2有分支结束
private Integer branchFlag;
//branch_flag == 1 分支节点
private Integer branchStep;
//step_type == 2 分支节点合并节点
private Integer branchMergeStep;
//branch_flag == 1 分支节点ID
private Long branchStep;
//step_type == 2 分支节点合并节点ID
private Long branchMergeStep;
//分支排序 示例10-1-5
private Integer stepOrder;
//是否可跳过1是
private Integer canSkip;
//can_skip == 1 跳过条件 示例 age == 20
private String skipCondition;
//是否持续步骤1是如气体检测在整个流程期间都活跃
private Integer ongoingFlag;
//持续步骤最少填写次数
private Integer minFillTimes;
//持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤
private Long blockingStepId;
}

View File

@ -71,16 +71,24 @@ public class TaskLogE extends BaseE {
private Integer measuresStepFlag;
//0无分支1有分支开始2有分支结束
private Integer branchFlag;
//branch_flag == 1 分支节点
private Integer branchStep;
//step_type == 2 分支节点合并节点
private Integer branchMergeStep;
//branch_flag == 1 分支节点ID
private Long branchStep;
//step_type == 2 分支节点合并节点ID
private Long branchMergeStep;
//分支排序 示例10-1-5
private Integer stepOrder;
//是否可跳过1是
private Integer canSkip;
//can_skip == 1 跳过条件 示例 age == 20
private String skipCondition;
//是否持续步骤1是如气体检测在整个流程期间都活跃
private Integer ongoingFlag;
//持续步骤最少填写次数
private Integer minFillTimes;
//持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤
private Long blockingStepId;
//持续步骤当前填写次数
private Integer currentFillTimes;
public TaskLogE(TaskLogE log) {
this.taskLogId = log.getTaskLogId();
@ -110,6 +118,10 @@ public class TaskLogE extends BaseE {
this.stepOrder = log.getStepOrder();
this.canSkip = log.getCanSkip();
this.skipCondition = log.getSkipCondition();
this.ongoingFlag = log.getOngoingFlag();
this.minFillTimes = log.getMinFillTimes();
this.blockingStepId = log.getBlockingStepId();
this.currentFillTimes = log.getCurrentFillTimes();
}

View File

@ -0,0 +1,64 @@
package com.zcloud.eightwork.domain.model.enums;
import lombok.Getter;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
*
* @author fangjiakai
* @date 2026-03-12
*/
@Getter
public enum BranchFlag {
NONE(0, "无分支"),
BRANCH_START(1, "有分支开始"),
BRANCH_END(2, "有分支结束");
private final Integer code;
private final String desc;
private static final Map<Integer, BranchFlag> CODE_MAP =
Arrays.stream(values())
.collect(Collectors.toMap(BranchFlag::getCode, Function.identity()));
BranchFlag(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
*
*/
public static BranchFlag getByCode(Integer code) {
if (code == null) {
return NONE;
}
return CODE_MAP.getOrDefault(code, NONE);
}
/**
*
*/
public boolean isBranchStart() {
return this == BRANCH_START;
}
/**
*
*/
public boolean isBranchEnd() {
return this == BRANCH_END;
}
/**
*
*/
public boolean hasBranch() {
return this == BRANCH_START || this == BRANCH_END;
}
}

View File

@ -0,0 +1,56 @@
package com.zcloud.eightwork.domain.model.enums;
import lombok.Getter;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
*
* @author fangjiakai
* @date 2026-03-12
*/
@Getter
public enum StepType {
NORMAL(1, "正常步骤"),
BRANCH(2, "分支步骤");
private final Integer code;
private final String desc;
private static final Map<Integer, StepType> CODE_MAP =
Arrays.stream(values())
.collect(Collectors.toMap(StepType::getCode, Function.identity()));
StepType(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
*
*/
public static StepType getByCode(Integer code) {
if (code == null) {
return null;
}
return CODE_MAP.get(code);
}
/**
*
*/
public boolean isBranchStep() {
return this == BRANCH;
}
/**
*
*/
public boolean isNormalStep() {
return this == NORMAL;
}
}

View File

@ -0,0 +1,67 @@
package com.zcloud.eightwork.domain.model.enums;
import lombok.Getter;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
*
* @author fangjiakai
* @date 2026-03-12
*/
@Getter
public enum TaskLogStatus {
NOT_STARTED(-99, "未开始"),
IN_PROGRESS(0, "进行中"),
APPROVED(1, "通过"),
REJECTED(2, "打回"),
SKIPPED(-1, "已跳过"),
ARCHIVED(999, "已归档");
private final Integer code;
private final String desc;
private static final Map<Integer, TaskLogStatus> CODE_MAP =
Arrays.stream(values())
.collect(Collectors.toMap(TaskLogStatus::getCode, Function.identity()));
TaskLogStatus(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
*
*/
public static TaskLogStatus getByCode(Integer code) {
if (code == null) {
return null;
}
return CODE_MAP.get(code);
}
/**
*
*/
public boolean equalsCode(Integer code) {
return this.code != null && this.code.equals(code);
}
/**
*
*/
public boolean isFinished() {
return this == APPROVED || this == REJECTED;
}
/**
*
*/
public boolean canProceed() {
return this == APPROVED;
}
}

View File

@ -62,12 +62,12 @@ public class TaskFlowDO extends BaseDO {
//0无分支1有分支开始2有分支结束
@ApiModelProperty(value = "0无分支1有分支开始2有分支结束")
private Integer branchFlag;
//branch_flag == 1 分支节点
@ApiModelProperty(value = "branch_flag == 1 分支节点")
private Integer branchStep;
//step_type == 2 分支节点合并节点
@ApiModelProperty(value = "step_type == 2 分支节点合并节点")
private Integer branchMergeStep;
//branch_flag == 1 分支节点ID
@ApiModelProperty(value = "branch_flag == 1 分支节点ID")
private Long branchStep;
//step_type == 2 分支节点合并节点ID
@ApiModelProperty(value = "step_type == 2 分支节点合并节点ID")
private Long branchMergeStep;
//分支排序 示例10-1-5
@ApiModelProperty(value = "分支排序 示例10-1-5")
private Integer stepOrder;
@ -77,6 +77,15 @@ public class TaskFlowDO extends BaseDO {
//can_skip == 1 跳过条件 示例 age == 20
@ApiModelProperty(value = "can_skip == 1 跳过条件 示例 age == 20")
private String skipCondition;
//是否持续步骤1是如气体检测在整个流程期间都活跃
@ApiModelProperty(value = "是否持续步骤1是如气体检测在整个流程期间都活跃")
private Integer ongoingFlag;
//持续步骤最少填写次数
@ApiModelProperty(value = "持续步骤最少填写次数")
private Integer minFillTimes;
//持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤
@ApiModelProperty(value = "持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤")
private Long blockingStepId;
}

View File

@ -101,12 +101,12 @@ public class TaskLogDO extends BaseDO {
//0无分支1有分支开始2有分支结束
@ApiModelProperty(value = "0无分支1有分支开始2有分支结束")
private Integer branchFlag;
//branch_flag == 1 分支节点
@ApiModelProperty(value = "branch_flag == 1 分支节点")
private Integer branchStep;
//step_type == 2 分支节点合并节点
@ApiModelProperty(value = "step_type == 2 分支节点合并节点")
private Integer branchMergeStep;
//branch_flag == 1 分支节点ID
@ApiModelProperty(value = "branch_flag == 1 分支节点ID")
private Long branchStep;
//step_type == 2 分支节点合并节点ID
@ApiModelProperty(value = "step_type == 2 分支节点合并节点ID")
private Long branchMergeStep;
//分支排序 示例10-1-5
@ApiModelProperty(value = "分支排序 示例10-1-5")
private Integer stepOrder;
@ -116,6 +116,18 @@ public class TaskLogDO extends BaseDO {
//can_skip == 1 跳过条件 示例 age == 20
@ApiModelProperty(value = "can_skip == 1 跳过条件 示例 age == 20")
private String skipCondition;
//是否持续步骤1是如气体检测在整个流程期间都活跃
@ApiModelProperty(value = "是否持续步骤1是如气体检测在整个流程期间都活跃")
private Integer ongoingFlag;
//持续步骤最少填写次数
@ApiModelProperty(value = "持续步骤最少填写次数")
private Integer minFillTimes;
//持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤
@ApiModelProperty(value = "持续步骤阻塞的步骤ID必须填写足够次数后才能激活的步骤")
private Long blockingStepId;
//持续步骤当前填写次数
@ApiModelProperty(value = "持续步骤当前填写次数")
private Integer currentFillTimes;
public TaskLogDO(String taskLogId) {
this.taskLogId = taskLogId;

View File

@ -20,5 +20,7 @@ public interface TaskLogMapper extends BaseMapper<TaskLogDO> {
List<TodoCountE> getTodoCount(@Param("orgId") Long orgId,@Param("userId") Long userId);
List<TodoCountE> getTodoCountForWork(@Param("orgId") Long orgId,@Param("userId") Long userId,@Param("workType") String workType);
TaskLogDO getByWorkIdAndStepId(@Param("workId") String workId, @Param("stepId") Long stepId);
}

View File

@ -24,5 +24,7 @@ public interface TaskLogRepository extends BaseRepository<TaskLogDO> {
List<TodoCountE> getTodoCount(Long orgId, Long userId);
List<TodoCountE> getTodoCountForWork(Long orgId, Long userId, String workType);
TaskLogDO getByWorkIdAndStepId(String workId, Long stepId);
}

View File

@ -59,5 +59,10 @@ public class TaskLogRepositoryImpl extends BaseRepositoryImpl<TaskLogMapper, Tas
public List<TodoCountE> getTodoCountForWork(Long orgId, Long userId, String workType){
return taskLogMapper.getTodoCountForWork(orgId, userId, workType);
}
@Override
public TaskLogDO getByWorkIdAndStepId(String workId, Long stepId) {
return taskLogMapper.getByWorkIdAndStepId(workId, stepId);
}
}

View File

@ -25,5 +25,13 @@
or (act_user_department = #{orgId} and act_user is null))
group by step_id
</select>
<select id="getByWorkIdAndStepId" resultType="com.zcloud.eightwork.persistence.dataobject.TaskLogDO">
select *
from eightwork_task_log
where work_id = #{workId}
and step_id = #{stepId}
limit 1
</select>
</mapper>