diff --git a/web-adapter/src/main/java/com/zcloud/eightwork/web/TaskLogController.java b/web-adapter/src/main/java/com/zcloud/eightwork/web/TaskLogController.java index 618c8c6..5cfc42f 100644 --- a/web-adapter/src/main/java/com/zcloud/eightwork/web/TaskLogController.java +++ b/web-adapter/src/main/java/com/zcloud/eightwork/web/TaskLogController.java @@ -9,6 +9,7 @@ import com.zcloud.eightwork.dto.TaskLogPageQry; import com.zcloud.eightwork.dto.TaskLogUpdateCmd; import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO; import com.zcloud.eightwork.dto.clientobject.TaskLogCO; +import com.zcloud.eightwork.dto.clientobject.TaskFlowChartCO; import com.alibaba.cola.dto.MultiResponse; import com.alibaba.cola.dto.PageResponse; import com.alibaba.cola.dto.Response; @@ -113,5 +114,11 @@ public class TaskLogController { cmd.setDepartmentId(AuthContext.getOrgId()); return taskLogService.saveDraft(cmd); } + + @ApiOperation("获取工作流程图") + @GetMapping("/flowChart/{workId}") + public MultiResponse getFlowChart(@PathVariable("workId") String workId) { + return MultiResponse.of(taskLogService.getFlowChart(workId)); + } } diff --git a/web-app/src/main/java/com/zcloud/eightwork/command/EightworkInfoSaveDraftExe.java b/web-app/src/main/java/com/zcloud/eightwork/command/EightworkInfoSaveDraftExe.java new file mode 100644 index 0000000..14c350c --- /dev/null +++ b/web-app/src/main/java/com/zcloud/eightwork/command/EightworkInfoSaveDraftExe.java @@ -0,0 +1,255 @@ +package com.zcloud.eightwork.command; + +import cn.hutool.core.date.DatePattern; +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.jjb.saas.framework.auth.utils.AuthContext; +import com.zcloud.eightwork.domain.gateway.TaskFlowGateway; +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.EightworkInfoSaveDraftCmd; +import com.zcloud.eightwork.dto.TaskSignStepInfoCmd; +import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO; +import com.zcloud.eightwork.persistence.dataobject.TaskLogDO; +import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository; +import com.zcloud.eightwork.persistence.repository.TaskLogRepository; +import com.zcloud.gbscommon.utils.Tools; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +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.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 八险作业暂存执行器 + * 负责保存/更新作业草稿 + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +@Slf4j +@Component +@AllArgsConstructor +public class EightworkInfoSaveDraftExe { + /** 第一步(申请步骤)的步骤ID */ + private static final Long FIRST_STEP_ID = 1L; + /** 暂存状态 */ + private static final Integer DRAFT_STATUS = 0; + /** 进行中状态 */ + private static final Integer IN_PROGRESS_STATUS = 1; + + private final TaskFlowGateway taskFlowGateway; + private final EightworkInfoRepository eightworkInfoRepository; + private final TaskLogRepository taskLogRepository; + + @Transactional(rollbackFor = Exception.class) + public void execute(EightworkInfoSaveDraftCmd cmd) { + log.info("开始暂存作业: id={}, workType={}, workLevel={}", + cmd.getId(), cmd.getWorkType(), cmd.getWorkLevel()); + + try { + if (cmd.getId() != null) { + // 更新现有暂存 + updateDraft(cmd); + } else { + // 创建新暂存 + createDraft(cmd); + } + + log.info("作业暂存成功: workType={}", cmd.getWorkType()); + } catch (Exception e) { + log.error("暂存作业失败: workType={}", cmd.getWorkType(), e); + throw new BizException("暂存失败: " + e.getMessage()); + } + } + + /** + * 更新现有暂存 + */ + private void updateDraft(EightworkInfoSaveDraftCmd cmd) { + log.info("更新现有暂存: id={}", cmd.getId()); + + // 1. 查询现有记录 + EightworkInfoDO existingInfo = eightworkInfoRepository.getById(cmd.getId()); + if (existingInfo == null) { + throw new BizException("暂存记录不存在"); + } + + // 2. 检查状态,只能修改暂存状态的记录 + if (!DRAFT_STATUS.equals(existingInfo.getStatus())) { + throw new BizException("只能修改暂存状态的记录"); + } + + // 3. 更新主表信息 + updateMainInfo(existingInfo, cmd); + eightworkInfoRepository.updateById(existingInfo); + + // 4. 删除旧的 task_log 记录 + taskLogRepository.remove(new LambdaQueryWrapper() + .eq(TaskLogDO::getWorkId, existingInfo.getWorkId())); + + // 5. 创建申请步骤 task_log + TaskLogDO taskLog = createApplyTaskLog(existingInfo.getWorkId(), cmd); + taskLogRepository.save(taskLog); + + // 6. 更新主表 info 中的预设签字人信息 + updateInfoWithSigners(existingInfo.getWorkId(), cmd.getSignLogs()); + + log.info("暂存更新成功: workId={}", existingInfo.getWorkId()); + } + + /** + * 创建新暂存 + */ + private void createDraft(EightworkInfoSaveDraftCmd cmd) { + log.info("创建新暂存: workType={}", cmd.getWorkType()); + + // 1. 创建主表记录(暂存不生成票号) + EightworkInfoDO eightworkInfo = new EightworkInfoDO(); + eightworkInfo.setWorkId(Tools.get32UUID()); + eightworkInfo.setWorkType(cmd.getWorkType()); + eightworkInfo.setWorkLevel(cmd.getWorkLevel()); + eightworkInfo.setCorpinfoId(cmd.getCorpinfoId()); + eightworkInfo.setXgfFlag(cmd.getXgfFlag()); + eightworkInfo.setInternalOperationFlag(cmd.getInternalOperationFlag()); + eightworkInfo.setProjectId(cmd.getProjectId()); + eightworkInfo.setXgfId(cmd.getXgfId()); + eightworkInfo.setGasFlag(cmd.getGasFlag()); + eightworkInfo.setCheckNo(null); // 暂存不生成票号 + eightworkInfo.setStatus(DRAFT_STATUS); + eightworkInfo.setInfo(cmd.getInfo()); + eightworkInfo.setDepartmentId(cmd.getDepartmentId()); + + eightworkInfoRepository.save(eightworkInfo); + log.info("主表创建成功: workId={}", eightworkInfo.getWorkId()); + + // 2. 创建申请步骤 task_log + TaskLogDO taskLog = createApplyTaskLog(eightworkInfo.getWorkId(), cmd); + taskLogRepository.save(taskLog); + + // 3. 更新主表 info 中的预设签字人信息 + updateInfoWithSigners(eightworkInfo.getWorkId(), cmd.getSignLogs()); + + log.info("暂存创建成功: workId={}", eightworkInfo.getWorkId()); + } + + /** + * 创建申请步骤 task_log + */ + private TaskLogDO createApplyTaskLog(String workId, EightworkInfoSaveDraftCmd cmd) { + // 获取流程配置 + List flows = taskFlowGateway.listAllByWorkType(cmd.getWorkType(), cmd.getWorkLevel()); + TaskFlowE applyFlow = flows.stream() + .filter(f -> FIRST_STEP_ID.equals(f.getStepId())) + .findFirst() + .orElseThrow(() -> new BizException("未找到申请步骤配置")); + + TaskLogDO taskLog = new TaskLogDO(Tools.get32UUID()); + BeanUtils.copyProperties(applyFlow, taskLog, "id"); + taskLog.setWorkId(workId); + taskLog.setWorkType(cmd.getWorkType()); + taskLog.setCorpinfoId(cmd.getCorpinfoId()); + taskLog.setCheckNo(""); // 暂存时票号为空,正式提交时生成 + + // 设置申请人为当前用户 + taskLog.setSign( + applyFlow.getActorField(), + AuthContext.getOrgId(), + AuthContext.getCurrentUser().getOrgName(), + AuthContext.getUserId(), + AuthContext.getName() + ); + + // 暂存时申请步骤状态为进行中 + taskLog.setStatus(IN_PROGRESS_STATUS); + + log.info("申请步骤 task_log 创建成功: stepName={}", applyFlow.getStepName()); + return taskLog; + } + + /** + * 更新主表信息 + */ + private void updateMainInfo(EightworkInfoDO existingInfo, EightworkInfoSaveDraftCmd cmd) { + existingInfo.setWorkType(cmd.getWorkType()); + existingInfo.setWorkLevel(cmd.getWorkLevel()); + existingInfo.setCorpinfoId(cmd.getCorpinfoId()); + existingInfo.setXgfFlag(cmd.getXgfFlag()); + existingInfo.setInternalOperationFlag(cmd.getInternalOperationFlag()); + existingInfo.setProjectId(cmd.getProjectId()); + existingInfo.setXgfId(cmd.getXgfId()); + existingInfo.setGasFlag(cmd.getGasFlag()); + existingInfo.setInfo(cmd.getInfo()); + existingInfo.setDepartmentId(cmd.getDepartmentId()); + } + + /** + * 更新主表 info 中的预设签字人信息 + */ + private void updateInfoWithSigners(String workId, List signLogs) { + if (signLogs == null || signLogs.isEmpty()) { + return; + } + + EightworkInfoDO infoDO = eightworkInfoRepository.getOne( + new LambdaQueryWrapper() + .eq(EightworkInfoDO::getWorkId, workId) + ); + + if (infoDO == null) { + log.warn("未找到作业信息: workId={}", workId); + return; + } + + // 解析现有 info + JSONObject infoJson; + if (StringUtils.isNotBlank(infoDO.getInfo())) { + try { + infoJson = JSONObject.parseObject(infoDO.getInfo()); + } catch (Exception e) { + log.warn("解析 info 失败,使用空对象: workId={}", workId, e); + infoJson = new JSONObject(); + } + } else { + infoJson = new JSONObject(); + } + + // 添加预设签字人信息到 info(格式同 updateEightworkInfo) + for (TaskSignStepInfoCmd signInfo : signLogs) { + JSONObject stepInfo = new JSONObject(); + stepInfo.put("stepName", getStepNameBySignInfo(signInfo)); + stepInfo.put("actUserDepartment", signInfo.getActUserDepartment()); + stepInfo.put("actUserDepartmentName", signInfo.getActUserDepartmentName()); + stepInfo.put("actUser", signInfo.getActUser()); + stepInfo.put("actUserName", signInfo.getActUserName()); + stepInfo.put("signTime", cn.hutool.core.date.DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN)); + stepInfo.put("status", TaskLogStatus.NOT_STARTED.getCode()); + + infoJson.put("step_" + signInfo.getStepId(), stepInfo); + } + + // 更新到数据库 + infoDO.setInfo(infoJson.toJSONString()); + eightworkInfoRepository.updateById(infoDO); + + log.info("预设签字人信息已保存: workId={}, count={}", workId, signLogs.size()); + } + + /** + * 从签字信息中获取步骤名称 + */ + private String getStepNameBySignInfo(TaskSignStepInfoCmd signInfo) { + // 这里可以通过 stepId 查询流程配置获取步骤名称 + // 暂时返回空,由前端或后续处理填充 + return ""; + } +} diff --git a/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogAddExe.java b/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogAddExe.java index cdfdb72..5eb50a2 100644 --- a/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogAddExe.java +++ b/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogAddExe.java @@ -1,6 +1,8 @@ package com.zcloud.eightwork.command; import com.alibaba.cola.exception.BizException; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.jjb.saas.framework.auth.utils.AuthContext; import com.zcloud.eightwork.domain.gateway.TaskFlowGateway; import com.zcloud.eightwork.domain.gateway.TaskLogGateway; @@ -86,32 +88,49 @@ public class TaskLogAddExe { throw new BizException("暂存记录不存在"); } - // 2. 检查状态 - if (!TaskLogStatus.NOT_STARTED.getCode().equals(existingInfo.getStatus())) { - throw new BizException("只能从暂存状态转为正式提交"); + // 2. 检查状态,暂存(0)或打回(2)都可以转正式提交 + if (!TaskLogStatus.NOT_STARTED.getCode().equals(existingInfo.getStatus()) && + !TaskLogStatus.REJECTED.equalsCode(existingInfo.getStatus())) { + throw new BizException("只能从暂存状态或打回状态转为正式提交"); } - // 3. 删除暂存的 task_log + // 3. 处理打回历史:将 rejectInfo 转为 rejectHistory + String processedInfo = processRejectHistory(existingInfo.getInfo(), cmd.getInfo()); + + // 4. 删除暂存的 task_log taskLogRepository.remove(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() .eq(TaskLogDO::getWorkId, existingInfo.getWorkId())); - // 4. 生成正式票号并更新主表 - String formalCheckNo = generateFormalCheckNo(cmd.getWorkType()); - existingInfo.setCheckNo(formalCheckNo); + // 5. 判断是否已有票号,没有则生成新票号 + String checkNo = existingInfo.getCheckNo(); + if (org.apache.commons.lang.StringUtils.isBlank(checkNo)) { + // 暂存后第一次正式提交,生成新票号 + checkNo = generateFormalCheckNo(cmd.getWorkType()); + existingInfo.setCheckNo(checkNo); + log.info("暂存转正式(生成新票号): workId={}, checkNo={}", existingInfo.getWorkId(), checkNo); + } else { + // 打回后重新提交,保持原票号 + log.info("暂存转正式(保持原票号): workId={}, checkNo={}", existingInfo.getWorkId(), checkNo); + } + existingInfo.setStatus(TaskLogStatus.IN_PROGRESS.getCode()); + existingInfo.setInfo(processedInfo); // 设置处理后的 info(包含 rejectHistory) eightworkInfoRepository.updateById(existingInfo); - log.info("暂存转正式: workId={}, checkNo={}", existingInfo.getWorkId(), formalCheckNo); - - // 5. 获取流程配置 + // 6. 获取流程配置 List flows = taskFlowGateway.listAllByWorkType(cmd.getWorkType(), cmd.getWorkLevel()); - // 6. 生成所有步骤 task_log + // 7. 生成所有步骤 task_log List taskLogs = flows.stream() .map(flow -> createTaskLog(flow, existingInfo.getWorkId(), cmd)) .collect(Collectors.toList()); - // 7. 批量保存 + // 8. 设置所有步骤的 checkNo(使用主表的票号) + for (TaskLogDO taskLog : taskLogs) { + taskLog.setCheckNo(checkNo); + } + + // 9. 批量保存 taskLogRepository.saveBatch(taskLogs); log.info("作业流程创建成功(从暂存): workId={}, stepCount={}", existingInfo.getWorkId(), taskLogs.size()); @@ -128,6 +147,12 @@ public class TaskLogAddExe { String workId = saveWork(cmd); log.info("作业信息已创建: workId={}", workId); + // 获取票号 + String checkNo = eightworkInfoRepository.getOne( + new LambdaQueryWrapper() + .eq(EightworkInfoDO::getWorkId, workId) + ).getCheckNo(); + // 2. 获取流程配置 List flows = taskFlowGateway.listAllByWorkType(cmd.getWorkType(), cmd.getWorkLevel()); log.info("获取到 {} 个流程步骤", flows.size()); @@ -135,7 +160,12 @@ public class TaskLogAddExe { // 3. 生成任务日志 List taskLogs = flows.stream().map(flow -> createTaskLog(flow, workId, cmd)).collect(Collectors.toList()); - // 4. 批量保存 + // 4. 设置所有步骤的 checkNo + for (TaskLogDO taskLog : taskLogs) { + taskLog.setCheckNo(checkNo); + } + + // 5. 批量保存 taskLogRepository.saveBatch(taskLogs); log.info("作业流程创建成功: workId={}, stepCount={}", workId, taskLogs.size()); @@ -264,6 +294,59 @@ public class TaskLogAddExe { return eightworkInfo.getWorkId(); } + /** + * 处理打回历史 + * 将旧的 rejectInfo 转换为 rejectHistory,并与新的 info 合并 + * + * @param oldInfo 旧的 info JSON 字符串 + * @param newInfo 新的 info JSONObject + * @return 合并后的 info JSON 字符串 + */ + private String processRejectHistory(String oldInfo, com.alibaba.fastjson.JSONObject newInfo) { + // 解析旧 info + com.alibaba.fastjson.JSONObject oldJson; + if (org.apache.commons.lang.StringUtils.isNotBlank(oldInfo)) { + try { + oldJson = com.alibaba.fastjson.JSONObject.parseObject(oldInfo); + } catch (Exception e) { + log.warn("解析旧 info 失败", e); + oldJson = new com.alibaba.fastjson.JSONObject(); + } + } else { + oldJson = new com.alibaba.fastjson.JSONObject(); + } + + // 复制新 info + com.alibaba.fastjson.JSONObject mergedJson = new com.alibaba.fastjson.JSONObject(); + if (newInfo != null) { + mergedJson = new com.alibaba.fastjson.JSONObject(newInfo); + } + + // 检查是否有 rejectInfo 需要转为 rejectHistory + com.alibaba.fastjson.JSONArray rejectHistory = oldJson.getJSONArray("rejectHistory"); + com.alibaba.fastjson.JSONObject rejectInfo = oldJson.getJSONObject("rejectInfo"); + + if (rejectInfo != null) { + // 初始化 rejectHistory + if (rejectHistory == null) { + rejectHistory = new com.alibaba.fastjson.JSONArray(); + } + + // 将 rejectInfo 添加到 history + rejectHistory.add(rejectInfo); + + // 从旧 info 中移除 rejectInfo + oldJson.remove("rejectInfo"); + } + + // 将 rejectHistory 合并到新 info + if (rejectHistory != null && !rejectHistory.isEmpty()) { + mergedJson.put("rejectHistory", rejectHistory); + } + + return mergedJson.toJSONString(); + } + /** * 构建票号 Redis Key * 格式: eightwork:ticket:no:{作业类型代码}:{日期} diff --git a/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogUpdateExe.java b/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogUpdateExe.java index 91ed570..ce7a5d6 100644 --- a/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogUpdateExe.java +++ b/web-app/src/main/java/com/zcloud/eightwork/command/TaskLogUpdateExe.java @@ -3,16 +3,17 @@ package com.zcloud.eightwork.command; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; 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.gateway.TaskLogGateway; import com.zcloud.eightwork.domain.model.EightworkSupplementaryInfoE; +import com.zcloud.eightwork.domain.model.MeasuresLogsE; import com.zcloud.eightwork.domain.model.TaskLogE; import com.zcloud.eightwork.domain.model.enums.BranchFlag; import com.zcloud.eightwork.domain.model.enums.StepType; @@ -21,12 +22,8 @@ import com.zcloud.eightwork.domain.model.enums.WorkCodeEnum; import com.zcloud.eightwork.dto.TaskLogNextCmd; import com.zcloud.eightwork.dto.TaskLogUpdateCmd; import com.zcloud.eightwork.dto.TaskSignStepInfoCmd; -import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO; -import com.zcloud.eightwork.persistence.dataobject.MeasuresLogsDO; -import com.zcloud.eightwork.persistence.dataobject.TaskLogDO; -import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository; -import com.zcloud.eightwork.persistence.repository.MeasuresLogsRepository; -import com.zcloud.eightwork.persistence.repository.TaskLogRepository; +import com.zcloud.eightwork.persistence.dataobject.*; +import com.zcloud.eightwork.persistence.repository.*; import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil; import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent; import com.zcloud.gbscommon.todolistmq.event.TodoListCompleteEvent; @@ -40,7 +37,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; @@ -55,27 +51,56 @@ import java.util.stream.Collectors; @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端待办标识 */ + /** + * PC端待办标识 + */ private static final Integer PC_FLAG = 1; - /** APP端待办标识 */ + /** + * APP端待办标识 + */ private static final Integer APP_FLAG = 1; + /** + * 第一步(申请步骤)ID + */ + private static final Long FIRST_STEP_ID = 1L; + /** + * 暂存状态 + */ + private static final Integer DRAFT_STATUS = 0; + /** + * 打回状态 + */ + private static final Integer REJECTED_STATUS = 2; private final TaskLogGateway taskLogGateway; private final TaskLogRepository taskLogRepository; + private final TaskLogArchiveRepository taskLogArchiveRepository; private final MeasuresLogsRepository measuresLogsRepository; private final EightworkInfoRepository eightworkInfoRepository; private final TodoListEventPusherUtil todoListEventPusherUtil; private final EightworkSupplementaryInfoGateway eightworkSupplementaryInfoGateway; + private final EightworkSupplementaryInfoRepository eightworkSupplementaryInfoRepository; + private final EightworkSupplementaryInfoArchiveRepository eightworkSupplementaryInfoArchiveRepository; @Transactional(rollbackFor = Exception.class) public void execute(TaskLogUpdateCmd taskLogUpdateCmd) { @@ -99,7 +124,9 @@ public class TaskLogUpdateExe { * * @param cmd 步骤流转命令 */ - /** 强制终止状态码 */ + /** + * 强制终止状态码 + */ private static final Integer FORCE_TERMINATE_STATUS = 998; @Transactional(rollbackFor = Exception.class) @@ -113,6 +140,12 @@ public class TaskLogUpdateExe { return; } + // 打回检查:status为2时打回到申请步骤 + if (TaskLogStatus.REJECTED.equalsCode(cmd.getStatus())) { + handleReject(cmd); + return; + } + List logs = taskLogGateway.listAllByWorkId(cmd.getWorkId()); List actionLogs = new ArrayList<>(); @@ -135,25 +168,25 @@ public class TaskLogUpdateExe { // 2. 判断是否通过,通过才流转 if (TaskLogStatus.APPROVED.equalsCode(cmd.getStatus())) { - // 3. 判断是否可以流转到下一步 + // 3. 先设置后续签字人(在激活步骤之前设置,避免状态覆盖问题) + handleSignStepsIfNeeded(currentLog, cmd, actionLogs, logs); + + // 4. 判断是否可以流转到下一步 if (canProceedToNext(currentLog, logs, cmd)) { - // 4. 处理特殊步骤逻辑 + // 5. 处理特殊步骤逻辑 boolean shouldProceed = handleSpecialStepIfNeeded(currentLog, cmd, actionLogs); - // 5. 处理其他安全措施 + // 6. 处理其他安全措施 handleOtherMeasuresIfNeeded(currentLog, cmd); - // 6. 流转到下一步 + // 7. 流转到下一步 if (shouldProceed) { proceedToNextStep(currentLog, actionLogs, logs); } } - // 7. 处理分支流程 + // 8. 处理分支流程 handleBranchIfNeeded(currentLog, actionLogs, logs); - - // 8. 设置后续签字人 - handleSignStepsIfNeeded(currentLog, cmd, actionLogs, logs); } // 批量更新 task_log @@ -267,25 +300,30 @@ public class TaskLogUpdateExe { private boolean handleDelayStep(TaskLogE currentLog, TaskLogNextCmd cmd, List 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); + if (ObjectUtil.isNotEmpty(cmd.getOthers())) { + // 保存延时监火信息到 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(currentLog); - TaskLogDO nextLogDO = new TaskLogDO(); - BeanUtils.copyProperties(newDelayStep, nextLogDO); - nextLogDO.setActUserDepartment(cmd.getOthers().getLong("actUserDepartment")); - nextLogDO.setActUserDepartmentName(cmd.getOthers().getString("actUserDepartmentName")); - taskLogRepository.save(nextLogDO); + if (ObjectUtil.isNotEmpty(cmd.getSignLogs())) { + // 保存下一步转交人记录 + TaskLogE newDelayStep = new TaskLogE(currentLog); + TaskLogDO nextLogDO = new TaskLogDO(); + BeanUtils.copyProperties(newDelayStep, nextLogDO); + nextLogDO.setActUserDepartment(cmd.getSignLogs().get(0).getActUserDepartment()); + nextLogDO.setActUserDepartmentName(cmd.getSignLogs().get(0).getActUserDepartmentName()); + nextLogDO.setStatus(TaskLogStatus.IN_PROGRESS.getCode()); + taskLogRepository.save(nextLogDO); - // 修改当前步骤状态为已完成 - currentLog.setStatus(TaskLogStatus.APPROVED.getCode()); - addActionLog(actionLogs, currentLog); + // 修改当前步骤状态为已完成 + currentLog.setStatus(TaskLogStatus.APPROVED.getCode()); + addActionLog(actionLogs, currentLog); + } // 延时转交步骤不自动流转下一步 return false; @@ -393,6 +431,13 @@ public class TaskLogUpdateExe { * 递归处理,直到找到不需要跳过的步骤或流程结束 */ private void proceedToNextStep(TaskLogE currentLog, List actionLogs, List allLogs) { + // 检查下一步是否为归档状态(nextStep = 999) + if (TaskLogStatus.ARCHIVED.getCode().equals(currentLog.getNextStep())) { + log.info("下一步为归档状态,工作流完成: workId={}, nextStep={}", currentLog.getWorkId(), currentLog.getNextStep()); + completeWorkflow(currentLog); + return; + } + List nextSteps = findNextSteps(currentLog, allLogs); if (CollectionUtil.isEmpty(nextSteps)) { @@ -454,7 +499,7 @@ public class TaskLogUpdateExe { * 包括主流程和分支步骤,必须都完成才能激活合并节点 * * @param mergeNode 合并节点 - * @param allLogs 所有步骤日志 + * @param allLogs 所有步骤日志 * @return true-所有前置步骤都已完成,false-还有步骤未完成 */ private boolean areAllBranchesCompleted(TaskLogE mergeNode, List allLogs) { @@ -468,7 +513,7 @@ public class TaskLogUpdateExe { * SKIPPED 状态的步骤视为已完成 * * @param mergeNode 合并节点 - * @param allLogs 所有步骤日志 + * @param allLogs 所有步骤日志 * @return 未完成的步骤列表 */ private List getPendingBranches(TaskLogE mergeNode, List allLogs) { @@ -615,6 +660,173 @@ public class TaskLogUpdateExe { log.info("工作流已强制终止: workId={}, skippedSteps={}", cmd.getWorkId(), actionLogs.size() - 1); } + /** + * 处理打回工作流 + * status为2时打回到申请步骤,删除后续流程,允许修改后重新提交 + */ + private void handleReject(TaskLogNextCmd cmd) { + log.info("开始处理打回: workId={}, stepId={}", cmd.getWorkId(), cmd.getStepId()); + + List allLogs = taskLogGateway.listAllByWorkId(cmd.getWorkId()); + TaskLogE currentLog = findCurrentLog(allLogs, cmd.getId()); + + if (currentLog == null) { + throw new BizException("未找到对应的步骤记录"); + } + + // 1. 归档当前的 task_log 记录(除了申请步骤) + archiveTaskLogs(allLogs); + + // 2. 归档辅助数据(delay、gas、measures) + archiveSupplementaryInfo(cmd.getWorkId()); + + // 3. 删除除申请步骤外的所有 task_log + deleteTaskLogsExceptFirst(cmd.getWorkId()); + + // 4. 删除辅助数据(delay、gas、measures) + deleteSupplementaryInfo(cmd.getWorkId()); + + // 5. 更新主表状态为暂存,添加打回信息 + updateMainInfoForReject(cmd.getWorkId(), currentLog, cmd.getOthers()); + + // 6. 发送待办完成事件 + sendTodoCompleteEvent(currentLog.getId()); + + log.info("工作流已打回到申请步骤: workId={}", cmd.getWorkId()); + } + + /** + * 归档 task_log 记录到 task_log_archive 表 + */ + private void archiveTaskLogs(List allLogs) { + List archiveList = new ArrayList<>(); + + for (TaskLogE log : allLogs) { + // 跳过申请步骤(stepId=1) + if (FIRST_STEP_ID.equals(log.getStepId())) { + continue; + } + // 只归档已处理的记录(状态不是未开始) + if (!TaskLogStatus.NOT_STARTED.equalsCode(log.getStatus())) { + TaskLogArchiveDO archiveDO = new TaskLogArchiveDO(); + BeanUtils.copyProperties(log, archiveDO, "id"); + archiveList.add(archiveDO); + } + } + + if (!archiveList.isEmpty()) { + // 批量保存到归档表 + for (TaskLogArchiveDO archiveDO : archiveList) { + taskLogArchiveRepository.save(archiveDO); + } + log.info("已归档 {} 条 task_log 记录", archiveList.size()); + } + } + + /** + * 归档辅助数据到 eightwork_supplementary_info_archive 表 + */ + private void archiveSupplementaryInfo(String workId) { + List infoList = eightworkSupplementaryInfoRepository.list( + new LambdaQueryWrapper() + .eq(EightworkSupplementaryInfoDO::getWorkId, workId) + ); + + if (!infoList.isEmpty()) { + for (EightworkSupplementaryInfoDO infoDO : infoList) { + com.zcloud.eightwork.persistence.dataobject.EightworkSupplementaryInfoArchiveDO archiveDO = + new com.zcloud.eightwork.persistence.dataobject.EightworkSupplementaryInfoArchiveDO(); + BeanUtils.copyProperties(infoDO, archiveDO, "id"); + eightworkSupplementaryInfoArchiveRepository.save(archiveDO); + } + log.info("已归档 {} 条辅助数据记录", infoList.size()); + } + } + + /** + * 删除除申请步骤外的所有 task_log + */ + private void deleteTaskLogsExceptFirst(String workId) { + taskLogRepository.remove( + new LambdaQueryWrapper() + .eq(TaskLogDO::getWorkId, workId) + .ne(TaskLogDO::getStepId, FIRST_STEP_ID) + ); + log.info("已删除除申请步骤外的 task_log: workId={}", workId); + } + + /** + * 删除辅助数据(delay、gas、measures) + */ + private void deleteSupplementaryInfo(String workId) { + // 删除 eightwork_supplementary_info 中的记录 + eightworkSupplementaryInfoRepository.remove( + new LambdaQueryWrapper() + .eq(EightworkSupplementaryInfoDO::getWorkId, workId) + ); + log.info("已删除辅助数据: workId={}", workId); + + // 删除 measures_logs 中的记录(如果有的话) + measuresLogsRepository.remove( + new LambdaQueryWrapper() + .eq(MeasuresLogsDO::getWorkId, workId) + ); + log.info("已删除安全措施记录: workId={}", workId); + } + + /** + * 更新主表信息(打回后) + */ + private void updateMainInfoForReject(String workId, TaskLogE currentLog, com.alibaba.fastjson.JSONObject others) { + // 获取主表记录 + EightworkInfoDO infoDO = eightworkInfoRepository.getOne( + new LambdaQueryWrapper() + .eq(EightworkInfoDO::getWorkId, workId) + ); + + if (infoDO == null) { + log.warn("未找到作业信息: workId={}", workId); + return; + } + + // 解析现有 info + JSONObject infoJson; + if (StringUtils.isNotBlank(infoDO.getInfo())) { + try { + infoJson = JSONObject.parseObject(infoDO.getInfo()); + } catch (Exception e) { + log.warn("解析 info 失败,使用空对象: workId={}", workId, e); + infoJson = new JSONObject(); + } + } else { + infoJson = new JSONObject(); + } + + // 构建 rejectInfo + JSONObject rejectInfo = new JSONObject(); + rejectInfo.put("rejected", true); + rejectInfo.put("rejectStepId", currentLog.getStepId()); + rejectInfo.put("rejectStepName", currentLog.getStepName()); + rejectInfo.put("rejectTime", cn.hutool.core.date.DateUtil.format(new Date(), cn.hutool.core.date.DatePattern.NORM_DATETIME_PATTERN)); + rejectInfo.put("rejectUser", currentLog.getActUserName()); + rejectInfo.put("rejectUserId", currentLog.getActUser()); + + // 如果有打回原因,添加到 rejectInfo + if (others != null && others.containsKey("rejectReason")) { + rejectInfo.put("rejectReason", others.getString("rejectReason")); + } + + // 将 rejectInfo 放入主 info + infoJson.put("rejectInfo", rejectInfo); + + // 更新主表状态为暂存 + infoDO.setStatus(DRAFT_STATUS); + infoDO.setInfo(infoJson.toJSONString()); + eightworkInfoRepository.updateById(infoDO); + + log.info("主表已更新为暂存状态并添加打回信息: workId={}", workId); + } + /** * 处理分支流程 * 职责:当主流程步骤为分支开始节点时,激活对应的分支步骤 @@ -667,7 +879,7 @@ public class TaskLogUpdateExe { } // 检查是否需要跳过 - if (CAN_SKIP_FLAG.equals(currentLog.getCanSkip()) && signInfo.getActUser() == null) { + if (CAN_SKIP_FLAG.equals(signStepLog.getCanSkip()) && signInfo.getActUser() == null) { // 设置为跳过状态 signStepLog.setStatus(TaskLogStatus.SKIPPED.getCode()); addActionLog(actionLogs, signStepLog); @@ -681,6 +893,15 @@ public class TaskLogUpdateExe { signInfo.getActUser(), signInfo.getActUserName() ); + + // 如果步骤当前是未开始状态,需要激活它(设置签字人后应该变为进行中) + if (TaskLogStatus.NOT_STARTED.equalsCode(signStepLog.getStatus())) { + signStepLog.setStatus(TaskLogStatus.IN_PROGRESS.getCode()); + // 发送待办通知 + sendTodoAddEvent(getWorkId(signStepLog.getWorkId()), signStepLog, currentLog.getWorkType()); + log.info("已激活签字步骤: {}", signStepLog.getStepName()); + } + addActionLog(actionLogs, signStepLog); log.info("已设置签字人: step={}, user={}", signStepLog.getStepName(), signInfo.getActUserName()); } @@ -760,14 +981,18 @@ public class TaskLogUpdateExe { /** * 合并 TaskLogDO 的修改 * 将 source 中非空字段合并到 target + * 策略:只有当 target 的字段为 null 时,才用 source 的值覆盖(保留已设置的值) + * 特殊处理:签字人相关字段允许覆盖(因为后续操作可能设置签字人) * * @param target 目标 DO(会被修改) * @param source 源 DO(提供新值) */ private void mergeTaskLogDO(TaskLogDO target, TaskLogDO source) { + // 状态:只覆盖空值,保留已激活的状态(IN_PROGRESS/其他) if (source.getStatus() != null) { target.setStatus(source.getStatus()); } + // 签字人相关字段:允许覆盖(后续操作可能设置签字人) if (source.getActUser() != null) { target.setActUser(source.getActUser()); } @@ -780,15 +1005,19 @@ public class TaskLogUpdateExe { if (source.getActUserDepartmentName() != null) { target.setActUserDepartmentName(source.getActUserDepartmentName()); } + // 签字路径:只覆盖空值 if (source.getSignPath() != null) { target.setSignPath(source.getSignPath()); } + // 填写次数:只覆盖空值 if (source.getCurrentFillTimes() != null) { target.setCurrentFillTimes(source.getCurrentFillTimes()); } + // 其他参数:只覆盖空值 if (source.getOtherParams() != null) { target.setOtherParams(source.getOtherParams()); } + // 经纬度:允许覆盖(最新的定位信息) if (source.getLatitude() != null) { target.setLatitude(source.getLatitude()); } diff --git a/web-app/src/main/java/com/zcloud/eightwork/command/query/TaskFlowChartQueryExe.java b/web-app/src/main/java/com/zcloud/eightwork/command/query/TaskFlowChartQueryExe.java new file mode 100644 index 0000000..5268507 --- /dev/null +++ b/web-app/src/main/java/com/zcloud/eightwork/command/query/TaskFlowChartQueryExe.java @@ -0,0 +1,135 @@ +package com.zcloud.eightwork.command.query; + +import com.zcloud.eightwork.domain.gateway.TaskLogGateway; +import com.zcloud.eightwork.domain.model.TaskFlowE; +import com.zcloud.eightwork.domain.model.TaskLogE; +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.dto.clientobject.TaskFlowChartCO; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 工作流程图查询执行器 + * + * @Author fangjiakai + * @Date 2026-03-23 + */ +@Slf4j +@Component +@AllArgsConstructor +public class TaskFlowChartQueryExe { + + private final TaskLogGateway taskLogGateway; + + /** + * 获取工作流程图 + * + * @param workId 工作ID + * @return 流程图列表 + */ + public List execute(String workId) { + log.info("查询工作流程图: workId={}", workId); + + // 1. 查询所有步骤 + List allLogs = taskLogGateway.listAllByWorkId(workId); + + // 2. 过滤 SKIPPED 状态的步骤 + List filteredLogs = allLogs.stream() + .filter(log -> !TaskLogStatus.SKIPPED.equalsCode(log.getStatus())) + .collect(Collectors.toList()); + + // 3. 区分主流程步骤和分支步骤 + List mainSteps = filteredLogs.stream() + .filter(this::isMainStep) + .collect(Collectors.toList()); + + List branchSteps = filteredLogs.stream() + .filter(log -> !isMainStep(log)) + .collect(Collectors.toList()); + + // 4. 按 branchStep 分组分支步骤 + Map> branchGroupMap = branchSteps.stream() + .collect(Collectors.groupingBy(TaskLogE::getBranchStep)); + + // 5. 构建流程图 + List result = new ArrayList<>(); + for (TaskLogE mainStep : mainSteps) { + TaskFlowChartCO mainCO = convertToCO(mainStep); + + // 如果该主流程步骤开启了分支,添加分支信息 + if (BranchFlag.getByCode(mainStep.getBranchFlag()).isBranchStart()) { + List branches = branchGroupMap.get(mainStep.getStepId()); + if (branches != null && !branches.isEmpty()) { + // 按步骤ID排序,确保分支内顺序正确 + branches.sort((a, b) -> a.getStepOrder().compareTo(b.getStepOrder())); + List branchCOs = convertBranches(branches); + mainCO.setBranches(branchCOs); + } + } + + result.add(mainCO); + } + + log.info("工作流程图查询完成: workId={}, stepCount={}", workId, result.size()); + return result; + } + + /** + * 判断是否为主流程步骤 + * 主流程步骤:stepType 为 normal 或 branch_start + */ + private boolean isMainStep(TaskLogE log) { + StepType stepType = StepType.getByCode(log.getStepType()); + return stepType != null && (stepType.isNormalStep()); + } + + /** + * 转换分支步骤列表为 CO + * 分支内按顺序排列,只有最后一个节点有 mergeStepId + */ + private List convertBranches(List branches) { + List result = new ArrayList<>(); + + for (int i = 0; i < branches.size(); i++) { + TaskLogE branch = branches.get(i); + TaskFlowChartCO co = convertToCO(branch); + + // 只有最后一个分支节点设置 mergeStepId + if (i == branches.size() - 1) { + co.setMergeStepId(branch.getBranchMergeStep()); + } + + result.add(co); + } + + return result; + } + + /** + * 将 TaskLogE 转换为 TaskFlowChartCO + */ + private TaskFlowChartCO convertToCO(TaskLogE log) { + TaskFlowChartCO co = new TaskFlowChartCO(); + co.setStepId(log.getStepId()); + co.setStatus(log.getStatus()); + co.setStepName(log.getStepName()); + co.setActUserName(log.getActUserName()); + + // 格式化时间 + if (log.getUpdateTime() != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + co.setUpdateTime(sdf.format(log.getUpdateTime())); + } + + return co; + } +} diff --git a/web-app/src/main/java/com/zcloud/eightwork/service/TaskLogServiceImpl.java b/web-app/src/main/java/com/zcloud/eightwork/service/TaskLogServiceImpl.java index 7fb9f8e..fc411ae 100644 --- a/web-app/src/main/java/com/zcloud/eightwork/service/TaskLogServiceImpl.java +++ b/web-app/src/main/java/com/zcloud/eightwork/service/TaskLogServiceImpl.java @@ -6,6 +6,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.command.query.TaskFlowChartQueryExe; import com.zcloud.eightwork.domain.model.enums.TaskLogStatus; import com.zcloud.eightwork.dto.EightworkInfoSaveDraftCmd; import com.zcloud.eightwork.dto.TaskLogAddCmd; @@ -14,6 +15,7 @@ import com.zcloud.eightwork.dto.TaskLogPageQry; import com.zcloud.eightwork.dto.TaskLogUpdateCmd; import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO; import com.zcloud.eightwork.dto.clientobject.TaskLogCO; +import com.zcloud.eightwork.dto.clientobject.TaskFlowChartCO; import com.alibaba.cola.dto.PageResponse; import com.alibaba.cola.dto.SingleResponse; @@ -39,6 +41,7 @@ public class TaskLogServiceImpl implements TaskLogServiceI { private final TaskLogRemoveExe taskLogRemoveExe; private final TaskLogQueryExe taskLogQueryExe; private final EightworkInfoSaveDraftExe eightworkInfoSaveDraftExe; + private final TaskFlowChartQueryExe taskFlowChartQueryExe; @Override public SingleResponse getInfoById(Long id) { @@ -105,5 +108,10 @@ public class TaskLogServiceImpl implements TaskLogServiceI { eightworkInfoSaveDraftExe.execute(cmd); return SingleResponse.buildSuccess(); } + + @Override + public List getFlowChart(String workId) { + return taskFlowChartQueryExe.execute(workId); + } } diff --git a/web-client/src/main/java/com/zcloud/eightwork/api/TaskLogServiceI.java b/web-client/src/main/java/com/zcloud/eightwork/api/TaskLogServiceI.java index e62dbdd..9c8f0dd 100644 --- a/web-client/src/main/java/com/zcloud/eightwork/api/TaskLogServiceI.java +++ b/web-client/src/main/java/com/zcloud/eightwork/api/TaskLogServiceI.java @@ -11,6 +11,7 @@ import com.zcloud.eightwork.dto.clientobject.TaskLogCO; import com.alibaba.cola.dto.PageResponse; import com.alibaba.cola.dto.SingleResponse; import com.zcloud.eightwork.dto.clientobject.TodoCountCO; +import com.zcloud.eightwork.dto.clientobject.TaskFlowChartCO; import java.util.List; @@ -44,5 +45,13 @@ public interface TaskLogServiceI { * 暂存作业 */ SingleResponse saveDraft(EightworkInfoSaveDraftCmd cmd); + + /** + * 获取工作流程图 + * + * @param workId 工作ID + * @return 流程图列表(主流程步骤,包含分支信息) + */ + List getFlowChart(String workId); } diff --git a/web-client/src/main/java/com/zcloud/eightwork/dto/EightworkInfoSaveDraftCmd.java b/web-client/src/main/java/com/zcloud/eightwork/dto/EightworkInfoSaveDraftCmd.java new file mode 100644 index 0000000..1d2efb5 --- /dev/null +++ b/web-client/src/main/java/com/zcloud/eightwork/dto/EightworkInfoSaveDraftCmd.java @@ -0,0 +1,70 @@ +package com.zcloud.eightwork.dto; + +import com.alibaba.cola.dto.Command; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * web-client + * 八险作业暂存命令 + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EightworkInfoSaveDraftCmd extends Command { + /** + * 主表ID(有值表示修改暂存,无值表示新建暂存) + */ + @ApiModelProperty(value = "主表ID") + private Long id; + + @ApiModelProperty(value = "企业", name = "corpinfoId", required = true) + @NotNull(message = "企业不能为空") + private Long corpinfoId; + + @ApiModelProperty(value = "是否相关方1是", name = "xgfFlag", required = true) + @NotNull(message = "是否相关方1是不能为空") + private Integer xgfFlag; + + @ApiModelProperty(value = "是否内部作业1是2否", name = "internalOperationFlag") + private Integer internalOperationFlag; + + @ApiModelProperty(value = "所属项目", name = "projectId", required = true) + @NotEmpty(message = "所属项目不能为空") + private String projectId; + + @ApiModelProperty(value = "相关方id", name = "xgfId", required = true) + @NotNull(message = "相关方id不能为空") + private Long xgfId; + + @ApiModelProperty(value = "是否需要气体检测1是2否", name = "gasFlag") + private Integer gasFlag; + + @ApiModelProperty(value = "工作类型", name = "workType", required = true) + @NotEmpty(message = "工作类型不能为空") + private String workType; + + @ApiModelProperty(value = "级别", name = "workLevel", required = true) + @NotEmpty(message = "级别不能为空") + private String workLevel; + + @ApiModelProperty(value = "详细信息", name = "info", required = true) + @NotEmpty(message = "详细信息不能为空") + private String info; + + @ApiModelProperty(value = "签字步骤", name = "signLogs") + private java.util.List signLogs; + + @ApiModelProperty(value = "部门id", name = "departmentId") + private Long departmentId; +} diff --git a/web-client/src/main/java/com/zcloud/eightwork/dto/clientobject/TaskFlowChartCO.java b/web-client/src/main/java/com/zcloud/eightwork/dto/clientobject/TaskFlowChartCO.java new file mode 100644 index 0000000..21c29c9 --- /dev/null +++ b/web-client/src/main/java/com/zcloud/eightwork/dto/clientobject/TaskFlowChartCO.java @@ -0,0 +1,43 @@ +package com.zcloud.eightwork.dto.clientobject; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 工作流程图 CO + * + * @Author fangjiakai + * @Date 2026-03-23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("工作流程图") +public class TaskFlowChartCO { + + @ApiModelProperty(value = "步骤ID") + private Long stepId; + + @ApiModelProperty(value = "状态:0-未开始,1-进行中,2-已完成,998-强制终止,999-已归档") + private Integer status; + + @ApiModelProperty(value = "步骤名称") + private String stepName; + + @ApiModelProperty(value = "签字人姓名") + private String actUserName; + + @ApiModelProperty(value = "更新时间") + private String updateTime; + + @ApiModelProperty(value = "分支步骤列表(仅主流程步骤中的分支开始节点有值)") + private List branches; + + @ApiModelProperty(value = "合并到的步骤ID(仅分支最后一个节点有值)") + private Long mergeStepId; +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/dataobject/EightworkSupplementaryInfoArchiveDO.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/dataobject/EightworkSupplementaryInfoArchiveDO.java new file mode 100644 index 0000000..51c4182 --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/dataobject/EightworkSupplementaryInfoArchiveDO.java @@ -0,0 +1,41 @@ +package com.zcloud.eightwork.persistence.dataobject; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.jjb.saas.framework.repository.basedo.BaseDO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * web-infrastructure + * 八险作业辅助信息归档表(打回时归档) + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +@Data +@TableName("eightwork_supplementary_info_archive") +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class EightworkSupplementaryInfoArchiveDO extends BaseDO { + //业务主键id + @ApiModelProperty(value = "业务主键id") + private String supplementaryInfoId; + //流程日志id + @ApiModelProperty(value = "流程日志id") + private String taskLogId; + //工作id + @ApiModelProperty(value = "工作id") + private String workId; + //信息类型delay,gas + @ApiModelProperty(value = "信息类型delay,gas") + private String type; + //详情 + @ApiModelProperty(value = "详情") + private String details; + + public EightworkSupplementaryInfoArchiveDO(String supplementaryInfoId) { + this.supplementaryInfoId = supplementaryInfoId; + } +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/dataobject/TaskLogArchiveDO.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/dataobject/TaskLogArchiveDO.java new file mode 100644 index 0000000..01b9668 --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/dataobject/TaskLogArchiveDO.java @@ -0,0 +1,146 @@ +package com.zcloud.eightwork.persistence.dataobject; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.jjb.saas.framework.repository.basedo.BaseDO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * web-infrastructure + * 任务日志归档表(打回时归档) + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +@Data +@TableName("task_log_archive") +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class TaskLogArchiveDO extends BaseDO { + //业务主键id + @ApiModelProperty(value = "业务主键id") + private String taskLogId; + //工作ID + @ApiModelProperty(value = "工作ID") + private String workId; + //任务ID + @ApiModelProperty(value = "任务ID") + private Long taskId; + //步骤ID + @ApiModelProperty(value = "步骤ID") + private Long stepId; + //步骤名称 + @ApiModelProperty(value = "步骤名称") + private String stepName; + //下一步 + @ApiModelProperty(value = "下一步") + private Long nextStep; + //下一步名称 + @ApiModelProperty(value = "下一步名称") + private String nextStepName; + //操作人部门 + @ApiModelProperty(value = "操作人部门") + private Long actUserDepartment; + //操作人部门 + @ApiModelProperty(value = "操作人部门") + private String actUserDepartmentName; + //操作人 + @ApiModelProperty(value = "操作人") + private Long actUser; + //操作人 + @ApiModelProperty(value = "操作人") + private String actUserName; + //-99未开始0进行中1通过2打回 + @ApiModelProperty(value = "-99未开始0进行中1通过2打回") + private Integer status; + //签字图片路径 + @ApiModelProperty(value = "签字图片路径") + private String signPath; + //任务类型 + @ApiModelProperty(value = "任务类型") + private String workType; + //企业ID + @ApiModelProperty(value = "企业ID") + private Long corpinfoId; + //工作票编号 + @ApiModelProperty(value = "工作票编号") + private String checkNo; + //操作人编码 + @ApiModelProperty(value = "操作人编码") + private String actorField; + //是否多人签字1是 + @ApiModelProperty(value = "是否多人签字1是") + private Integer multipleFlag; + //1正常2分支 + @ApiModelProperty(value = "1正常2分支") + private Integer stepType; + //是否签字步骤1是 + @ApiModelProperty(value = "是否签字步骤1是") + private Integer signStepFlag; + @ApiModelProperty(value = "sign_step_flag == 1 选择级别1部门2人员") + private Integer selectLevel; + @ApiModelProperty(value = "sign_step_flag == 1 是否可选相关方0否1是") + private Integer allowXgfFlag; + //是否上传附件 + @ApiModelProperty(value = "是否上传附件") + private Integer fileStepFlag; + //是否定位步骤 + @ApiModelProperty(value = "是否定位步骤") + private Integer locateStepFlag; + //特殊步骤编码gas气体检测measures安全措施确认delay延时监火 + @ApiModelProperty(value = "特殊步骤编码gas气体检测measures安全措施确认delay延时监火") + private String specialStepCode; + //sign_step_flag == 1 在那个步骤选人 + @ApiModelProperty(value = "sign_step_flag == 1 在那个步骤选人") + private Integer selectSignStep; + @ApiModelProperty(value = "是否可以添加安全措施") + private Integer measuresStepFlag; + //0无分支1有分支开始2有分支结束 + @ApiModelProperty(value = "0无分支1有分支开始2有分支结束") + private Integer branchFlag; + //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; + //是否可跳过1是 + @ApiModelProperty(value = "是否可跳过1是") + private Integer canSkip; + //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 = "纬度") + private String latitude; + //经度 + @ApiModelProperty(value = "经度") + private String longitude; + //其他参数(special_step_code==other 时使用) + @ApiModelProperty(value = "其他参数") + private String otherParams; + //手机端组件名称(special_step_code==other 时使用) + @ApiModelProperty(value = "手机端组件名称") + private String componentName; + + public TaskLogArchiveDO(String taskLogId) { + this.taskLogId = taskLogId; + } +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/mapper/EightworkSupplementaryInfoArchiveMapper.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/mapper/EightworkSupplementaryInfoArchiveMapper.java new file mode 100644 index 0000000..d515dc7 --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/mapper/EightworkSupplementaryInfoArchiveMapper.java @@ -0,0 +1,14 @@ +package com.zcloud.eightwork.persistence.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zcloud.eightwork.persistence.dataobject.EightworkSupplementaryInfoArchiveDO; + +/** + * web-infrastructure + * 八险作业辅助信息归档表 Mapper + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +public interface EightworkSupplementaryInfoArchiveMapper extends BaseMapper { +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/mapper/TaskLogArchiveMapper.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/mapper/TaskLogArchiveMapper.java new file mode 100644 index 0000000..d4bd2ae --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/mapper/TaskLogArchiveMapper.java @@ -0,0 +1,14 @@ +package com.zcloud.eightwork.persistence.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zcloud.eightwork.persistence.dataobject.TaskLogArchiveDO; + +/** + * web-infrastructure + * 任务日志归档表 Mapper + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +public interface TaskLogArchiveMapper extends BaseMapper { +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/EightworkSupplementaryInfoArchiveRepository.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/EightworkSupplementaryInfoArchiveRepository.java new file mode 100644 index 0000000..e23709b --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/EightworkSupplementaryInfoArchiveRepository.java @@ -0,0 +1,14 @@ +package com.zcloud.eightwork.persistence.repository; + +import com.jjb.saas.framework.repository.repo.BaseRepository; +import com.zcloud.eightwork.persistence.dataobject.EightworkSupplementaryInfoArchiveDO; + +/** + * web-infrastructure + * 八险作业辅助信息归档表 Repository + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +public interface EightworkSupplementaryInfoArchiveRepository extends BaseRepository { +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/TaskLogArchiveRepository.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/TaskLogArchiveRepository.java new file mode 100644 index 0000000..bd674ef --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/TaskLogArchiveRepository.java @@ -0,0 +1,14 @@ +package com.zcloud.eightwork.persistence.repository; + +import com.jjb.saas.framework.repository.repo.BaseRepository; +import com.zcloud.eightwork.persistence.dataobject.TaskLogArchiveDO; + +/** + * web-infrastructure + * 任务日志归档表 Repository + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +public interface TaskLogArchiveRepository extends BaseRepository { +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/impl/EightworkSupplementaryInfoArchiveRepositoryImpl.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/impl/EightworkSupplementaryInfoArchiveRepositoryImpl.java new file mode 100644 index 0000000..ed9f3a5 --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/impl/EightworkSupplementaryInfoArchiveRepositoryImpl.java @@ -0,0 +1,18 @@ +package com.zcloud.eightwork.persistence.repository.impl; + +import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl; +import com.zcloud.eightwork.persistence.dataobject.EightworkSupplementaryInfoArchiveDO; +import com.zcloud.eightwork.persistence.mapper.EightworkSupplementaryInfoArchiveMapper; +import com.zcloud.eightwork.persistence.repository.EightworkSupplementaryInfoArchiveRepository; +import org.springframework.stereotype.Service; + +/** + * web-infrastructure + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +@Service +public class EightworkSupplementaryInfoArchiveRepositoryImpl extends BaseRepositoryImpl + implements EightworkSupplementaryInfoArchiveRepository { +} diff --git a/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/impl/TaskLogArchiveRepositoryImpl.java b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/impl/TaskLogArchiveRepositoryImpl.java new file mode 100644 index 0000000..98e1871 --- /dev/null +++ b/web-infrastructure/src/main/java/com/zcloud/eightwork/persistence/repository/impl/TaskLogArchiveRepositoryImpl.java @@ -0,0 +1,18 @@ +package com.zcloud.eightwork.persistence.repository.impl; + +import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl; +import com.zcloud.eightwork.persistence.dataobject.TaskLogArchiveDO; +import com.zcloud.eightwork.persistence.mapper.TaskLogArchiveMapper; +import com.zcloud.eightwork.persistence.repository.TaskLogArchiveRepository; +import org.springframework.stereotype.Service; + +/** + * web-infrastructure + * + * @Author fangjiakai + * @Date 2026-03-20 + */ +@Service +public class TaskLogArchiveRepositoryImpl extends BaseRepositoryImpl + implements TaskLogArchiveRepository { +}