package jnpf.flowable.service.dev; import com.baomidou.dynamic.datasource.annotation.DSTransactional; import jnpf.exception.WorkFlowException; import jnpf.base.model.flow.FlowFormDataModel; import jnpf.flowable.service.OperatorService; import jnpf.flowable.model.templatenode.nodejson.NodeModel; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import jnpf.flowable.entity.OperatorEntity; import jnpf.flowable.model.task.FlowModel; import jnpf.flowable.model.util.DevApprovalActor; import jnpf.flowable.model.util.FlowContextHolder; import jnpf.flowable.util.OperatorUtil; import jnpf.flowable.util.ServiceUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.Date; /** Transaction boundary identical to native automatic approval, followed by normal event dispatch. */ @Service @RequiredArgsConstructor public class DevApprovalStep { private final OperatorUtil operatorUtil; private final ServiceUtil serviceUtil; private final OperatorService operatorService; @DSTransactional public void approve(OperatorEntity operator, FlowModel model, String actorId) throws WorkFlowException { try (DevApprovalActor ignored = DevApprovalActor.open(operator.getId(), actorId, operator.getTaskId())) { if (operator.getSignTime() == null) operator.setSignTime(new Date()); if (operator.getStartHandleTime() == null) operator.setStartHandleTime(new Date()); operatorService.updateById(operator); NodeModel node = model.getNodes().get(operator.getNodeCode()); var definition = model.getNodeEntityList().stream() .filter(n -> operator.getNodeCode().equals(n.getNodeCode())).findFirst().orElseThrow(); FlowFormDataModel form = new FlowFormDataModel(); form.setFormId(definition.getFormId()); form.setId(operator.getTaskId()); form.setFlowId(model.getTaskEntity().getFlowId()); form.setWorkflowOperatorId(operator.getId()); form.setMap(model.getFormData()); // Native persistence still enforces field rights; ensure the run's real signature is saved. var permissions = new ArrayList>(); if (node.getFormOperates() != null) for (Map permission : node.getFormOperates()) { var copy = new HashMap<>(permission); if ("biz_sign".equals(copy.get("id")) || Boolean.TRUE.equals(copy.get("required"))) copy.put("write", true); permissions.add(copy); } form.setFormOperates(permissions); serviceUtil.saveOrUpdateFormData(form); var saved = serviceUtil.infoData(definition.getFormId(), operator.getTaskId()); var missing = DevApprovalValidation.missing(node, saved); if (!missing.isEmpty()) throw new WorkFlowException("原生保存后仍有必填项为空:" + String.join(";", missing)); model.setFormData(saved); FlowContextHolder.addChildData(operator.getTaskId(), definition.getFormId(), saved, node.getFormOperates(), false); // Use native system-approval semantics; preserve the original assignee on the task. operatorUtil.audit(operator, model); FlowContextHolder.deleteFormOperator(); serviceUtil.handleFormData(model.getTaskEntity().getFlowId(), true); } } }