feat(workflow): 完善作业流程管理功能
parent
486cc0d0dc
commit
6e726ac4b3
|
|
@ -49,12 +49,12 @@ public class TaskFlowController {
|
|||
|
||||
@ApiOperation("作业初始化")
|
||||
@PostMapping("/getWorkInit")
|
||||
public SingleResponse<TaskWorkInitCO> getWorkInit(@RequestBody TaskWorkQryCmd qry) {
|
||||
public SingleResponse<TaskWorkInitCO> getWorkInit(@Validated @RequestBody TaskWorkQryCmd qry) {
|
||||
return SingleResponse.of(taskFlowService.getWorkInit(qry));
|
||||
}
|
||||
@ApiOperation("作业初始化流程")
|
||||
@PostMapping("/getFlowInit")
|
||||
public SingleResponse<TaskFlowInitCO> getFlowInit(@RequestBody TaskFlowQryCmd qry) {
|
||||
public SingleResponse<TaskFlowInitCO> getFlowInit(@Validated @RequestBody TaskFlowQryCmd qry) {
|
||||
return SingleResponse.of(taskFlowService.getFlowInit(qry));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,6 +181,9 @@ public class EightworkInfoSaveDraftExe {
|
|||
*/
|
||||
private TaskLogDO createApplyTaskLog(String workId, EightworkInfoSaveDraftCmd cmd) {
|
||||
// 获取流程配置
|
||||
if(StringUtils.isNotEmpty(cmd.getWorkLevel())){
|
||||
|
||||
}
|
||||
List<TaskFlowE> flows = taskFlowGateway.listAllByWorkType(cmd.getWorkType(), cmd.getWorkLevel());
|
||||
TaskFlowE applyFlow = flows.stream()
|
||||
.filter(f -> FIRST_STEP_ID.equals(f.getStepId()))
|
||||
|
|
|
|||
|
|
@ -23,10 +23,7 @@ import com.zcloud.eightwork.domain.model.EightworkSupplementaryInfoE;
|
|||
import com.zcloud.eightwork.domain.model.MeasuresLogsE;
|
||||
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.domain.model.enums.WorkCodeEnum;
|
||||
import com.zcloud.eightwork.domain.model.enums.*;
|
||||
import com.zcloud.eightwork.dto.TaskLogNextCmd;
|
||||
import com.zcloud.eightwork.dto.TaskLogUpdateCmd;
|
||||
import com.zcloud.eightwork.dto.TaskSignStepInfoCmd;
|
||||
|
|
@ -283,7 +280,7 @@ public class TaskLogUpdateExe {
|
|||
// 签字步骤,保存签字图片
|
||||
if (SIGN_STEP_FLAG.equals(currentLog.getSignStepFlag())) {
|
||||
currentLog.setSignPath(cmd.getSignPath());
|
||||
currentLog.setSignTime(LocalDateTime.now());
|
||||
currentLog.setSignTime(cmd.getSignTime());
|
||||
}
|
||||
|
||||
// 定位步骤,保存经纬度
|
||||
|
|
@ -427,7 +424,7 @@ public class TaskLogUpdateExe {
|
|||
return d;
|
||||
}).collect(Collectors.toList()));
|
||||
} else {
|
||||
measuresLogsRepository.deleteByWorkId(currentLog.getWorkId());
|
||||
measuresLogsRepository.deleteByWorkId(currentLog.getWorkId(), MeasuresLogType.PRIMARY.getCode());
|
||||
measuresLogsRepository.saveBatch(measuresList.stream().map(item -> {
|
||||
MeasuresLogsDO d = new MeasuresLogsDO();
|
||||
BeanUtils.copyProperties(item, d, "id");
|
||||
|
|
@ -1000,6 +997,8 @@ public class TaskLogUpdateExe {
|
|||
}
|
||||
|
||||
private void handleRejectStep(TaskLogNextCmd cmd) {
|
||||
log.info("请求参数:{}",JSONUtil.toJsonStr( cmd));
|
||||
|
||||
log.info("开始处理打回到某一步: workId={}, stepId={}", cmd.getWorkId(), cmd.getStepId());
|
||||
|
||||
|
||||
|
|
@ -1010,8 +1009,6 @@ public class TaskLogUpdateExe {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Integer rejectStepId = currentLog.getRejectStepId();
|
||||
if(rejectStepId==null){
|
||||
log.warn("未找到对应的步骤记录.workId={}, stepId={}", cmd.getWorkId(), cmd.getStepId());
|
||||
|
|
@ -1025,6 +1022,8 @@ public class TaskLogUpdateExe {
|
|||
log.warn("未找到作业信息: workId={}", cmd.getWorkId());
|
||||
return;
|
||||
}
|
||||
// 从 others.otherParams.hotTime 中提取并更新作业结束时间
|
||||
updateWorkEndTimeFromOtherParams(infoDO, cmd, cmd.getWorkId(),currentLog);
|
||||
|
||||
// 1. 归档当前的 task_log 记录(除了申请步骤)
|
||||
archiveTaskLogs(allLogs);
|
||||
|
|
@ -1046,7 +1045,7 @@ public class TaskLogUpdateExe {
|
|||
// 3. 设置所有步骤的id
|
||||
for (TaskLogDO taskLog : taskLogs) {
|
||||
taskLog.setId(null);
|
||||
taskLog.setTaskLogId(Tools.get32UUID());
|
||||
// taskLog.setTaskLogId(Tools.get32UUID());
|
||||
taskLog.setUpdateTime(LocalDateTime.now());
|
||||
taskLog.setUpdateId(null);
|
||||
taskLog.setUpdateName( null);
|
||||
|
|
@ -1058,13 +1057,13 @@ public class TaskLogUpdateExe {
|
|||
taskLogRepository.saveBatch(taskLogs);
|
||||
|
||||
// 批量更新 eightworkInfo.info(只更新本次变化的步骤)
|
||||
updateEightworkInfo(cmd.getWorkId(), taskLogs);
|
||||
// updateEightworkInfo(cmd.getWorkId(), taskLogs);
|
||||
|
||||
// 6. 发送待办完成事件
|
||||
sendTodoCompleteEvent(currentLog.getId());
|
||||
TaskLogE branchStep = new TaskLogE();
|
||||
branchStep.setActUser(currentLog.getActUser());
|
||||
branchStep.setStatus(TaskLogStatus.REJECTED.getCode());
|
||||
branchStep.setStatus(TaskLogStatus.IN_PROGRESS.getCode());
|
||||
branchStep.setStepName(currentLog.getStepName());
|
||||
messageNotice(branchStep, currentLog);
|
||||
log.info("工作流已打回到指定步骤: workId={},step={}", cmd.getWorkId(),rejectStepId);
|
||||
|
|
@ -1090,7 +1089,68 @@ public class TaskLogUpdateExe {
|
|||
log.info("工作流已打回到指定步骤: workId={}, step={}", cmd.getWorkId(), rejectStepId);
|
||||
|
||||
}
|
||||
/**
|
||||
* 从 otherParams 中提取 hotTime 并更新到 infoDO 的 workEndTime 字段
|
||||
*
|
||||
* @param infoDO 作业信息对象
|
||||
* @param cmd 其他参数字典
|
||||
* @param workId 作业ID(用于日志)
|
||||
*/
|
||||
private void updateWorkEndTimeFromOtherParams(EightworkInfoDO infoDO, TaskLogNextCmd cmd, String workId,TaskLogE currentLog) {
|
||||
JSONObject others = cmd.getOthers();
|
||||
if (others == null || !others.containsKey("otherParams")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String otherParamsStr = others.getString("otherParams");
|
||||
if (StringUtils.isBlank(otherParamsStr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 解析 otherParams JSON 字符串
|
||||
JSONObject otherParamsJson = JSONObject.parseObject(otherParamsStr);
|
||||
String hotTime = otherParamsJson.getString("hotTime");
|
||||
|
||||
if (StringUtils.isBlank(hotTime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析现有的 info JSON
|
||||
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();
|
||||
}
|
||||
//更新当前步骤的签字时间个日期
|
||||
Object o = infoJson.get("step_" + currentLog.getStepId());
|
||||
log.info("更新签名和路径的step={}",currentLog.getStepId());
|
||||
if (o instanceof JSONObject) {
|
||||
JSONObject stepInfo = (JSONObject) o;
|
||||
LocalDateTime signTime = cmd.getSignTime() != null ? cmd.getSignTime() : LocalDateTime.now();
|
||||
String formattedSignTime = DateUtil.format(DateUtil.date(signTime), DatePattern.NORM_DATETIME_PATTERN);
|
||||
stepInfo.put("signTime", formattedSignTime);
|
||||
stepInfo.put("signPath", cmd.getSignPath());
|
||||
infoJson.put("step_" + currentLog.getStepId(), stepInfo);
|
||||
}
|
||||
|
||||
|
||||
// 设置 workEndTime 字段
|
||||
infoJson.put("workEndTime", hotTime);
|
||||
infoDO.setInfo(infoJson.toJSONString());
|
||||
eightworkInfoRepository.updateById(infoDO);
|
||||
|
||||
log.info("更新作业结束时间: workId={}, hotTime={}", workId, hotTime);
|
||||
} catch (Exception e) {
|
||||
log.error("解析 otherParams 失败: workId={}, otherParams={}", workId, otherParamsStr, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定步骤ID之后的所有步骤重置状态
|
||||
|
|
@ -1844,7 +1904,7 @@ public class TaskLogUpdateExe {
|
|||
// 签字路径:只覆盖空值
|
||||
if (source.getSignPath() != null) {
|
||||
target.setSignPath(source.getSignPath());
|
||||
target.setSignTime(LocalDateTime.now());
|
||||
target.setSignTime(source.getSignTime());
|
||||
}
|
||||
// 填写次数:只覆盖空值
|
||||
if (source.getCurrentFillTimes() != null) {
|
||||
|
|
@ -1979,6 +2039,7 @@ public class TaskLogUpdateExe {
|
|||
}*/
|
||||
private void updateEightworkInfo(String workId, List<TaskLogDO> actionLogs) {
|
||||
if (actionLogs == null || actionLogs.isEmpty()) {
|
||||
log.warn("未找到作业信息: workId={}", workId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2004,7 +2065,7 @@ public class TaskLogUpdateExe {
|
|||
} else {
|
||||
infoJson = new JSONObject();
|
||||
}
|
||||
|
||||
log.info("已解析 wordId={},info: {}",workId, infoJson);
|
||||
// 循环更新本次变化的步骤
|
||||
for (TaskLogDO logDO : actionLogs) {
|
||||
String baseKey = "step_" + logDO.getStepId();
|
||||
|
|
@ -2012,22 +2073,25 @@ public class TaskLogUpdateExe {
|
|||
// 判断是否为多人签字步骤
|
||||
if (logDO.getMultipleFlag() != null && logDO.getMultipleFlag() == 1) {
|
||||
// 多人签字步骤:根据 actUser 查找并更新,或追加新记录
|
||||
log.info("更新多人签字步骤wordId={}: {}", workId,baseKey);
|
||||
updateOrAppendMultipleSignStepByUser(infoJson, baseKey, logDO);
|
||||
} else {
|
||||
// 普通步骤:直接替换
|
||||
JSONObject stepInfo = buildStepInfo(logDO);
|
||||
infoJson.put(baseKey, stepInfo);
|
||||
log.info("更新普通步骤: {}", baseKey);
|
||||
log.info("更新普通步骤wordId={}: {}", workId,baseKey);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新到数据库
|
||||
infoDO.setInfo(infoJson.toJSONString());
|
||||
log.info("已更新 info: workId={},info={}", workId,infoJson.toJSONString());
|
||||
eightworkInfoRepository.updateById(infoDO);
|
||||
|
||||
|
||||
log.info("已批量更新步骤 info: workId={}, count={}", workId, actionLogs.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 actUser 更新或追加多人签字步骤记录
|
||||
* 策略:
|
||||
|
|
@ -2116,7 +2180,12 @@ public class TaskLogUpdateExe {
|
|||
stepInfo.put("actUser", logDO.getActUser());
|
||||
stepInfo.put("actUserName", logDO.getActUserName());
|
||||
stepInfo.put("signPath", logDO.getSignPath());
|
||||
stepInfo.put("signTime", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
|
||||
if(logDO.getSignTime() != null){
|
||||
LocalDateTime signTime = logDO.getSignTime();
|
||||
String formattedSignTime = DateUtil.format(DateUtil.date(signTime), DatePattern.NORM_DATETIME_PATTERN);
|
||||
stepInfo.put("signTime", formattedSignTime);
|
||||
}
|
||||
|
||||
stepInfo.put("status", logDO.getStatus());
|
||||
|
||||
// 定位步骤,添加经纬度信息
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.zcloud.eightwork.dto;
|
|||
|
||||
import com.alibaba.cola.dto.Command;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
|
@ -9,6 +10,7 @@ import lombok.EqualsAndHashCode;
|
|||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -55,6 +57,8 @@ public class TaskLogNextCmd extends Command {
|
|||
private String filePath;
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remarks;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime signTime = LocalDateTime.now();
|
||||
|
||||
public TaskLogNextCmd(Long id, String workId, Long stepId, Integer status, JSONObject others) {
|
||||
this.id = id;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* 安全措施类型1主要2其他
|
||||
*/
|
||||
@Getter
|
||||
public enum MeasuresLogType {
|
||||
PRIMARY(1, "主要"),
|
||||
OTHER(2, "其他");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
private static final Map<Integer, MeasuresLogType> CODE_MAP =
|
||||
Arrays.stream(values())
|
||||
.collect(Collectors.toMap(MeasuresLogType::getCode, Function.identity()));
|
||||
|
||||
MeasuresLogType(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型码获取枚举
|
||||
*/
|
||||
public static MeasuresLogType getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
return CODE_MAP.get(code);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -25,6 +25,6 @@ public interface MeasuresLogsRepository extends BaseRepository<MeasuresLogsDO> {
|
|||
*/
|
||||
int physicalDeleteByWorkId(String workId);
|
||||
|
||||
void deleteByWorkId(String workId);
|
||||
void deleteByWorkId(String workId, Integer code);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class MeasuresLogsRepositoryImpl extends BaseRepositoryImpl<MeasuresLogsM
|
|||
}
|
||||
|
||||
@Override
|
||||
public void deleteByWorkId(String workId) {
|
||||
public void deleteByWorkId(String workId, Integer type) {
|
||||
if (workId == null || workId.isEmpty()) {
|
||||
log.warn("workId 为空,跳过删除操作");
|
||||
return;
|
||||
|
|
@ -64,6 +64,7 @@ public class MeasuresLogsRepositoryImpl extends BaseRepositoryImpl<MeasuresLogsM
|
|||
|
||||
LambdaQueryWrapper<MeasuresLogsDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(MeasuresLogsDO::getWorkId, workId);
|
||||
queryWrapper.eq(MeasuresLogsDO::getType, type);
|
||||
int deletedCount = measuresLogsMapper.delete(queryWrapper);
|
||||
log.info("逻辑删除安全措施记录: workId={}, 删除数量={}", workId, deletedCount);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue