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<Map<String, Object>>();
|
if (node.getFormOperates() != null) for (Map<String, Object> 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);
|
}
|
}
|
}
|