刘光辉
118 分钟以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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);
        }
    }
}